summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
Diffstat (limited to 'guix')
-rw-r--r--guix/build/dune-build-system.scm4
-rw-r--r--guix/config.scm.in6
-rw-r--r--guix/gexp.scm15
-rw-r--r--guix/git.scm136
-rw-r--r--guix/import/opam.scm46
-rw-r--r--guix/monads.scm15
-rw-r--r--guix/profiles.scm59
-rw-r--r--guix/scripts/build.scm3
-rw-r--r--guix/scripts/package.scm4
-rw-r--r--guix/scripts/pull.scm26
-rw-r--r--guix/self.scm18
-rw-r--r--guix/status.scm87
-rw-r--r--guix/store.scm5
-rw-r--r--guix/ui.scm8
14 files changed, 325 insertions, 107 deletions
diff --git a/guix/build/dune-build-system.scm b/guix/build/dune-build-system.scm
index fcc2d6567d..00b0c7c406 100644
--- a/guix/build/dune-build-system.scm
+++ b/guix/build/dune-build-system.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
+;;; Copyright © 2019 Gabriel Hondet <gabrielhondet@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -49,7 +50,8 @@
"Install the given package."
(let ((out (assoc-ref outputs "out"))
(program (if jbuild? "jbuilder" "dune")))
- (invoke program install-target "--prefix" out))
+ (invoke program install-target "--prefix" out "--libdir"
+ (string-append out "/lib/ocaml/site-lib")))
#t)
(define %standard-phases
diff --git a/guix/config.scm.in b/guix/config.scm.in
index 1a761b912e..d2ec9921c6 100644
--- a/guix/config.scm.in
+++ b/guix/config.scm.in
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2017 Caleb Ristvedt <caleb.ristvedt@cune.org>
;;;
;;; This file is part of GNU Guix.
@@ -73,11 +73,11 @@
(define %state-directory
;; This must match `NIX_STATE_DIR' as defined in `nix/local.mk'.
- (or (getenv "NIX_STATE_DIR")
+ (or (getenv "GUIX_STATE_DIRECTORY")
(string-append %localstatedir "/guix")))
(define %store-database-directory
- (or (getenv "NIX_DB_DIR")
+ (or (getenv "GUIX_DATABASE_DIRECTORY")
(string-append %state-directory "/db")))
(define %config-directory
diff --git a/guix/gexp.scm b/guix/gexp.scm
index f7c064297b..5b5b064b59 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -920,7 +920,18 @@ and in the current monad setting (system type, etc.)"
(simple-format #f "~a:~a" line column)))
"<unknown location>")))
-(define-syntax-parameter current-imported-modules
+(define-syntax-rule (define-syntax-parameter-once name proc)
+ ;; Like 'define-syntax-parameter' but ensure the top-level binding for NAME
+ ;; does not get redefined. This works around a race condition in a
+ ;; multi-threaded context with Guile <= 2.2.4: <https://bugs.gnu.org/27476>.
+ (eval-when (load eval expand compile)
+ (define name
+ (if (module-locally-bound? (current-module) 'name)
+ (module-ref (current-module) 'name)
+ (make-syntax-transformer 'name 'syntax-parameter
+ (list proc))))))
+
+(define-syntax-parameter-once current-imported-modules
;; Current list of imported modules.
(identifier-syntax '()))
@@ -931,7 +942,7 @@ environment."
(identifier-syntax modules)))
body ...))
-(define-syntax-parameter current-imported-extensions
+(define-syntax-parameter-once current-imported-extensions
;; Current list of extensions.
(identifier-syntax '()))
diff --git a/guix/git.scm b/guix/git.scm
index 0666f0c0a9..0e3ce37e26 100644
--- a/guix/git.scm
+++ b/guix/git.scm
@@ -1,6 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
-;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -35,6 +35,8 @@
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
#:export (%repository-cache-directory
+ honor-system-x509-certificates!
+
update-cached-checkout
latest-repository-commit
@@ -43,25 +45,70 @@
git-checkout-url
git-checkout-branch))
+;; XXX: Use this hack instead of #:autoload to avoid compilation errors.
+;; See <http://bugs.gnu.org/12202>.
+(module-autoload! (current-module)
+ '(git submodule) '(repository-submodules))
+
(define %repository-cache-directory
(make-parameter (string-append (cache-directory #:ensure? #f)
"/checkouts")))
+(define (honor-system-x509-certificates!)
+ "Use the system's X.509 certificates for Git checkouts over HTTPS. Honor
+the 'SSL_CERT_FILE' and 'SSL_CERT_DIR' environment variables."
+ ;; On distros such as CentOS 7, /etc/ssl/certs contains only a couple of
+ ;; files (instead of all the certificates) among which "ca-bundle.crt". On
+ ;; other distros /etc/ssl/certs usually contains the whole set of
+ ;; certificates along with "ca-certificates.crt". Try to choose the right
+ ;; one.
+ (let ((file (letrec-syntax ((choose
+ (syntax-rules ()
+ ((_ file rest ...)
+ (let ((f file))
+ (if (and f (file-exists? f))
+ f
+ (choose rest ...))))
+ ((_)
+ #f))))
+ (choose (getenv "SSL_CERT_FILE")
+ "/etc/ssl/certs/ca-certificates.crt"
+ "/etc/ssl/certs/ca-bundle.crt")))
+ (directory (or (getenv "SSL_CERT_DIR") "/etc/ssl/certs")))
+ (and (or file
+ (and=> (stat directory #f)
+ (lambda (st)
+ (> (stat:nlink st) 2))))
+ (begin
+ (set-tls-certificate-locations! directory file)
+ #t))))
+
+(define %certificates-initialized?
+ ;; Whether 'honor-system-x509-certificates!' has already been called.
+ #f)
+
(define-syntax-rule (with-libgit2 thunk ...)
(begin
;; XXX: The right thing to do would be to call (libgit2-shutdown) here,
;; but pointer finalizers used in guile-git may be called after shutdown,
;; resulting in a segfault. Hence, let's skip shutdown call for now.
(libgit2-init!)
+ (unless %certificates-initialized?
+ (honor-system-x509-certificates!)
+ (set! %certificates-initialized? #t))
thunk ...))
(define* (url-cache-directory url
#:optional (cache-directory
- (%repository-cache-directory)))
+ (%repository-cache-directory))
+ #:key recursive?)
"Return the directory associated to URL in %repository-cache-directory."
(string-append
cache-directory "/"
- (bytevector->base32-string (sha256 (string->utf8 url)))))
+ (bytevector->base32-string
+ (sha256 (string->utf8 (if recursive?
+ (string-append "R:" url)
+ url))))))
(define (clone* url directory)
"Clone git repository at URL into DIRECTORY. Upon failure,
@@ -119,18 +166,62 @@ OID (roughly the commit hash) corresponding to REF."
(reset repository obj RESET_HARD)
(object-id obj))
+(define (call-with-repository directory proc)
+ (let ((repository #f))
+ (dynamic-wind
+ (lambda ()
+ (set! repository (repository-open directory)))
+ (lambda ()
+ (proc repository))
+ (lambda ()
+ (repository-close! repository)))))
+
+(define-syntax-rule (with-repository directory repository exp ...)
+ "Open the repository at DIRECTORY and bind REPOSITORY to it within the
+dynamic extent of EXP."
+ (call-with-repository directory
+ (lambda (repository) exp ...)))
+
+(define* (update-submodules repository
+ #:key (log-port (current-error-port)))
+ "Update the submodules of REPOSITORY, a Git repository object."
+ ;; Guile-Git < 0.2.0 did not have (git submodule).
+ (if (false-if-exception (resolve-interface '(git submodule)))
+ (for-each (lambda (name)
+ (let ((submodule (submodule-lookup repository name)))
+ (format log-port (G_ "updating submodule '~a'...~%")
+ name)
+ (submodule-update submodule)
+
+ ;; Recurse in SUBMODULE.
+ (let ((directory (string-append
+ (repository-working-directory repository)
+ "/" (submodule-path submodule))))
+ (with-repository directory repository
+ (update-submodules repository
+ #:log-port log-port)))))
+ (repository-submodules repository))
+ (format (current-error-port)
+ (G_ "Support for submodules is missing; \
+please upgrade Guile-Git.~%"))))
+
(define* (update-cached-checkout url
#:key
(ref '(branch . "master"))
+ recursive?
+ (log-port (%make-void-port "w"))
(cache-directory
(url-cache-directory
- url (%repository-cache-directory))))
+ url (%repository-cache-directory)
+ #:recursive? recursive?)))
"Update the cached checkout of URL to REF in CACHE-DIRECTORY. Return two
values: the cache directory name, and the SHA1 commit (a string) corresponding
to REF.
REF is pair whose key is [branch | commit | tag] and value the associated
-data, respectively [<branch name> | <sha1> | <tag name>]."
+data, respectively [<branch name> | <sha1> | <tag name>].
+
+When RECURSIVE? is true, check out submodules as well, if any."
(define canonical-ref
;; We used to require callers to specify "origin/" for each branch, which
;; made little sense since the cache should be transparent to them. So
@@ -150,6 +241,8 @@ data, respectively [<branch name> | <sha1> | <tag name>]."
;; Only fetch remote if it has not been cloned just before.
(when cache-exists?
(remote-fetch (remote-lookup repository "origin")))
+ (when recursive?
+ (update-submodules repository #:log-port log-port))
(let ((oid (switch-to-ref repository canonical-ref)))
;; Reclaim file descriptors and memory mappings associated with
@@ -162,6 +255,7 @@ data, respectively [<branch name> | <sha1> | <tag name>]."
(define* (latest-repository-commit store url
#:key
+ recursive?
(log-port (%make-void-port "w"))
(cache-directory
(%repository-cache-directory))
@@ -172,21 +266,33 @@ reference to be checkout, once the repository is fetched, is specified by REF.
REF is pair whose key is [branch | commit | tag] and value the associated
data, respectively [<branch name> | <sha1> | <tag name>].
+When RECURSIVE? is true, check out submodules as well, if any.
+
Git repositories are kept in the cache directory specified by
%repository-cache-directory parameter.
Log progress and checkout info to LOG-PORT."
(define (dot-git? file stat)
(and (string=? (basename file) ".git")
- (eq? 'directory (stat:type stat))))
+ (or (eq? 'directory (stat:type stat))
+
+ ;; Submodule checkouts end up with a '.git' regular file that
+ ;; contains metadata about where their actual '.git' directory
+ ;; lives.
+ (and recursive?
+ (eq? 'regular (stat:type stat))))))
(format log-port "updating checkout of '~a'...~%" url)
(let*-values
(((checkout commit)
(update-cached-checkout url
+ #:recursive? recursive?
#:ref ref
#:cache-directory
- (url-cache-directory url cache-directory)))
+ (url-cache-directory url cache-directory
+ #:recursive?
+ recursive?)
+ #:log-port log-port))
((name)
(url+commit->name url commit)))
(format log-port "retrieved commit ~a~%" commit)
@@ -205,9 +311,10 @@ Log progress and checkout info to LOG-PORT."
git-checkout?
(url git-checkout-url)
(branch git-checkout-branch (default "master"))
- (commit git-checkout-commit (default #f)))
+ (commit git-checkout-commit (default #f))
+ (recursive? git-checkout-recursive? (default #f)))
-(define* (latest-repository-commit* url #:key ref log-port)
+(define* (latest-repository-commit* url #:key ref recursive? log-port)
;; Monadic variant of 'latest-repository-commit'.
(lambda (store)
;; The caller--e.g., (guix scripts build)--may not handle 'git-error' so
@@ -216,7 +323,9 @@ Log progress and checkout info to LOG-PORT."
(catch 'git-error
(lambda ()
(values (latest-repository-commit store url
- #:ref ref #:log-port log-port)
+ #:ref ref
+ #:recursive? recursive?
+ #:log-port log-port)
store))
(lambda (key error . _)
(raise (condition
@@ -238,9 +347,14 @@ Log progress and checkout info to LOG-PORT."
;; "Compile" CHECKOUT by updating the local checkout and adding it to the
;; store.
(match checkout
- (($ <git-checkout> url branch commit)
+ (($ <git-checkout> url branch commit recursive?)
(latest-repository-commit* url
#:ref (if commit
`(commit . ,commit)
`(branch . ,branch))
+ #:recursive? recursive?
#:log-port (current-error-port)))))
+
+;; Local Variables:
+;; eval: (put 'with-repository 'scheme-indent-function 2)
+;; End:
diff --git a/guix/import/opam.scm b/guix/import/opam.scm
index c254db5f2c..7b2e832e92 100644
--- a/guix/import/opam.scm
+++ b/guix/import/opam.scm
@@ -1,4 +1,3 @@
-;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
;;;
;;; This file is part of GNU Guix.
@@ -90,8 +89,8 @@
(define-peg-pattern condition-lower all (and (ignore "<") (* SP) condition-string))
(define-peg-pattern condition-and all (and condition-form2 (* SP) (? (ignore "&")) (* SP) condition-form))
(define-peg-pattern condition-or all (and condition-form2 (* SP) (ignore "|") (* SP) condition-form))
-(define-peg-pattern condition-eq all (and condition-content (* SP) (ignore "=") (* SP) condition-content))
-(define-peg-pattern condition-neq all (and condition-content (* SP) (ignore (and "!" "=")) (* SP) condition-content))
+(define-peg-pattern condition-eq all (and (? condition-content) (* SP) (ignore "=") (* SP) condition-content))
+(define-peg-pattern condition-neq all (and (? condition-content) (* SP) (ignore (and "!" "=")) (* SP) condition-content))
(define-peg-pattern condition-content body (or condition-string condition-var))
(define-peg-pattern condition-content2 body (and condition-content (* SP) (not-followed-by (or "&" "=" "!"))))
(define-peg-pattern condition-string all (and QUOTE (* STRCHR) QUOTE))
@@ -117,7 +116,11 @@ path to the repository."
(lambda (dir)
(string-join (cdr (string-split dir #\.)) "."))
versions)))
- (latest-version versions))
+ ;; Workaround for janestreet re-versionning
+ (let ((v-versions (filter (lambda (version) (string-prefix? "v" version)) versions)))
+ (if (null? v-versions)
+ (latest-version versions)
+ (string-append "v" (latest-version (map (lambda (version) (substring version 1)) v-versions))))))
(begin
(format #t (G_ "Package not found in opam repository: ~a~%") package)
#f))))
@@ -127,12 +130,17 @@ path to the repository."
(lambda _
(peg:tree (match-pattern records (get-string-all (current-input-port)))))))
+(define (substitute-char str what with)
+ (string-join (string-split str what) with))
+
(define (ocaml-name->guix-name name)
- (cond
- ((equal? name "ocamlfind") "ocaml-findlib")
- ((string-prefix? "ocaml" name) name)
- ((string-prefix? "conf-" name) (substring name 5))
- (else (string-append "ocaml-" name))))
+ (substitute-char
+ (cond
+ ((equal? name "ocamlfind") "ocaml-findlib")
+ ((string-prefix? "ocaml" name) name)
+ ((string-prefix? "conf-" name) (substring name 5))
+ (else (string-append "ocaml-" name)))
+ #\_ "-"))
(define (metadata-ref file lookup)
(fold (lambda (record acc)
@@ -234,7 +242,9 @@ path to the repository."
(values
`(package
(name ,(ocaml-name->guix-name name))
- (version ,version)
+ (version ,(if (string-prefix? "v" version)
+ (substring version 1)
+ version))
(source
(origin
(method url-fetch)
@@ -247,6 +257,10 @@ path to the repository."
,@(if (null? native-inputs)
'()
`((native-inputs ,(list 'quasiquote native-inputs))))
+ ,@(if (equal? name (guix-name->opam-name (ocaml-name->guix-name name)))
+ '()
+ `((properties
+ ,(list 'quasiquote `((upstream-name . ,name))))))
(home-page ,(metadata-ref opam-content "homepage"))
(synopsis ,(metadata-ref opam-content "synopsis"))
(description ,(metadata-ref opam-content "description"))
@@ -259,6 +273,11 @@ path to the repository."
(opam->guix-package name))
#:guix-name ocaml-name->guix-name))
+(define (guix-name->opam-name name)
+ (if (string-prefix? "ocaml-" name)
+ (substring name 6)
+ name))
+
(define (guix-package->opam-name package)
"Given an OCaml PACKAGE built from OPAM, return the name of the
package in OPAM."
@@ -266,10 +285,9 @@ package in OPAM."
(package-properties package)
'upstream-name))
(name (package-name package)))
- (cond
- (upstream-name upstream-name)
- ((string-prefix? "ocaml-" name) (substring name 6))
- (else name))))
+ (if upstream-name
+ upstream-name
+ (guix-name->opam-name name))))
(define (opam-package? package)
"Return true if PACKAGE is an OCaml package from OPAM"
diff --git a/guix/monads.scm b/guix/monads.scm
index 6ae616aca9..6924471345 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -274,12 +274,23 @@ more optimizations."
(_
#'generic-name))))))))))
-(define-syntax-parameter >>=
+(define-syntax-rule (define-syntax-parameter-once name proc)
+ ;; Like 'define-syntax-parameter' but ensure the top-level binding for NAME
+ ;; does not get redefined. This works around a race condition in a
+ ;; multi-threaded context with Guile <= 2.2.4: <https://bugs.gnu.org/27476>.
+ (eval-when (load eval expand compile)
+ (define name
+ (if (module-locally-bound? (current-module) 'name)
+ (module-ref (current-module) 'name)
+ (make-syntax-transformer 'name 'syntax-parameter
+ (list proc))))))
+
+(define-syntax-parameter-once >>=
;; The name 'bind' is already taken, so we choose this (obscure) symbol.
(lambda (s)
(syntax-violation '>>= ">>= (bind) used outside of 'with-monad'" s)))
-(define-syntax-parameter return
+(define-syntax-parameter-once return
(lambda (s)
(syntax-violation 'return "return used outside of 'with-monad'" s)))
diff --git a/guix/profiles.scm b/guix/profiles.scm
index 598e0acf62..6564526aee 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2014, 2016 Alex Kost <alezost@gmail.com>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
@@ -63,6 +63,10 @@
&missing-generation-error
missing-generation-error?
missing-generation-error-generation
+ &unmatched-pattern-error
+ unmatched-pattern-error?
+ unmatched-pattern-error-pattern
+ unmatched-pattern-error-manifest
manifest make-manifest
manifest?
@@ -156,6 +160,11 @@
(entry profile-collision-error-entry) ;<manifest-entry>
(conflict profile-collision-error-conflict)) ;<manifest-entry>
+(define-condition-type &unmatched-pattern-error &error
+ unmatched-pattern-error?
+ (pattern unmatched-pattern-error-pattern) ;<manifest-pattern>
+ (manifest unmatched-pattern-error-manifest)) ;<manifest>
+
(define-condition-type &missing-generation-error &profile-error
missing-generation-error?
(generation missing-generation-error-generation))
@@ -559,16 +568,21 @@ no match.."
(->bool (manifest-lookup manifest pattern)))
(define (manifest-matching-entries manifest patterns)
- "Return all the entries of MANIFEST that match one of the PATTERNS."
- (define predicates
- (map entry-predicate patterns))
-
- (define (matches? entry)
- (any (lambda (pred)
- (pred entry))
- predicates))
-
- (filter matches? (manifest-entries manifest)))
+ "Return all the entries of MANIFEST that match one of the PATTERNS. Raise
+an '&unmatched-pattern-error' if none of the entries of MANIFEST matches one
+of PATTERNS."
+ (fold-right (lambda (pattern matches)
+ (match (filter (entry-predicate pattern)
+ (manifest-entries manifest))
+ (()
+ (raise (condition
+ (&unmatched-pattern-error
+ (pattern pattern)
+ (manifest manifest)))))
+ (lst
+ (append lst matches))))
+ '()
+ patterns))
(define (manifest-search-paths manifest)
"Return the list of search path specifications that apply to MANIFEST,
@@ -1300,12 +1314,22 @@ the entries in MANIFEST."
(srfi srfi-19))
(define (compute-entries)
- (append-map (lambda (directory)
- (let ((man (string-append directory "/share/man")))
- (if (directory-exists? man)
- (mandb-entries man)
- '())))
- '#$(manifest-inputs manifest)))
+ ;; This is the most expensive part (I/O and CPU, due to
+ ;; decompression), so report progress as we traverse INPUTS.
+ (let* ((inputs '#$(manifest-inputs manifest))
+ (total (length inputs)))
+ (append-map (lambda (directory count)
+ (format #t "\r[~3d/~3d] building list of \
+man-db entries..."
+ count total)
+ (force-output)
+ (let ((man (string-append directory
+ "/share/man")))
+ (if (directory-exists? man)
+ (mandb-entries man)
+ '())))
+ inputs
+ (iota total 1))))
(define man-directory
(string-append #$output "/share/man"))
@@ -1320,6 +1344,7 @@ the entries in MANIFEST."
"/index.db")
entries))
(duration (time-difference (current-time) start)))
+ (newline)
(format #t "~a entries processed in ~,1f s~%"
(length entries)
(+ (time-second duration)
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index 5a158799ae..fb7e04904d 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -308,7 +308,8 @@ strings like \"guile-next=stable-3.0\" meaning that packages are built using
(package
(inherit old)
(version (string-append "git." branch))
- (source (git-checkout (url url) (branch branch)))))
+ (source (git-checkout (url url) (branch branch)
+ (recursive? #t)))))
(let* ((replacements (evaluate-git-replacement-specs replacement-specs
replace))
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index a633d2ee6d..8a71467b52 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -739,9 +739,9 @@ processed, #f otherwise."
(available (fold-available-packages
(lambda* (name version result
#:key outputs location
- supported? superseded?
+ supported? deprecated?
#:allow-other-keys)
- (if (and supported? (not superseded?))
+ (if (and supported? (not deprecated?))
(if regexp
(if (regexp-exec regexp name)
(cons `(,name ,version
diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm
index 683ab3f059..3320200c07 100644
--- a/guix/scripts/pull.scm
+++ b/guix/scripts/pull.scm
@@ -216,30 +216,8 @@ true, display what would be built without actually building it."
(define (honor-x509-certificates store)
"Use the right X.509 certificates for Git checkouts over HTTPS."
- ;; On distros such as CentOS 7, /etc/ssl/certs contains only a couple of
- ;; files (instead of all the certificates) among which "ca-bundle.crt". On
- ;; other distros /etc/ssl/certs usually contains the whole set of
- ;; certificates along with "ca-certificates.crt". Try to choose the right
- ;; one.
- (let ((file (letrec-syntax ((choose
- (syntax-rules ()
- ((_ file rest ...)
- (let ((f file))
- (if (and f (file-exists? f))
- f
- (choose rest ...))))
- ((_)
- #f))))
- (choose (getenv "SSL_CERT_FILE")
- "/etc/ssl/certs/ca-certificates.crt"
- "/etc/ssl/certs/ca-bundle.crt")))
- (directory (or (getenv "SSL_CERT_DIR") "/etc/ssl/certs")))
- (if (or file
- (and=> (stat directory #f)
- (lambda (st)
- (> (stat:nlink st) 2))))
- (set-tls-certificate-locations! directory file)
- (honor-lets-encrypt-certificates! store))))
+ (unless (honor-system-x509-certificates!)
+ (honor-lets-encrypt-certificates! store)))
(define (report-git-error error)
"Report the given Guile-Git error."
diff --git a/guix/self.scm b/guix/self.scm
index f028bdbfdd..a45470a0a6 100644
--- a/guix/self.scm
+++ b/guix/self.scm
@@ -460,17 +460,27 @@ load path."
the modules (under share/guile/site and lib/guile), and DEPENDENCIES, a list
of packages depended on. COMMAND is the 'guix' program to use; INFO is the
Info manual."
+ (define (wrap daemon)
+ (program-file "guix-daemon"
+ #~(begin
+ (setenv "GUIX" #$command)
+ (apply execl #$(file-append daemon "/bin/guix-daemon")
+ "guix-daemon" (cdr (command-line))))))
+
(computed-file name
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
+ (define daemon
+ #$(and daemon (wrap daemon)))
+
(mkdir-p (string-append #$output "/bin"))
(symlink #$command
(string-append #$output "/bin/guix"))
- (when #$daemon
- (symlink (string-append #$daemon "/bin/guix-daemon")
+ (when daemon
+ (symlink daemon
(string-append #$output "/bin/guix-daemon")))
(let ((share (string-append #$output "/share"))
@@ -786,11 +796,11 @@ Info manual."
(define %state-directory
;; This must match `NIX_STATE_DIR' as defined in
;; `nix/local.mk'.
- (or (getenv "NIX_STATE_DIR")
+ (or (getenv "GUIX_STATE_DIRECTORY")
(string-append %localstatedir "/guix")))
(define %store-database-directory
- (or (getenv "NIX_DB_DIR")
+ (or (getenv "GUIX_DATABASE_DIRECTORY")
(string-append %state-directory "/db")))
(define %config-directory
diff --git a/guix/status.scm b/guix/status.scm
index e3375816c5..cd5027ef17 100644
--- a/guix/status.scm
+++ b/guix/status.scm
@@ -30,6 +30,7 @@
#:use-module (guix memoization)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (srfi srfi-9 gnu)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
#:use-module (ice-9 regex)
@@ -54,6 +55,9 @@
build
build-derivation
build-system
+ build-log-file
+ build-phase
+ build-completion
download?
download
@@ -100,18 +104,21 @@
(default '())))
;; On-going or completed build.
-(define-record-type <build>
- (%build derivation id system log-file completion)
+(define-immutable-record-type <build>
+ (%build derivation id system log-file phase completion)
build?
(derivation build-derivation) ;string (.drv file name)
(id build-id) ;#f | integer
(system build-system) ;string
(log-file build-log-file) ;#f | string
- (completion build-completion)) ;#f | integer (percentage)
+ (phase build-phase ;#f | symbol
+ set-build-phase)
+ (completion build-completion ;#f | integer (percentage)
+ set-build-completion))
-(define* (build derivation system #:key id log-file completion)
+(define* (build derivation system #:key id log-file phase completion)
"Return a new build."
- (%build derivation id system log-file completion))
+ (%build derivation id system log-file phase completion))
;; On-going or completed downloads. Downloads can be stem from substitutes
;; and from "builtin:download" fixed-output derivations.
@@ -142,6 +149,10 @@
(lambda (download)
(string=? item (download-item download))))
+(define %phase-start-rx
+ ;; Match the "starting phase" message emitted by 'gnu-build-system'.
+ (make-regexp "^starting phase [`']([^']+)'"))
+
(define %percentage-line-rx
;; Things like CMake write lines like "[ 10%] gcc -c …". This regexp
;; matches them.
@@ -156,13 +167,6 @@
(define (update-build status id line)
"Update STATUS based on LINE, a build output line for ID that might contain
a completion indication."
- (define (set-completion b %)
- (build (build-derivation b)
- (build-system b)
- #:id (build-id b)
- #:log-file (build-log-file b)
- #:completion %))
-
(define (find-build)
(find (lambda (build)
(and (build-id build)
@@ -173,7 +177,7 @@ a completion indication."
(let ((build (find-build)))
(build-status
(inherit status)
- (building (cons (set-completion build %)
+ (building (cons (set-build-completion build %)
(delq build (build-status-building status)))))))
(cond ((string-any #\nul line)
@@ -190,6 +194,19 @@ a completion indication."
(let ((done (string->number (match:substring match 1)))
(total (string->number (match:substring match 3))))
(update (* 100. (/ done total))))))
+ ((regexp-exec %phase-start-rx line)
+ =>
+ (lambda (match)
+ (let ((phase (match:substring match 1))
+ (build (find-build)))
+ (if build
+ (build-status
+ (inherit status)
+ (building
+ (cons (set-build-phase (set-build-completion build #f)
+ (string->symbol phase))
+ (delq build (build-status-building status)))))
+ status))))
(else
status)))
@@ -328,14 +345,21 @@ build-log\" traces."
(define spin!
(let ((steps (circular-list "\\" "|" "/" "-")))
- (lambda (port)
- "Display a spinner on PORT."
+ (lambda (phase port)
+ "Display a spinner on PORT. If PHASE is true, display it as a hint of
+the current build phase."
(when (isatty?* port)
(match steps
((first . rest)
(set! steps rest)
(display "\r\x1b[K" port)
(display first port)
+ (when phase
+ (display " " port)
+ ;; TRANSLATORS: The word "phase" here denotes a "build phase";
+ ;; "~a" is a placeholder for the untranslated name of the current
+ ;; build phase--e.g., 'configure' or 'build'.
+ (format port (G_ "'~a' phase") phase))
(force-output port)))))))
(define (color-output? port)
@@ -441,12 +465,18 @@ addition to build events."
(cut colorize-string <> 'RED 'BOLD)
identity))
- (define (report-build-progress %)
+ (define (report-build-progress phase %)
(let ((% (min (max % 0) 100))) ;sanitize
(erase-current-line port)
- (format port "~3d% " (inexact->exact (round %)))
- (display (progress-bar % (- (current-terminal-columns) 5))
- port)
+ (let* ((prefix (format #f "~3d% ~@['~a' ~]"
+ (inexact->exact (round %))
+ (case phase
+ ((build) #f) ;not useful to display it
+ (else phase))))
+ (length (string-length prefix)))
+ (display prefix port)
+ (display (progress-bar % (- (current-terminal-columns) length))
+ port))
(force-output port)))
(define print-log-line
@@ -460,13 +490,20 @@ addition to build events."
(match (build-status-building status)
((build) ;single job
(match (build-completion build)
- ((? number? %) (report-build-progress %))
- (_ (spin! port))))
+ ((? number? %)
+ (report-build-progress (build-phase build) %))
+ (_
+ (spin! (build-phase build) port))))
(_
- (spin! port))))))
+ (spin! #f port))))))
+
+ (define erase-current-line*
+ (if (and (not print-log?) (isatty?* port))
+ (lambda ()
+ (erase-current-line port)
+ (force-output port))
+ (const #t)))
- (unless print-log?
- (display "\r" port)) ;erase the spinner
(match event
(('build-started drv . _)
(let ((properties (derivation-properties
@@ -491,6 +528,7 @@ addition to build events."
(format port (info (G_ "building ~a...")) drv))))
(newline port))
(('build-succeeded drv . _)
+ (erase-current-line*) ;erase spinner or progress bar
(when (or print-log? (not (extended-build-trace-supported?)))
(format port (success (G_ "successfully built ~a")) drv)
(newline port))
@@ -503,6 +541,7 @@ addition to build events."
(length ongoing))
(map build-derivation ongoing)))))
(('build-failed drv . _)
+ (erase-current-line*) ;erase spinner or progress bar
(format port (failure (G_ "build of ~a failed")) drv)
(newline port)
(match (derivation-log-file drv)
diff --git a/guix/store.scm b/guix/store.scm
index d079147529..0a0a7c7c52 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -1856,8 +1856,9 @@ syntactically valid store path."
"Return the build log file for DRV, a derivation file name, or #f if it
could not be found."
(let* ((base (basename drv))
- (log (string-append (dirname %state-directory) ; XXX
- "/log/guix/drvs/"
+ (log (string-append (or (getenv "GUIX_LOG_DIRECTORY")
+ (string-append %localstatedir "/log/guix"))
+ "/drvs/"
(string-take base 2) "/"
(string-drop base 2)))
(log.gz (string-append log ".gz"))
diff --git a/guix/ui.scm b/guix/ui.scm
index 9eab4ba3f7..f0465519b6 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -643,6 +643,14 @@ or remove one of them from the profile.")
(leave (G_ "generation ~a of profile '~a' does not exist~%")
(missing-generation-error-generation c)
(profile-error-profile c)))
+ ((unmatched-pattern-error? c)
+ (let ((pattern (unmatched-pattern-error-pattern c)))
+ (leave (G_ "package '~a~@[@~a~]~@[:~a~]' not found in profile~%")
+ (manifest-pattern-name pattern)
+ (manifest-pattern-version pattern)
+ (match (manifest-pattern-output pattern)
+ ("out" #f)
+ (output output)))))
((profile-collision-error? c)
(let ((entry (profile-collision-error-entry c))
(conflict (profile-collision-error-conflict c)))