aboutsummaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-04-06 12:00:29 +0200
committerLudovic Courtès <ludo@gnu.org>2016-04-06 12:00:29 +0200
commit933d2fe4cfb380f66af631a2203ec23c367e5b1a (patch)
treef10581ed0da1911eed9b02e69d999ba481d9d3c6 /guix
parentf8835ff4b3dd59d59bf44838d05d3d60114d15d2 (diff)
parent998afc3608242b75051f43ece36d52474c51e285 (diff)
downloadgnu-guix-933d2fe4cfb380f66af631a2203ec23c367e5b1a.tar
gnu-guix-933d2fe4cfb380f66af631a2203ec23c367e5b1a.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'guix')
-rw-r--r--guix/build-system/ant.scm10
-rw-r--r--guix/build-system/r.scm4
-rw-r--r--guix/build/ant-build-system.scm29
-rw-r--r--guix/build/cvs.scm11
-rw-r--r--guix/build/syscalls.scm12
-rw-r--r--guix/derivations.scm29
-rw-r--r--guix/gexp.scm9
-rw-r--r--guix/graph.scm16
-rw-r--r--guix/import/cran.scm2
-rw-r--r--guix/import/hackage.scm103
-rw-r--r--guix/licenses.scm6
-rw-r--r--guix/profiles.scm4
-rw-r--r--guix/scripts/build.scm6
-rw-r--r--guix/scripts/environment.scm53
-rw-r--r--guix/scripts/package.scm3
-rw-r--r--guix/scripts/refresh.scm2
-rwxr-xr-xguix/scripts/substitute.scm18
-rw-r--r--guix/scripts/system.scm18
-rw-r--r--guix/store.scm7
-rw-r--r--guix/ui.scm8
20 files changed, 274 insertions, 76 deletions
diff --git a/guix/build-system/ant.scm b/guix/build-system/ant.scm
index d3054e5ffa..f333aa5ae8 100644
--- a/guix/build-system/ant.scm
+++ b/guix/build-system/ant.scm
@@ -54,15 +54,22 @@
(let ((jdk-mod (resolve-interface '(gnu packages java))))
(module-ref jdk-mod 'ant)))
+(define (default-zip)
+ "Return the default ZIP package."
+ ;; Lazily resolve the binding to avoid a circular dependency.
+ (let ((zip-mod (resolve-interface '(gnu packages zip))))
+ (module-ref zip-mod 'zip)))
+
(define* (lower name
#:key source inputs native-inputs outputs system target
(jdk (default-jdk))
(ant (default-ant))
+ (zip (default-zip))
#:allow-other-keys
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:source #:target #:jdk #:ant #:inputs #:native-inputs))
+ '(#:source #:target #:jdk #:ant #:zip #:inputs #:native-inputs))
(and (not target) ;XXX: no cross-compilation
(bag
@@ -77,6 +84,7 @@
,@(standard-packages)))
(build-inputs `(("jdk" ,jdk "jdk")
("ant" ,ant)
+ ("zip" ,zip)
,@native-inputs))
(outputs outputs)
(build ant-build)
diff --git a/guix/build-system/r.scm b/guix/build-system/r.scm
index a8ca354227..e8269fdeb1 100644
--- a/guix/build-system/r.scm
+++ b/guix/build-system/r.scm
@@ -101,6 +101,7 @@ release corresponding to NAME and VERSION."
(search-paths '())
(system (%current-system))
(guile #f)
+ (substitutable? #t)
(imported-modules %r-build-system-modules)
(modules '((guix build r-build-system)
(guix build utils))))
@@ -140,7 +141,8 @@ release corresponding to NAME and VERSION."
#:system system
#:modules imported-modules
#:outputs outputs
- #:guile-for-build guile-for-build))
+ #:guile-for-build guile-for-build
+ #:substitutable? substitutable?))
(define r-build-system
(build-system
diff --git a/guix/build/ant-build-system.scm b/guix/build/ant-build-system.scm
index d302b948b5..27277af34b 100644
--- a/guix/build/ant-build-system.scm
+++ b/guix/build/ant-build-system.scm
@@ -65,13 +65,8 @@
(target (@ (name "jar")
(depends "compile"))
(mkdir (@ (dir "${jar.dir}")))
- ;; We cannot use the simpler "jar" task here, because
- ;; there is no way to disable generation of a
- ;; manifest. We do not include a generated manifest
- ;; to ensure determinism, because we cannot easily
- ;; reset the ctime/mtime before creating the archive.
(exec (@ (executable "jar"))
- (arg (@ (line ,(string-append "-Mcf ${jar.dir}/" jar-name
+ (arg (@ (line ,(string-append "-cf ${jar.dir}/" jar-name
" -C ${classes.dir} ."))))))
(target (@ (name "install"))
@@ -105,16 +100,15 @@ INPUTS."
(zero? (apply system* `("ant" ,build-target ,@make-flags))))
(define* (strip-jar-timestamps #:key outputs
- #:allow-other-keys)
+ #:allow-other-keys)
"Unpack all jar archives, reset the timestamp of all contained files, and
repack them. This is necessary to ensure that archives are reproducible."
(define (repack-archive jar)
(format #t "repacking ~a\n" jar)
- (let ((dir (mkdtemp! "jar-contents.XXXXXX")))
+ (let* ((dir (mkdtemp! "jar-contents.XXXXXX"))
+ (manifest (string-append dir "/META-INF/MANIFEST.MF")))
(and (with-directory-excursion dir
(zero? (system* "jar" "xf" jar)))
- ;; The manifest file contains timestamps
- (for-each delete-file (find-files dir "MANIFEST.MF"))
(delete-file jar)
;; XXX: copied from (gnu build install)
(for-each (lambda (file)
@@ -122,8 +116,19 @@ repack them. This is necessary to ensure that archives are reproducible."
(unless (eq? (stat:type s) 'symlink)
(utime file 0 0 0 0))))
(find-files dir #:directories? #t))
- (unless (zero? (system* "jar" "-Mcf" jar "-C" dir "."))
- (error "'jar' failed"))
+
+ ;; The jar tool will always set the timestamp on the manifest file
+ ;; and the containing directory to the current time, even when we
+ ;; reuse an existing manifest file. To avoid this we use "zip"
+ ;; instead of "jar". It is important that the manifest appears
+ ;; first.
+ (with-directory-excursion dir
+ (let* ((files (find-files "." ".*" #:directories? #t))
+ (command (if (file-exists? manifest)
+ `("zip" "-X" ,jar ,manifest ,@files)
+ `("zip" "-X" ,jar ,@files))))
+ (unless (zero? (apply system* command))
+ (error "'zip' failed"))))
(utime jar 0 0)
#t)))
diff --git a/guix/build/cvs.scm b/guix/build/cvs.scm
index bd5c50a51a..9976e624b3 100644
--- a/guix/build/cvs.scm
+++ b/guix/build/cvs.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -51,14 +52,20 @@
"Fetch REVISION from MODULE of CVS-ROOT-DIRECTORY into DIRECTORY. REVISION
must either be a date in ISO-8601 format (e.g. \"2012-12-21\") or a CVS tag.
Return #t on success, #f otherwise."
- (and (zero? (system* cvs-command "-z3"
+ ;; Use "-z0" because enabling compression leads to hangs during checkout on
+ ;; certain repositories, such as
+ ;; ":pserver:anonymous@cvs.savannah.gnu.org:/sources/gnustandards".
+ (and (zero? (system* cvs-command "-z0"
"-d" cvs-root-directory
"checkout"
(if (string-match "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" revision)
"-D" "-r")
revision
module))
- (rename-file module directory)
+ ;; Copy rather than rename in case MODULE and DIRECTORY are on
+ ;; different devices.
+ (copy-recursively module directory)
+
(with-directory-excursion directory
(for-each delete-file-recursively (find-cvs-directories)))
#t))
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index ea68b22bb7..69a507def8 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -767,10 +767,14 @@ the same type as that returned by 'make-socket-address'."
(format port "#<interface ~s " name)
(unless (zero? (logand IFF_UP flags))
(display "up " port))
- (if (member (sockaddr:fam address) (list AF_INET AF_INET6))
- (format port "~a " (inet-ntop (sockaddr:fam address)
- (sockaddr:addr address)))
- (format port "family:~a " (sockaddr:fam address)))
+
+ ;; Check whether ADDRESS really is a sockaddr.
+ (when address
+ (if (member (sockaddr:fam address) (list AF_INET AF_INET6))
+ (format port "~a " (inet-ntop (sockaddr:fam address)
+ (sockaddr:addr address)))
+ (format port "family:~a " (sockaddr:fam address))))
+
(format port "~a>" (number->string (object-address interface) 16)))))
(set-record-type-printer! <interface> write-interface)
diff --git a/guix/derivations.scm b/guix/derivations.scm
index f24e3c6f92..2d8584e72d 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -90,7 +90,12 @@
build-derivations
built-derivations
+ file-search-error?
+ file-search-error-file-name
+ file-search-error-search-path
+ search-path*
+ module->source-file-name
build-expression->derivation)
;; Re-export it from here for backward compatibility.
@@ -1035,10 +1040,28 @@ system, imported, and appears under FINAL-PATH in the resulting store path."
#:guile-for-build guile
#:local-build? #t)))
+;; The "file not found" error condition.
+(define-condition-type &file-search-error &error
+ file-search-error?
+ (file file-search-error-file-name)
+ (path file-search-error-search-path))
+
(define search-path*
;; A memoizing version of 'search-path' so 'imported-modules' does not end
;; up looking for the same files over and over again.
- (memoize search-path))
+ (memoize (lambda (path file)
+ "Search for FILE in PATH and memoize the result. Raise a
+'&file-search-error' condition if it could not be found."
+ (or (search-path path file)
+ (raise (condition
+ (&file-search-error (file file)
+ (path path))))))))
+
+(define (module->source-file-name module)
+ "Return the file name corresponding to MODULE, a Guile module name (a list
+of symbols.)"
+ (string-append (string-join (map symbol->string module) "/")
+ ".scm"))
(define* (%imported-modules store modules ;deprecated
#:key (name "module-import")
@@ -1051,9 +1074,7 @@ search path."
;; TODO: Determine the closure of MODULES, build the `.go' files,
;; canonicalize the source files through read/write, etc.
(let ((files (map (lambda (m)
- (let ((f (string-append
- (string-join (map symbol->string m) "/")
- ".scm")))
+ (let ((f (module->source-file-name m)))
(cons f (search-path* module-path f))))
modules)))
(imported-files store files #:name name #:system system
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 7cbc79c31c..b4d737ecae 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -902,11 +902,6 @@ system, imported, and appears under FINAL-PATH in the resulting store path."
#:guile-for-build guile
#:local-build? #t)))
-(define search-path*
- ;; A memoizing version of 'search-path' so 'imported-modules' does not end
- ;; up looking for the same files over and over again.
- (memoize search-path))
-
(define* (imported-modules modules
#:key (name "module-import")
(system (%current-system))
@@ -918,9 +913,7 @@ search path."
;; TODO: Determine the closure of MODULES, build the `.go' files,
;; canonicalize the source files through read/write, etc.
(let ((files (map (lambda (m)
- (let ((f (string-append
- (string-join (map symbol->string m) "/")
- ".scm")))
+ (let ((f (module->source-file-name m)))
(cons f (search-path* module-path f))))
modules)))
(imported-files files #:name name #:system system
diff --git a/guix/graph.scm b/guix/graph.scm
index a39208e7f9..1a8f2d55b3 100644
--- a/guix/graph.scm
+++ b/guix/graph.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -131,6 +131,16 @@ typically returned by 'node-edges' or 'node-back-edges'."
(node graph-backend-node)
(edge graph-backend-edge))
+(define %colors
+ ;; See colortbl.h in Graphviz.
+ #("red" "magenta" "blue" "cyan3" "darkseagreen"
+ "peachpuff4" "darkviolet" "dimgrey" "darkgoldenrod"))
+
+(define (pop-color hint)
+ "Return a Graphviz color based on HINT, an arbitrary object."
+ (let ((index (hash hint (vector-length %colors))))
+ (vector-ref %colors index)))
+
(define (emit-prologue name port)
(format port "digraph \"Guix ~a\" {\n"
name))
@@ -140,8 +150,8 @@ typically returned by 'node-edges' or 'node-back-edges'."
(format port " \"~a\" [label = \"~a\", shape = box, fontname = Helvetica];~%"
id label))
(define (emit-edge id1 id2 port)
- (format port " \"~a\" -> \"~a\" [color = red];~%"
- id1 id2))
+ (format port " \"~a\" -> \"~a\" [color = ~a];~%"
+ id1 id2 (pop-color id1)))
(define %graphviz-backend
(graph-backend emit-prologue emit-epilogue
diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index f36e9482cf..562917c0a0 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -227,7 +227,7 @@ s-expression corresponding to that package, or #f on failure."
(match (package-source package)
((? origin? origin)
(match (origin-uri origin)
- ((url rest ...)
+ ((or (? string? url) (url _ ...))
(let ((end (string-rindex url #\_))
(start (string-rindex url #\/)))
;; The URL ends on
diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index 8725ffa0df..640ead24f3 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;; Copyright © 2016 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -18,19 +19,25 @@
(define-module (guix import hackage)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-11)
#:use-module (srfi srfi-1)
- #:use-module ((guix download) #:select (download-to-store))
+ #:use-module (gnu packages)
+ #:use-module ((guix download) #:select (download-to-store url-fetch))
#:use-module ((guix utils) #:select (package-name->name+version
canonical-newline-port))
- #:use-module (guix import utils)
+ #:use-module (guix http-client)
+ #:use-module ((guix import utils) #:select (factorize-uri))
#:use-module (guix import cabal)
#:use-module (guix store)
#:use-module (guix hash)
#:use-module (guix base32)
+ #:use-module (guix upstream)
+ #:use-module (guix packages)
#:use-module ((guix utils) #:select (call-with-temporary-output-file))
- #:export (hackage->guix-package))
+ #:export (hackage->guix-package
+ %hackage-updater))
(define ghc-standard-libraries
;; List of libraries distributed with ghc (7.10.2). We include GHC itself as
@@ -65,28 +72,49 @@
(define package-name-prefix "ghc-")
+(define (hackage-source-url name version)
+ "Given a Hackage package NAME and VERSION, return a url to the source
+tarball."
+ (string-append "http://hackage.haskell.org/package/" name
+ "/" name "-" version ".tar.gz"))
+
+(define* (hackage-cabal-url name #:optional version)
+ "Given a Hackage package NAME and VERSION, return a url to the corresponding
+.cabal file on Hackage. If VERSION is #f or missing, the url for the latest
+version is returned."
+ (if version
+ (string-append "http://hackage.haskell.org/package/"
+ name "-" version "/" name ".cabal")
+ (string-append "http://hackage.haskell.org/package/"
+ name "/" name ".cabal")))
+
(define (hackage-name->package-name name)
"Given the NAME of a Cabal package, return the corresponding Guix name."
(if (string-prefix? package-name-prefix name)
(string-downcase name)
(string-append package-name-prefix (string-downcase name))))
+(define guix-package->hackage-name
+ (let ((uri-rx (make-regexp "https?://hackage.haskell.org/package/([^/]+)/.*"))
+ (name-rx (make-regexp "(.*)-[0-9\\.]+")))
+ (lambda (package)
+ "Given a Guix package name, return the corresponding Hackage name."
+ (let* ((source-url (and=> (package-source package) origin-uri))
+ (name (match:substring (regexp-exec uri-rx source-url) 1)))
+ (match (regexp-exec name-rx name)
+ (#f name)
+ (m (match:substring m 1)))))))
+
(define (hackage-fetch name-version)
"Return the Cabal file for the package NAME-VERSION, or #f on failure. If
the version part is omitted from the package name, then return the latest
version."
- (let*-values (((name version) (package-name->name+version name-version))
- ((url)
- (if version
- (string-append "http://hackage.haskell.org/package/"
- name "-" version "/" name ".cabal")
- (string-append "http://hackage.haskell.org/package/"
- name "/" name ".cabal"))))
- (call-with-temporary-output-file
- (lambda (temp port)
- (and (url-fetch url temp)
- (call-with-input-file temp
- (compose read-cabal canonical-newline-port)))))))
+ (let-values (((name version) (package-name->name+version name-version)))
+ (let* ((url (hackage-cabal-url name version))
+ (port (http-fetch url))
+ (result (read-cabal (canonical-newline-port port))))
+ (close-port port)
+ result)))
(define string->license
;; List of valid values from
@@ -154,8 +182,7 @@ representation of a Cabal file as produced by 'read-cabal'."
(cabal-package-version cabal))
(define source-url
- (string-append "http://hackage.haskell.org/package/" name
- "/" name "-" version ".tar.gz"))
+ (hackage-source-url name version))
(define dependencies
(let ((names
@@ -225,4 +252,46 @@ respectively."
include-test-dependencies?)
(cut eval-cabal <> cabal-environment)))))
+(define (hackage-package? package)
+ "Return #t if PACKAGE is a Haskell package from Hackage."
+
+ (define haskell-url?
+ (let ((hackage-rx (make-regexp "https?://hackage.haskell.org")))
+ (lambda (url)
+ (regexp-exec hackage-rx url))))
+
+ (let ((source-url (and=> (package-source package) origin-uri))
+ (fetch-method (and=> (package-source package) origin-method)))
+ (and (eq? fetch-method url-fetch)
+ (match source-url
+ ((? string?)
+ (haskell-url? source-url))
+ ((source-url ...)
+ (any haskell-url? source-url))))))
+
+(define (latest-release guix-package)
+ "Return an <upstream-source> for the latest release of GUIX-PACKAGE."
+ (let* ((hackage-name (guix-package->hackage-name
+ (specification->package guix-package)))
+ (cabal-meta (hackage-fetch hackage-name)))
+ (match cabal-meta
+ (#f
+ (format (current-error-port)
+ "warning: failed to parse ~a~%"
+ (hackage-cabal-url hackage-name))
+ #f)
+ ((_ *** ("version" (version)))
+ (let ((url (hackage-source-url hackage-name version)))
+ (upstream-source
+ (package guix-package)
+ (version version)
+ (urls (list url))))))))
+
+(define %hackage-updater
+ (upstream-updater
+ (name 'hackage)
+ (description "Updater for Hackage packages")
+ (pred hackage-package?)
+ (latest latest-release)))
+
;;; cabal.scm ends here
diff --git a/guix/licenses.scm b/guix/licenses.scm
index 71c0736223..265f048278 100644
--- a/guix/licenses.scm
+++ b/guix/licenses.scm
@@ -57,6 +57,7 @@
mpl1.0 mpl1.1 mpl2.0
ms-pl
ncsa
+ nmap
openldap2.8 openssl
psfl public-domain
qpl
@@ -360,6 +361,11 @@ at URI, which may be a file:// URI pointing the package's tree."
"http://directory.fsf.org/wiki/License:IllinoisNCSA"
"https://www.gnu.org/licenses/license-list#NCSA"))
+(define nmap
+ (license "Nmap license"
+ "https://svn.nmap.org/nmap/COPYING"
+ "https://fedoraproject.org/wiki/Licensing/Nmap"))
+
(define openssl
(license "OpenSSL"
"http://directory.fsf.org/wiki/License:OpenSSL"
diff --git a/guix/profiles.scm b/guix/profiles.scm
index 1c53c8047a..a3277cef71 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -21,7 +21,9 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix profiles)
- #:use-module (guix utils)
+ #:use-module ((guix utils) #:hide (package-name->name+version))
+ #:use-module ((guix build utils)
+ #:select (package-name->name+version))
#:use-module (guix records)
#:use-module (guix packages)
#:use-module (guix derivations)
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index b25bf50d2b..9a6b427fc5 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -24,7 +24,11 @@
#:use-module (guix derivations)
#:use-module (guix packages)
#:use-module (guix grafts)
- #:use-module (guix utils)
+
+ ;; Use the procedure that destructures "NAME-VERSION" forms.
+ #:use-module ((guix utils) #:hide (package-name->name+version))
+ #:use-module ((guix build utils) #:select (package-name->name+version))
+
#:use-module (guix monads)
#:use-module (guix gexp)
#:autoload (guix http-client) (http-fetch http-get-error?)
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index b122b4cd40..0ec2c5d3cb 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -358,8 +358,22 @@ and suitable for 'exit'."
"Run COMMAND in a new environment containing INPUTS, using the native search
paths defined by the list PATHS. When PURE?, pre-existing environment
variables are cleared before setting the new ones."
+ ;; Properly handle SIGINT, so pressing C-c in an interactive terminal
+ ;; application works.
+ (sigaction SIGINT SIG_DFL)
(create-environment inputs paths pure?)
- (apply system* command))
+ (match command
+ ((program . args)
+ (apply execlp program program args))))
+
+(define (launch-environment/fork command inputs paths pure?)
+ "Run COMMAND in a new process with an environment containing INPUTS, using
+the native search paths defined by the list PATHS. When PURE?, pre-existing
+environment variables are cleared before setting the new ones."
+ (match (primitive-fork)
+ (0 (launch-environment command inputs paths pure?))
+ (pid (match (waitpid pid)
+ ((_ . status) status)))))
(define* (launch-environment/container #:key command bash user-mappings
profile paths network?)
@@ -373,6 +387,7 @@ host file systems to mount inside the container."
(list (direct-store-path bash) profile))))
(return
(let* ((cwd (getcwd))
+ (passwd (getpwuid (getuid)))
;; Bind-mount all requisite store items, user-specified mappings,
;; /bin/sh, the current working directory, and possibly networking
;; configuration files within the container.
@@ -410,6 +425,9 @@ host file systems to mount inside the container."
(mkdir-p "/bin")
(symlink bash "/bin/sh")
+ ;; Set a reasonable default PS1.
+ (setenv "PS1" "\\u@\\h \\w [env]\\$ ")
+
;; Setup directory for temporary files.
(mkdir-p "/tmp")
(for-each (lambda (var)
@@ -417,16 +435,26 @@ host file systems to mount inside the container."
;; The same variables as in Nix's 'build.cc'.
'("TMPDIR" "TEMPDIR" "TMP" "TEMP"))
- ;; From Nix build.cc:
- ;;
- ;; Set HOME to a non-existing path to prevent certain
- ;; programs from using /etc/passwd (or NIS, or whatever)
- ;; to locate the home directory (for example, wget looks
- ;; for ~/.wgetrc). I.e., these tools use /etc/passwd if
- ;; HOME is not set, but they will just assume that the
- ;; settings file they are looking for does not exist if
- ;; HOME is set but points to some non-existing path.
- (setenv "HOME" "/homeless-shelter")
+ ;; Create a dummy home directory under the same name as on the
+ ;; host.
+ (mkdir-p (passwd:dir passwd))
+ (setenv "HOME" (passwd:dir passwd))
+
+ ;; Create a dummy /etc/passwd to satisfy applications that demand
+ ;; to read it, such as 'git clone' over SSH, a valid use-case when
+ ;; sharing the host's network namespace.
+ (mkdir-p "/etc")
+ (call-with-output-file "/etc/passwd"
+ (lambda (port)
+ (display (string-join (list (passwd:name passwd)
+ "x" ; but there is no shadow
+ "0" "0" ; user is now root
+ (passwd:gecos passwd)
+ (passwd:dir passwd)
+ bash)
+ ":")
+ port)
+ (newline port)))
;; For convenience, start in the user's current working
;; directory rather than the root directory.
@@ -571,4 +599,5 @@ message if any test fails."
(else
(return
(exit/status
- (launch-environment command profile paths pure?)))))))))))))
+ (launch-environment/fork command profile
+ paths pure?)))))))))))))
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index 1d88b33996..697afc17c3 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -47,7 +47,8 @@
#:autoload (gnu packages base) (canonical-package)
#:autoload (gnu packages guile) (guile-2.0)
#:autoload (gnu packages bootstrap) (%bootstrap-guile)
- #:export (delete-generations
+ #:export (build-and-use-profile
+ delete-generations
display-search-paths
guix-package))
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index e541138682..0efc190b22 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -35,6 +35,7 @@
#:select (%gnu-updater %gnome-updater %xorg-updater))
#:use-module (guix import elpa)
#:use-module (guix import cran)
+ #:use-module (guix import hackage)
#:use-module (guix gnupg)
#:use-module (gnu packages)
#:use-module ((gnu packages commencement) #:select (%final-inputs))
@@ -198,6 +199,7 @@ unavailable optional dependencies such as Guile-JSON."
%elpa-updater
%cran-updater
%bioconductor-updater
+ %hackage-updater
((guix import pypi) => %pypi-updater)
((guix import gem) => %gem-updater)
((guix import github) => %github-updater)))
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 4563f3df0f..82ce069598 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -780,16 +780,24 @@ PORT. REPORT-PROGRESS is a two-argument procedure such as that returned by
(define-syntax with-networking
(syntax-rules ()
- "Catch DNS lookup errors and gracefully exit."
+ "Catch DNS lookup errors and TLS errors and gracefully exit."
;; Note: no attempt is made to catch other networking errors, because DNS
;; lookup errors are typically the first one, and because other errors are
;; a subset of `system-error', which is harder to filter.
((_ exp ...)
- (catch 'getaddrinfo-error
+ (catch #t
(lambda () exp ...)
- (lambda (key error)
- (leave (_ "host name lookup error: ~a~%")
- (gai-strerror error)))))))
+ (match-lambda*
+ (('getaddrinfo-error error)
+ (leave (_ "host name lookup error: ~a~%")
+ (gai-strerror error)))
+ (('gnutls-error error proc . rest)
+ (let ((error->string (module-ref (resolve-interface '(gnutls))
+ 'error->string)))
+ (leave (_ "TLS error in procedure '~a': ~a~%")
+ proc (error->string error))))
+ (args
+ (apply throw args)))))))
;;;
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 8ebeb4d595..566e7e8768 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -482,6 +482,21 @@ PATTERN, a string. When PATTERN is #f, display all the system generations."
((disk-image)
(system-disk-image os #:disk-image-size image-size))))
+(define (maybe-suggest-running-guix-pull)
+ "Suggest running 'guix pull' if this has never been done before."
+ ;; The reason for this is that the 'guix' binding that we see here comes
+ ;; from either ~/.config/latest or, if it's missing, from the
+ ;; globally-installed Guix, which is necessarily older. See
+ ;; <http://lists.gnu.org/archive/html/guix-devel/2014-08/msg00057.html> for
+ ;; a discussion.
+ (define latest
+ (string-append (config-directory) "/latest"))
+
+ (unless (file-exists? latest)
+ (warning (_ "~a not found: 'guix pull' was never run~%") latest)
+ (warning (_ "Consider running 'guix pull' before 'reconfigure'.~%"))
+ (warning (_ "Failing to do that may downgrade your system!~%"))))
+
(define* (perform-action action os
#:key grub? dry-run? derivations-only?
use-substitutes? device target
@@ -498,6 +513,9 @@ building anything."
(define println
(cut format #t "~a~%" <>))
+ (when (eq? action 'reconfigure)
+ (maybe-suggest-running-guix-pull))
+
(mlet* %store-monad
((sys (system-derivation-for-action os action
#:image-size image-size
diff --git a/guix/store.scm b/guix/store.scm
index ae52628545..906611658e 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -504,12 +504,13 @@ encoding conversion errors."
(status k))))))))
(define %default-substitute-urls
- ;; Default list of substituters. This is *not* the list used by
- ;; 'guix-daemon', and few clients use it ('guix build --log-file' uses it.)
+ ;; Default list of substituters. This is *not* the list baked in
+ ;; 'guix-daemon', but it is used by 'guix-service-type' and and a couple of
+ ;; clients ('guix build --log-file' uses it.)
(map (if (false-if-exception (resolve-interface '(gnutls)))
(cut string-append "https://" <>)
(cut string-append "http://" <>))
- '("hydra.gnu.org")))
+ '("mirror.hydra.gnu.org" "hydra.gnu.org")))
(define* (set-build-options server
#:key keep-failed? keep-going? fallback?
diff --git a/guix/ui.scm b/guix/ui.scm
index 7b7bee0ac8..f95c63a81b 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -461,6 +461,11 @@ interpreted."
(leave (_ "reference to invalid output '~a' of derivation '~a'~%")
(derivation-missing-output c)
(derivation-file-name (derivation-error-derivation c))))
+ ((file-search-error? c)
+ (leave (_ "file '~a' could not be found in these \
+directories:~{ ~a~}~%")
+ (file-search-error-file-name c)
+ (file-search-error-search-path c)))
((message-condition? c)
;; Normally '&message' error conditions have an i18n'd message.
(leave (_ "~a~%")
@@ -1043,6 +1048,9 @@ DURATION-RELATION with the current time."
"~b ~d ~Y ~T")))
(current (generation-number profile)))
(if (= number current)
+ ;; TRANSLATORS: The word "current" here is an adjective for
+ ;; "Generation", as in "current generation". Use the appropriate
+ ;; gender where applicable.
(format #t (_ "~a\t(current)~%") header)
(format #t "~a~%" header)))))