From 0865d8a8f6c229fef5bcba647cc7b37c2f3d3dae Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Fri, 21 Dec 2018 17:48:55 +0530 Subject: guix: lint: Check for source URIs redirecting to GitHub. * guix/scripts/lint.scm (check-github-uri): New procedure. (%checkers): Add it. * doc/guix.texi (Invoking guix lint): Document it. * tests/lint.scm ("github-url", "github-url: one suggestion"): New tests. --- tests/lint.scm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/lint.scm b/tests/lint.scm index 300153e24e..d4aa7c0e8e 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2016 Hartmut Goebel ;;; Copyright © 2017 Alex Kost ;;; Copyright © 2017 Efraim Flashner +;;; Copyright © 2018 Arun Isaac ;;; ;;; This file is part of GNU Guix. ;;; @@ -669,6 +670,33 @@ (check-mirror-url (dummy-package "x" (source source))))) "mirror://gnu/foo/foo.tar.gz")) +(test-assert "github-url" + (string-null? + (with-warnings + (with-http-server 200 %long-string + (check-github-url + (dummy-package "x" (source + (origin + (method url-fetch) + (uri (%local-url)) + (sha256 %null-sha256))))))))) + +(let ((github-url "https://github.com/foo/bar/bar-1.0.tar.gz")) + (test-assert "github-url: one suggestion" + (string-contains + (with-warnings + (with-http-server (301 `((location . ,(string->uri github-url)))) "" + (let ((initial-uri (%local-url))) + (parameterize ((%http-server-port (+ 1 (%http-server-port)))) + (with-http-server (302 `((location . ,(string->uri initial-uri)))) "" + (check-github-url + (dummy-package "x" (source + (origin + (method url-fetch) + (uri (%local-url)) + (sha256 %null-sha256)))))))))) + github-url))) + (test-assert "cve" (mock ((guix scripts lint) package-vulnerabilities (const '())) (string-null? -- cgit v1.2.3 From c180017b6f7e9b6d23238c1fbaac986c435cd35e Mon Sep 17 00:00:00 2001 From: Efraim Flashner Date: Tue, 25 Dec 2018 16:29:12 +0200 Subject: lint: Check for unstable tarballs. * guix/scripts/lint.scm (check-source-unstable-tarball): New procedure. (%checkers): Add it. * tests/lint.scm ("source-unstable-tarball", "source-unstable-tarball: source #f", "source-unstable-tarball: valid", "source-unstable-tarball: package named archive", "source-unstable-tarball: not-github", "source-unstable-tarball: git-fetch"): New tests. * doc/guix.texi (Invoking guix lint): Document it. --- doc/guix.texi | 5 ++++ guix/scripts/lint.scm | 23 ++++++++++++++- tests/lint.scm | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/doc/guix.texi b/doc/guix.texi index 20952e9a36..fcb5b8c088 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -7704,6 +7704,11 @@ URL. Check that the source file name is meaningful, e.g.@: is not just a version number or ``git-checkout'', without a declared @code{file-name} (@pxref{origin Reference}). +@item source-unstable-tarball +Parse the @code{source} URL to determine if a tarball from GitHub is +autogenerated or if it is a release tarball. Unfortunately GitHub's +autogenerated tarballs are sometimes regenerated. + @item cve @cindex security vulnerabilities @cindex CVE, Common Vulnerabilities and Exposures diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm index 354f6f7031..2c1c7ec669 100644 --- a/guix/scripts/lint.scm +++ b/guix/scripts/lint.scm @@ -7,7 +7,7 @@ ;;; Copyright © 2016 Hartmut Goebel ;;; Copyright © 2017 Alex Kost ;;; Copyright © 2017 Tobias Geerinckx-Rice -;;; Copyright © 2017 Efraim Flashner +;;; Copyright © 2017, 2018 Efraim Flashner ;;; Copyright © 2018 Arun Isaac ;;; ;;; This file is part of GNU Guix. @@ -76,6 +76,7 @@ check-home-page check-source check-source-file-name + check-source-unstable-tarball check-mirror-url check-github-url check-license @@ -752,6 +753,22 @@ descriptions maintained upstream." (G_ "the source file name should contain the package name") 'source)))) +(define (check-source-unstable-tarball package) + "Emit a warning if PACKAGE's source is an autogenerated tarball." + (define (check-source-uri uri) + (when (and (string=? (uri-host (string->uri uri)) "github.com") + (string=? (third (split-and-decode-uri-path + (uri-path (string->uri uri)))) + "archive")) + (emit-warning package + (G_ "the source URI should not be an autogenerated tarball") + 'source))) + (let ((origin (package-source package))) + (when (and (origin? origin) + (eqv? (origin-method origin) url-fetch)) + (let ((uris (origin-uris origin))) + (for-each check-source-uri uris))))) + (define (check-mirror-url package) "Check whether PACKAGE uses source URLs that should be 'mirror://'." (define (check-mirror-uri uri) ;XXX: could be optimized @@ -1098,6 +1115,10 @@ or a list thereof") (name 'source-file-name) (description "Validate file names of sources") (check check-source-file-name)) + (lint-checker + (name 'source-unstable-tarball) + (description "Check for autogenerated tarballs") + (check check-source-unstable-tarball)) (lint-checker (name 'derivation) (description "Report failure to compile a package to a derivation") diff --git a/tests/lint.scm b/tests/lint.scm index d4aa7c0e8e..fe12bebd88 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -572,6 +572,86 @@ (check-source-file-name pkg))) "file name should contain the package name")))) +(test-assert "source-unstable-tarball" + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source + (origin + (method url-fetch) + (uri "https://github.com/example/example/archive/v0.0.tar.gz") + (sha256 %null-sha256)))))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")) + +(test-assert "source-unstable-tarball: source #f" + (not + (->bool + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source #f)))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")))) + +(test-assert "source-unstable-tarball: valid" + (not + (->bool + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source + (origin + (method url-fetch) + (uri "https://github.com/example/example/releases/download/x-0.0/x-0.0.tar.gz") + (sha256 %null-sha256)))))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")))) + +(test-assert "source-unstable-tarball: package named archive" + (not + (->bool + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source + (origin + (method url-fetch) + (uri "https://github.com/example/archive/releases/download/x-0.0/x-0.0.tar.gz") + (sha256 %null-sha256)))))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")))) + +(test-assert "source-unstable-tarball: not-github" + (not + (->bool + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source + (origin + (method url-fetch) + (uri "https://bitbucket.org/archive/example/download/x-0.0.tar.gz") + (sha256 %null-sha256)))))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")))) + +(test-assert "source-unstable-tarball: git-fetch" + (not + (->bool + (string-contains + (with-warnings + (let ((pkg (dummy-package "x" + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/archive/example.git") + (commit "0"))) + (sha256 %null-sha256)))))) + (check-source-unstable-tarball pkg))) + "source URI should not be an autogenerated tarball")))) + (test-skip (if (http-server-can-listen?) 0 1)) (test-equal "source: 200" "" -- cgit v1.2.3 From 9ec154f51f52ee3702c611637e96ccb0d59f543a Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sat, 5 Jan 2019 00:01:18 +0100 Subject: gexp: Lowering a honors SYSTEM and TARGET. * guix/gexp.scm (computed-file-compiler): Pass #:system and #:target to 'gexp->derivation'. * tests/gexp.scm ("lower-object, computed-file, #:system"): New test. --- guix/gexp.scm | 7 ++++--- tests/gexp.scm | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/guix/gexp.scm b/guix/gexp.scm index 88cabc8ed5..febd72a904 100644 --- a/guix/gexp.scm +++ b/guix/gexp.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2018 Clément Lassieur ;;; Copyright © 2018 Jan Nieuwenhuizen ;;; @@ -388,8 +388,9 @@ This is the declarative counterpart of 'gexp->derivation'." (mlet %store-monad ((guile (lower-object guile system #:target target))) (apply gexp->derivation name gexp #:guile-for-build guile - options)) - (apply gexp->derivation name gexp options))))) + #:system system #:target target options)) + (apply gexp->derivation name gexp + #:system system #:target target options))))) (define-record-type (%program-file name gexp guile path) diff --git a/tests/gexp.scm b/tests/gexp.scm index 35a76a496e..c4b437cd49 100644 --- a/tests/gexp.scm +++ b/tests/gexp.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -1171,6 +1171,24 @@ (string=? (readlink (string-append comp "/text")) text))))))) +(test-equal "lower-object, computed-file, #:system" + '("mips64el-linux") + (run-with-store %store + (let* ((exp #~(symlink #$coreutils #$output)) + (computed (computed-file "computed" exp + #:guile %bootstrap-guile))) + ;; Make sure that the SYSTEM argument to 'lower-object' is honored. + (mlet* %store-monad ((drv (lower-object computed "mips64el-linux")) + (refs (references* (derivation-file-name drv)))) + (return (delete-duplicates + (filter-map (lambda (file) + (and (string-suffix? ".drv" file) + (let ((drv (read-derivation-from-file + file))) + (derivation-system drv)))) + (cons (derivation-file-name drv) + refs)))))))) + (test-assert "lower-object & gexp-input-error?" (guard (c ((gexp-input-error? c) (gexp-error-invalid-input c))) -- cgit v1.2.3 From a65177a657b0cb36d45f2e8db574ea9c10f89a1f Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 6 Jan 2019 22:02:40 +0100 Subject: maint: Remove 'cond-expand' forms for Guile 2.0. Note: Leave 'cond-expand' forms used in the build-side modules that can run on %BOOTSTRAP-GUILE, which is currently Guile 2.0. * guix/build/compile.scm: Move 'use-modules' clause from 'cond-expand' to 'define-module' form. (%default-optimizations): Remove 'cond-expand'. * guix/build/download.scm (tls-wrap): Remove 'cond-expand'. * guix/build/syscalls.scm: Remove 'cond-expand' form around '%set-automatic-finalization-enabled?!' and 'without-automatic-finalization'. * guix/inferior.scm (port->inferior): Remove 'cond-expand'. * guix/scripts/pack.scm (wrapped-package)[build]: Remove 'cond-expand'. * guix/status.scm (build-event-output-port): Remove 'cond-expand'. * guix/store.scm (open-inet-socket): Remove 'cond-expand'. * guix/ui.scm (install-locale): Remove 'cond-expand'. * tests/status.scm ("current-build-output-port, UTF-8 + garbage"): Remove 'cond-expand'. * tests/store.scm ("current-build-output-port, UTF-8 + garbage"): Remove 'cond-expand'. --- guix/build/compile.scm | 18 +++++---------- guix/build/download.scm | 6 ++--- guix/build/syscalls.scm | 58 +++++++++++++++++++++---------------------------- guix/inferior.scm | 6 ++--- guix/scripts/pack.scm | 6 ++--- guix/status.scm | 6 ++--- guix/store.scm | 7 +----- guix/ui.scm | 5 ----- tests/status.scm | 6 ++--- tests/store.scm | 6 ++--- 10 files changed, 44 insertions(+), 80 deletions(-) (limited to 'tests') diff --git a/guix/build/compile.scm b/guix/build/compile.scm index 5a1363556a..215489f136 100644 --- a/guix/build/compile.scm +++ b/guix/build/compile.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2013, 2014, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer ;;; ;;; This file is part of GNU Guix. @@ -26,28 +26,22 @@ #:use-module (system base message) #:use-module (guix modules) #:use-module (guix build utils) + #:use-module (language tree-il optimize) + #:use-module (language cps optimize) #:export (%default-optimizations %lightweight-optimizations compile-files)) ;;; Commentary: ;;; -;;; Support code to compile Guile code as efficiently as possible (both with -;;; Guile 2.0 and 2.2). +;;; Support code to compile Guile code as efficiently as possible (with 2.2). ;;; ;;; Code: -(cond-expand - (guile-2.2 (use-modules (language tree-il optimize) - (language cps optimize))) - (else #f)) - (define %default-optimizations ;; Default optimization options (equivalent to -O2 on Guile 2.2). - (cond-expand - (guile-2.2 (append (tree-il-default-optimization-options) - (cps-default-optimization-options))) - (else '()))) + (append (tree-il-default-optimization-options) + (cps-default-optimization-options))) (define %lightweight-optimizations ;; Lightweight optimizations (like -O0, but with partial evaluation). diff --git a/guix/build/download.scm b/guix/build/download.scm index 54163849a2..199702a679 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2015 Mark H Weaver ;;; Copyright © 2017 Tobias Geerinckx-Rice ;;; @@ -314,9 +314,7 @@ host name without trailing dot." ;; Write HTTP requests line by line rather than byte by byte: ;; . This is possible with Guile >= 2.2. - (cond-expand - (guile-2.2 (setvbuf record 'line)) - (else #f)) + (setvbuf record 'line) record))) diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index 56a689f667..d75c11ada7 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2015 David Thompson ;;; Copyright © 2015 Mark H Weaver ;;; Copyright © 2017 Mathieu Othacehe @@ -699,39 +699,31 @@ mounted at FILE." (define CLONE_NEWPID #x20000000) (define CLONE_NEWNET #x40000000) -(cond-expand - (guile-2.2 - (define %set-automatic-finalization-enabled?! - ;; When using a statically-linked Guile, for instance in the initrd, we - ;; cannot resolve this symbol, but most of the time we don't need it - ;; anyway. Thus, delay it. - (let ((proc (delay - (pointer->procedure int - (dynamic-func - "scm_set_automatic_finalization_enabled" - (dynamic-link)) - (list int))))) - (lambda (enabled?) - "Switch on or off automatic finalization in a separate thread. +(define %set-automatic-finalization-enabled?! + ;; When using a statically-linked Guile, for instance in the initrd, we + ;; cannot resolve this symbol, but most of the time we don't need it + ;; anyway. Thus, delay it. + (let ((proc (delay + (pointer->procedure int + (dynamic-func + "scm_set_automatic_finalization_enabled" + (dynamic-link)) + (list int))))) + (lambda (enabled?) + "Switch on or off automatic finalization in a separate thread. Turning finalization off shuts down the finalization thread as a side effect." - (->bool ((force proc) (if enabled? 1 0)))))) - - (define-syntax-rule (without-automatic-finalization exp) - "Turn off automatic finalization within the dynamic extent of EXP." - (let ((enabled? #t)) - (dynamic-wind - (lambda () - (set! enabled? (%set-automatic-finalization-enabled?! #f))) - (lambda () - exp) - (lambda () - (%set-automatic-finalization-enabled?! enabled?)))))) - - (else - (define-syntax-rule (without-automatic-finalization exp) - ;; Nothing to do here: Guile 2.0 does not have a separate finalization - ;; thread. - exp))) + (->bool ((force proc) (if enabled? 1 0)))))) + +(define-syntax-rule (without-automatic-finalization exp) + "Turn off automatic finalization within the dynamic extent of EXP." + (let ((enabled? #t)) + (dynamic-wind + (lambda () + (set! enabled? (%set-automatic-finalization-enabled?! #f))) + (lambda () + exp) + (lambda () + (%set-automatic-finalization-enabled?! enabled?))))) ;; The libc interface to sys_clone is not useful for Scheme programs, so the ;; low-level system call is wrapped instead. The 'syscall' function is diff --git a/guix/inferior.scm b/guix/inferior.scm index 973bd5264e..a6e6d2f16e 100644 --- a/guix/inferior.scm +++ b/guix/inferior.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018 Ludovic Courtès +;;; Copyright © 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -137,9 +137,7 @@ it's an old Guix." "Given PIPE, an input/output port, return an inferior that talks over PIPE. PIPE is closed with CLOSE when 'close-inferior' is called on the returned inferior." - (cond-expand - ((and guile-2 (not guile-2.2)) #t) - (else (setvbuf pipe 'line))) + (setvbuf pipe 'line) (match (read pipe) (('repl-version 0 rest ...) diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 98b06971bd..e137fb136a 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017, 2018 Ludovic Courtès +;;; Copyright © 2015, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2017, 2018 Ricardo Wurmus ;;; Copyright © 2018 Konrad Hinsen ;;; Copyright © 2018 Chris Marusich @@ -553,9 +553,7 @@ please email '~a'~%") "run.c" "-o" result) (delete-file "run.c"))) - (setvbuf (current-output-port) - (cond-expand (guile-2.2 'line) - (else _IOLBF))) + (setvbuf (current-output-port) 'line) ;; Link the top-level files of PACKAGE so that search paths are ;; properly defined in PROFILE/etc/profile. diff --git a/guix/status.scm b/guix/status.scm index d4fc4ca16e..1a7cb313ea 100644 --- a/guix/status.scm +++ b/guix/status.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2017, 2018 Ludovic Courtès +;;; Copyright © 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2018 Ricardo Wurmus ;;; ;;; This file is part of GNU Guix. @@ -636,9 +636,7 @@ The second return value is a thunk to retrieve the current state." ;; The build port actually receives Unicode strings. (set-port-encoding! port "UTF-8") - (cond-expand - ((and guile-2 (not guile-2.2)) #t) - (else (setvbuf port 'line))) + (setvbuf port 'line) (values port (lambda () %state))) (define (call-with-status-report on-event thunk) diff --git a/guix/store.scm b/guix/store.scm index 042dfab67f..1883829231 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2018 Jan Nieuwenhuizen ;;; ;;; This file is part of GNU Guix. @@ -404,11 +404,6 @@ (define (open-inet-socket host port) "Connect to the Unix-domain socket at HOST:PORT and return it. Raise a '&nix-connection-error' upon error." - ;; Define 'TCP_NODELAY' on Guile 2.0. The value is the same on all GNU - ;; systems. - (cond-expand (guile-2.2 #t) - (else (define TCP_NODELAY 1))) - (let ((sock (with-fluids ((%default-port-encoding #f)) ;; This trick allows use of the `scm_c_read' optimization. (socket PF_UNIX SOCK_STREAM 0)))) diff --git a/guix/ui.scm b/guix/ui.scm index 4c31246920..f542cd3e3f 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -427,11 +427,6 @@ report them in a user-friendly way." (lambda _ (setlocale LC_ALL "")) (lambda args - (cond-expand - ;; Guile 2.2 already emits a warning, so let's not add a second one. - (guile-2.2 #t) - (else (warning (G_ "failed to install locale: ~a~%") - (strerror (system-error-errno args))))) (display-hint (G_ "Consider installing the @code{glibc-utf8-locales} or @code{glibc-locales} package and defining @code{GUIX_LOCPATH}, along these lines: diff --git a/tests/status.scm b/tests/status.scm index 99abb41c8b..08a3153218 100644 --- a/tests/status.scm +++ b/tests/status.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018 Ludovic Courtès +;;; Copyright © 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -125,9 +125,7 @@ (test-equal "current-build-output-port, UTF-8 + garbage" ;; What about a mixture of UTF-8 + garbage? - (let ((replacement (cond-expand - ((and guile-2 (not guile-2.2)) "?") - (else "�")))) + (let ((replacement "�")) `((build-log #f ,(string-append "garbage: " replacement "lambda: λ\n")))) (let-values (((port get-status) (build-event-output-port cons '()))) (display "garbage: " port) diff --git a/tests/store.scm b/tests/store.scm index 3ff526cdcf..5ff9308d7d 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -444,9 +444,7 @@ (package-derivation %store %bootstrap-guile)))) (guard (c ((nix-protocol-error? c) #t)) (build-derivations %store (list d)))))))) - (cond-expand - (guile-2.2 "garbage: �lambda: λ") - (else "garbage: ?lambda: λ")))) + "garbage: �lambda: λ")) (test-assert "log-file, derivation" (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '())) -- cgit v1.2.3 From 76832d3420594c8b5feaf7682b84b5481a49a076 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 7 Jan 2019 10:57:18 +0100 Subject: Remove most uses of the _IO*F constants. These constants, for use with 'setvbuf', were deprecated in Guile 2.2 and disappeared in Guile 3.0. Here we keep these constants in build-side code where removing them is not feasible. * guix/build/download-nar.scm (download-nar): Adjust 'setvbuf' calls to the Guile 2.2+ API. * guix/build/download.scm (open-socket-for-uri): Likewise. (open-connection-for-uri, url-fetch): Likewise. * guix/build/make-bootstrap.scm (make-stripped-libc): Likewise. * guix/build/union.scm (setvbuf) [guile-2.0]: New conditional wrapper. (union-build): Adjust to new API. * guix/ftp-client.scm (ftp-open, ftp-list, ftp-retr): Likewise. * guix/http-client.scm (http-fetch): Likewise. * guix/inferior.scm (proxy): Likewise. * guix/scripts/substitute.scm (fetch, http-multiple-get): Likewise. * guix/self.scm (compiled-modules): Likewise. * guix/ssh.scm (remote-daemon-channel, store-import-channel) (store-export-channel): Likewise. * guix/ui.scm (initialize-guix): Likewise. * tests/publish.scm (http-get-port): Likewise. * guix/store.scm (%newlines): Adjust comment. --- guix/build/download-nar.scm | 6 +++--- guix/build/download.scm | 10 +++++----- guix/build/make-bootstrap.scm | 4 ++-- guix/build/union.scm | 21 +++++++++++++++++---- guix/ftp-client.scm | 8 ++++---- guix/http-client.scm | 2 +- guix/inferior.scm | 4 ++-- guix/scripts/substitute.scm | 6 +++--- guix/self.scm | 6 +++--- guix/ssh.scm | 12 ++++++------ guix/store.scm | 2 +- guix/ui.scm | 4 ++-- tests/publish.scm | 6 +++--- 13 files changed, 52 insertions(+), 39 deletions(-) (limited to 'tests') diff --git a/guix/build/download-nar.scm b/guix/build/download-nar.scm index 13f01fb1e8..681f22238d 100644 --- a/guix/build/download-nar.scm +++ b/guix/build/download-nar.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2017 Ludovic Courtès +;;; Copyright © 2017, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -93,8 +93,8 @@ ITEM." "Download and extract the normalized archive for ITEM. Return #t on success, #f otherwise." ;; Let progress reports go through. - (setvbuf (current-error-port) _IONBF) - (setvbuf (current-output-port) _IONBF) + (setvbuf (current-error-port) 'none) + (setvbuf (current-output-port) 'none) (let loop ((urls (urls-for-item item))) (match urls diff --git a/guix/build/download.scm b/guix/build/download.scm index 24b5aa378f..c08221b3b2 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -357,7 +357,7 @@ ETIMEDOUT error is raised." (connect* s (addrinfo:addr ai) timeout) ;; Buffer input and output on this port. - (setvbuf s _IOFBF) + (setvbuf s 'block) ;; If we're using a proxy, make a note of that. (when http-proxy (set-http-proxy-port?! s #t)) s) @@ -401,7 +401,7 @@ VERIFY-CERTIFICATE? is true, verify HTTPS server certificates." (with-https-proxy (let ((s (open-socket-for-uri uri #:timeout timeout))) ;; Buffer input and output on this port. - (setvbuf s _IOFBF %http-receive-buffer-size) + (setvbuf s 'block %http-receive-buffer-size) (if https? (tls-wrap s (uri-host uri) @@ -777,11 +777,11 @@ otherwise simply ignore them." hashes)) content-addressed-mirrors)) - ;; Make this unbuffered so 'progress-report/file' works as expected. _IOLBF + ;; Make this unbuffered so 'progress-report/file' works as expected. 'line ;; means '\n', not '\r', so it's not appropriate here. - (setvbuf (current-output-port) _IONBF) + (setvbuf (current-output-port) 'none) - (setvbuf (current-error-port) _IOLBF) + (setvbuf (current-error-port) 'line) (let try ((uri (append uri content-addressed-uris))) (match uri diff --git a/guix/build/make-bootstrap.scm b/guix/build/make-bootstrap.scm index 43b136248f..48799f7e90 100644 --- a/guix/build/make-bootstrap.scm +++ b/guix/build/make-bootstrap.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Manolis Fragkiskos Ragkousis -;;; Copyright © 2015 Ludovic Courtès +;;; Copyright © 2015, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -67,7 +67,7 @@ when producing a bootstrap libc." util).*\\.so(\\..*)?|lib(machuser|hurduser).so.*|(libc(rt|)|libpthread)\ _nonshared\\.a)$") - (setvbuf (current-output-port) _IOLBF) + (setvbuf (current-output-port) 'line) (let* ((libdir (string-append output "/lib"))) (mkdir-p libdir) (for-each (lambda (file) diff --git a/guix/build/union.scm b/guix/build/union.scm index fff795c4d3..961ac3298b 100644 --- a/guix/build/union.scm +++ b/guix/build/union.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014 Mark H Weaver ;;; Copyright © 2017 Huang Ying ;;; @@ -39,6 +39,19 @@ ;;; ;;; Code: +;; This code can be used with the bootstrap Guile, which is Guile 2.0, so +;; provide a compatibility layer. +(cond-expand + ((and guile-2 (not guile-2.2)) + (define (setvbuf port mode . rest) + (apply (@ (guile) setvbuf) port + (match mode + ('line _IOLBF) + ('block _IOFBF) + ('none _IONBF)) + rest))) + (else #f)) + (define (files-in-directory dirname) (let ((dir (opendir dirname))) (let loop ((files '())) @@ -179,10 +192,10 @@ returns #f, skip the faulty file altogether." (reverse dirs-with-file)))) table))) - (setvbuf (current-output-port) _IOLBF) - (setvbuf (current-error-port) _IOLBF) + (setvbuf (current-output-port) 'line) + (setvbuf (current-error-port) 'line) (when (file-port? log-port) - (setvbuf log-port _IOLBF)) + (setvbuf log-port 'line)) (union-of-directories output (delete-duplicates inputs))) diff --git a/guix/ftp-client.scm b/guix/ftp-client.scm index 0b8f61c276..8d5adcb8ed 100644 --- a/guix/ftp-client.scm +++ b/guix/ftp-client.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès +;;; Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -154,7 +154,7 @@ TIMEOUT, an ETIMEDOUT error is raised." (catch 'system-error (lambda () (connect* s (addrinfo:addr ai) timeout) - (setvbuf s _IOLBF) + (setvbuf s 'line) (let-values (((code message) (%ftp-listen s))) (if (eqv? code 220) (begin @@ -237,7 +237,7 @@ TIMEOUT, an ETIMEDOUT error is raised." (s (socket (addrinfo:fam ai) (addrinfo:socktype ai) (addrinfo:protocol ai)))) (connect* s (address-with-port (addrinfo:addr ai) port) timeout) - (setvbuf s _IOLBF) + (setvbuf s 'line) (dynamic-wind (lambda () #t) @@ -293,7 +293,7 @@ must be closed before CONN can be used for other purposes." (throw 'ftp-error conn "LIST" code message)))) (connect* s (address-with-port (addrinfo:addr ai) port) timeout) - (setvbuf s _IOLBF) + (setvbuf s 'line) (%ftp-command (string-append "RETR " file) 150 (ftp-connection-socket conn)) diff --git a/guix/http-client.scm b/guix/http-client.scm index 07360e6108..067002a79a 100644 --- a/guix/http-client.scm +++ b/guix/http-client.scm @@ -97,7 +97,7 @@ Raise an '&http-get-error' condition if downloading fails." headers)) (_ headers)))) (unless (or buffered? (not (file-port? port))) - (setvbuf port _IONBF)) + (setvbuf port 'none)) (let*-values (((resp data) (http-get uri #:streaming? #t #:port port #:keep-alive? #t diff --git a/guix/inferior.scm b/guix/inferior.scm index a6e6d2f16e..ba8d00866b 100644 --- a/guix/inferior.scm +++ b/guix/inferior.scm @@ -389,8 +389,8 @@ input/output ports.)" ;; Use buffered ports so that 'get-bytevector-some' returns up to the ;; whole buffer like read(2) would--see . - (setvbuf client _IOFBF 65536) - (setvbuf backend _IOFBF 65536) + (setvbuf client 'block 65536) + (setvbuf backend 'block 65536) (let loop () (match (select* (list client backend) '() '()) diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm index 53b1777241..797a76db3f 100755 --- a/guix/scripts/substitute.scm +++ b/guix/scripts/substitute.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014 Nikita Karetnikov ;;; Copyright © 2018 Kyle Meyer ;;; @@ -219,7 +219,7 @@ provide." (set! port (guix:open-connection-for-uri uri #:verify-certificate? #f)) (unless (or buffered? (not (file-port? port))) - (setvbuf port _IONBF))) + (setvbuf port 'none))) (http-fetch uri #:text? #f #:port port #:verify-certificate? #f)))))) (else @@ -567,7 +567,7 @@ initial connection on which HTTP requests are sent." verify-certificate?)))) ;; For HTTPS, P is not a file port and does not support 'setvbuf'. (when (file-port? p) - (setvbuf p _IOFBF (expt 2 16))) + (setvbuf p 'block (expt 2 16))) ;; Send REQUESTS, up to a certain number, in a row. ;; XXX: Do our own caching to work around inefficiencies when diff --git a/guix/self.scm b/guix/self.scm index e9a768bc90..a2ae441d42 100644 --- a/guix/self.scm +++ b/guix/self.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2017, 2018 Ludovic Courtès +;;; Copyright © 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -904,8 +904,8 @@ containing MODULE-FILES and possibly other files as well." #:report-load report-load #:report-compilation report-compilation))) - (setvbuf (current-output-port) _IONBF) - (setvbuf (current-error-port) _IONBF) + (setvbuf (current-output-port) 'none) + (setvbuf (current-error-port) 'none) (set! %load-path (cons #+module-tree %load-path)) (set! %load-path diff --git a/guix/ssh.scm b/guix/ssh.scm index 1ed8406633..d90cb77be0 100644 --- a/guix/ssh.scm +++ b/guix/ssh.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -140,12 +140,12 @@ right away." (match (select read write except) ((read write except) (select read write except 0)))))) - (setvbuf stdout _IONBF) + (setvbuf stdout 'none) ;; Use buffered ports so that 'get-bytevector-some' returns up to the ;; whole buffer like read(2) would--see . - (setvbuf stdin _IOFBF 65536) - (setvbuf sock _IOFBF 65536) + (setvbuf stdin 'block 65536) + (setvbuf sock 'block 65536) (connect sock AF_UNIX ,socket-name) @@ -218,7 +218,7 @@ can be written." (consume-input (current-input-port)) (list 'protocol-error (nix-protocol-error-message c)))) (with-store store - (setvbuf (current-input-port) _IONBF) + (setvbuf (current-input-port) 'none) (import-paths store (current-input-port)) '(success)))) (lambda args @@ -269,7 +269,7 @@ be read. When RECURSIVE? is true, the closure of FILES is exported." (write '(exporting)) ;we're ready (force-output) - (setvbuf (current-output-port) _IONBF) + (setvbuf (current-output-port) 'none) (export-paths store files (current-output-port) #:recursive? ,recursive?)))))) diff --git a/guix/store.scm b/guix/store.scm index 1883829231..1f88eb2b33 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -608,7 +608,7 @@ to OUT, using chunks of BUFFER-SIZE bytes." (define %newlines ;; Newline characters triggering a flush of 'current-build-output-port'. - ;; Unlike Guile's _IOLBF, we flush upon #\return so that progress reports + ;; Unlike Guile's 'line, we flush upon #\return so that progress reports ;; that use that trick are correctly displayed. (char-set #\newline #\return)) diff --git a/guix/ui.scm b/guix/ui.scm index f542cd3e3f..1e089753e1 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -454,8 +454,8 @@ See the \"Application Setup\" section in the manual, for more info.\n"))))) ;; notified via an EPIPE later. (sigaction SIGPIPE SIG_IGN) - (setvbuf (current-output-port) _IOLBF) - (setvbuf (current-error-port) _IOLBF)) + (setvbuf (current-output-port) 'line) + (setvbuf (current-error-port) 'line)) (define* (show-version-and-exit #:optional (command (car (command-line)))) "Display version information for COMMAND and `(exit 0)'." diff --git a/tests/publish.scm b/tests/publish.scm index 79a786e723..097ac036e0 100644 --- a/tests/publish.scm +++ b/tests/publish.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 David Thompson -;;; Copyright © 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -63,12 +63,12 @@ (let ((socket (open-socket-for-uri uri))) ;; Make sure to use an unbuffered port so that we can then peek at the ;; underlying file descriptor via 'call-with-gzip-input-port'. - (setvbuf socket _IONBF) + (setvbuf socket 'none) (call-with-values (lambda () (http-get uri #:port socket #:streaming? #t)) (lambda (response port) - ;; Don't (setvbuf port _IONBF) because of + ;; Don't (setvbuf port 'none) because of ;; (PORT might be a custom binary input port). port)))) -- cgit v1.2.3 From 40fa21c22e1d11b741515fd38f5204a5fa57fbaa Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Mon, 7 Jan 2019 23:11:58 +0530 Subject: guix: lint: Warn only if GitHub URI is not same as the package URI. * guix/scripts/lint.scm (check-github-url): Warn only if the GitHub URI obtained after following redirects is not same as the original URI. * tests/lint.scm ("github-url: already the correct github url"): New test. --- guix/scripts/lint.scm | 11 ++++++----- tests/lint.scm | 13 +++++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm index 9acec48577..0f315a9352 100644 --- a/guix/scripts/lint.scm +++ b/guix/scripts/lint.scm @@ -8,7 +8,7 @@ ;;; Copyright © 2017 Alex Kost ;;; Copyright © 2017 Tobias Geerinckx-Rice ;;; Copyright © 2017, 2018 Efraim Flashner -;;; Copyright © 2018 Arun Isaac +;;; Copyright © 2018, 2019 Arun Isaac ;;; ;;; This file is part of GNU Guix. ;;; @@ -820,10 +820,11 @@ descriptions maintained upstream." (lambda (uri) (and=> (follow-redirects-to-github uri) (lambda (github-uri) - (emit-warning - package - (format #f (G_ "URL should be '~a'") github-uri) - 'source)))) + (unless (string=? github-uri uri) + (emit-warning + package + (format #f (G_ "URL should be '~a'") github-uri) + 'source))))) (origin-uris origin))))) (define (check-derivation package) diff --git a/tests/lint.scm b/tests/lint.scm index fe12bebd88..912a78d111 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -6,7 +6,7 @@ ;;; Copyright © 2016 Hartmut Goebel ;;; Copyright © 2017 Alex Kost ;;; Copyright © 2017 Efraim Flashner -;;; Copyright © 2018 Arun Isaac +;;; Copyright © 2018, 2019 Arun Isaac ;;; ;;; This file is part of GNU Guix. ;;; @@ -775,7 +775,16 @@ (method url-fetch) (uri (%local-url)) (sha256 %null-sha256)))))))))) - github-url))) + github-url)) + (test-assert "github-url: already the correct github url" + (string-null? + (with-warnings + (check-github-url + (dummy-package "x" (source + (origin + (method url-fetch) + (uri github-url) + (sha256 %null-sha256))))))))) (test-assert "cve" (mock ((guix scripts lint) package-vulnerabilities (const '())) -- cgit v1.2.3 From 84a2de36a10dc2ab80f86e16721cbd228c85279e Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 10 Jan 2019 23:33:36 +0100 Subject: services: Deprecate a few more service procedures. These procedures were already either undocumented (and de facto deprecated) or documented as deprecated or redundant. * gnu/services/base.scm (guix-service, guix-publish-service): Mark as deprecated. * gnu/services/mcron.scm (mcron-service): Likewise. * gnu/services/networking.scm (tor-service): Likewise. * doc/guix.texi (Scheduled Job Execution): Remove 'mcron-service' and adjust example. (Networking Services): Remove 'tor-service'. * gnu/tests/base.scm (%mcron-os): Use 'mcron-service-type' instead of 'mcron-service'. * gnu/tests/networking.scm (%tor-os): Use 'tor-service-type' instead of 'tor-service'. * tests/guix-system.sh: Likewise. --- doc/guix.texi | 25 +++++-------------------- gnu/services/base.scm | 8 ++++++-- gnu/services/mcron.scm | 6 ++++-- gnu/services/networking.scm | 7 ++++--- gnu/system/install.scm | 3 ++- gnu/tests/base.scm | 5 +++-- gnu/tests/networking.scm | 2 +- tests/guix-system.sh | 6 ++++-- 8 files changed, 29 insertions(+), 33 deletions(-) (limited to 'tests') diff --git a/doc/guix.texi b/doc/guix.texi index c0cc8d4169..ed7723c00b 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -11684,9 +11684,11 @@ gexps to introduce job definitions that are passed to mcron (operating-system ;; @dots{} - (services (cons (mcron-service (list garbage-collector-job - updatedb-job - idutils-job)) + (services (cons (service mcron-service-type + (mcron-configuration + (jobs (list garbage-collector-job + updatedb-job + idutils-job)))) %base-services))) @end lisp @@ -11709,17 +11711,6 @@ also specify the number of tasks to display: # herd schedule mcron 10 @end example -@deffn {Scheme Procedure} mcron-service @var{jobs} [#:mcron @var{mcron}] -Return an mcron service running @var{mcron} that schedules @var{jobs}, a -list of gexps denoting mcron job specifications. - -This is a shorthand for: -@example -(service mcron-service-type - (mcron-configuration (mcron mcron) (jobs jobs))) -@end example -@end deffn - @defvr {Scheme Variable} mcron-service-type This is the type of the @code{mcron} service, whose value is an @code{mcron-configuration} object. @@ -12313,12 +12304,6 @@ Tor} anonymous networking daemon. The service is configured using a @end defvr -@deffn {Scheme Procedure} tor-service [@var{config-file}] [#:tor @var{tor}] -This procedure is deprecated and will be removed in a future release. Return -a service of the @code{tor-service-type} type. @var{config-file} and -@var{tor} have the same meaning as in @code{}. -@end deffn - @deftp {Data Type} tor-configuration @table @asis @item @code{tor} (default: @code{tor}) diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 6e99cbfec4..8395a856fc 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -1688,7 +1688,9 @@ failed to register public key '~a': ~a~%" key status))))))) (description "Run the build daemon of GNU@tie{}Guix, aka. @command{guix-daemon}."))) -(define* (guix-service #:optional (config %default-guix-configuration)) +(define-deprecated (guix-service #:optional + (config %default-guix-configuration)) + guix-service-type "Return a service that runs the Guix build daemon according to @var{config}." (service guix-service-type config)) @@ -1789,7 +1791,9 @@ failed to register public key '~a': ~a~%" key status))))))) "Add a Shepherd service running @command{guix publish}, a command that allows you to share pre-built binaries with others over HTTP."))) -(define* (guix-publish-service #:key (guix guix) (port 80) (host "localhost")) +(define-deprecated (guix-publish-service #:key (guix guix) + (port 80) (host "localhost")) + guix-publish-service-type "Return a service that runs @command{guix publish} listening on @var{host} and @var{port} (@pxref{Invoking guix publish}). diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm index 120b663e3e..e4b652b3d4 100644 --- a/gnu/services/mcron.scm +++ b/gnu/services/mcron.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -21,6 +21,7 @@ #:use-module (gnu services base) #:use-module (gnu services shepherd) #:autoload (gnu packages guile) (mcron) + #:use-module (guix deprecation) #:use-module (guix records) #:use-module (guix gexp) #:use-module (srfi srfi-1) @@ -142,7 +143,8 @@ files." jobs))))) (default-value (mcron-configuration)))) ;empty job list -(define* (mcron-service jobs #:optional (mcron mcron)) +(define-deprecated (mcron-service jobs #:optional (mcron mcron)) + mcron-service-type "Return an mcron service running @var{mcron} that schedules @var{jobs}, a list of gexps denoting mcron job specifications. diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 2f49bf28dd..cab129e0c3 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -755,9 +755,10 @@ HiddenServicePort ~a ~a~%" "Run the @uref{https://torproject.org, Tor} anonymous networking daemon."))) -(define* (tor-service #:optional - (config-file (plain-file "empty" "")) - #:key (tor tor)) +(define-deprecated (tor-service #:optional + (config-file (plain-file "empty" "")) + #:key (tor tor)) + tor-service-type "Return a service to run the @uref{https://torproject.org, Tor} anonymous networking daemon. diff --git a/gnu/system/install.scm b/gnu/system/install.scm index c345ba0626..19a6f6a038 100644 --- a/gnu/system/install.scm +++ b/gnu/system/install.scm @@ -253,7 +253,8 @@ You have been warned. Thanks for being so brave.\x1b[0m ;; The build daemon. Register the official server keys as trusted. ;; This allows the installation process to use substitutes by ;; default. - (guix-service (guix-configuration (authorize-key? #t))) + (service guix-service-type + (guix-configuration (authorize-key? #t))) ;; Start udev so that useful device nodes are available. ;; Use device-mapper rules for cryptsetup & co; enable the CRDA for diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm index 8d4e218a8f..2b20aac1dc 100644 --- a/gnu/tests/base.scm +++ b/gnu/tests/base.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2018 Clément Lassieur ;;; ;;; This file is part of GNU Guix. @@ -627,7 +627,8 @@ non-ASCII names from /tmp.") (job3 #~(job next-second-from ;to test $PATH "touch witness-touch"))) (simple-operating-system - (mcron-service (list job1 job2 job3))))) + (service mcron-service-type + (mcron-configuration (jobs (list job1 job2 job3))))))) (define (run-mcron-test name) (define os diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm index 9f12a4ae8d..a97b29bc4b 100644 --- a/gnu/tests/networking.scm +++ b/gnu/tests/networking.scm @@ -351,7 +351,7 @@ subnet 192.168.1.0 netmask 255.255.255.0 { (define %tor-os (simple-operating-system - (tor-service))) + (service tor-service-type))) (define %tor-os/unix-socks-socket (simple-operating-system diff --git a/tests/guix-system.sh b/tests/guix-system.sh index 23d2da4903..adb623d244 100644 --- a/tests/guix-system.sh +++ b/tests/guix-system.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +# Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès # Copyright © 2017 Tobias Geerinckx-Rice # Copyright © 2018 Chris Marusich # @@ -258,7 +258,9 @@ cat > "$tmpdir/config.scm"< Date: Tue, 15 Jan 2019 11:31:16 +0100 Subject: guix package: '--upgrade' preserves package order. Fixes . Reported by Chris Marusich . * guix/scripts/package.scm (options->installable)[upgraded]: Use 'fold' instead of 'fold-right'. This reverts eca16a3d1d9e6b2c064e0105c1015258bf2755f2. * tests/guix-package-net.sh: Add 'guix package u' test. --- guix/scripts/package.scm | 12 ++++++------ tests/guix-package-net.sh | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 7ff6bfd6d8..5a8fd203ee 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -604,12 +604,12 @@ and upgrades." (options->upgrade-predicate opts)) (define upgraded - (fold-right (lambda (entry transaction) - (if (upgrade? (manifest-entry-name entry)) - (transaction-upgrade-entry entry transaction) - transaction)) - transaction - (manifest-entries manifest))) + (fold (lambda (entry transaction) + (if (upgrade? (manifest-entry-name entry)) + (transaction-upgrade-entry entry transaction) + transaction)) + transaction + (manifest-entries manifest))) (define to-install (filter-map (match-lambda diff --git a/tests/guix-package-net.sh b/tests/guix-package-net.sh index 927c856b23..82c346dd4c 100644 --- a/tests/guix-package-net.sh +++ b/tests/guix-package-net.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2015, 2017 Ludovic Courtès +# Copyright © 2012, 2013, 2014, 2015, 2017, 2019 Ludovic Courtès # Copyright © 2013 Nikita Karetnikov # # This file is part of GNU Guix. @@ -167,6 +167,37 @@ then false; fi guix package -p "$profile" -p "$profile_alt" --search-paths \ | grep "LIBRARY_PATH.*$profile/lib.$profile_alt/lib" +# Simulate an upgrade and make sure the package order is preserved. +module_dir="t-guix-package-net-$$" +trap 'rm -rf "$module_dir"' EXIT + +mkdir "$module_dir" +cat > "$module_dir/new.scm" < Date: Fri, 11 Jan 2019 15:17:10 +0100 Subject: guix package: Avoid 'find-newest-available-packages'. * guix/scripts/package.scm (transaction-upgrade-entry): Use 'find-best-packages-by-name' instead of 'find-newest-available-packages'. * tests/packages.scm ("transaction-upgrade-entry, zero upgrades") ("transaction-upgrade-entry, one upgrade") ("transaction-upgrade-entry, superseded package"): Adjust accordingly. --- guix/scripts/package.scm | 51 ++++++++++++++++++++++++------------------------ tests/packages.scm | 14 ++++++------- 2 files changed, 33 insertions(+), 32 deletions(-) (limited to 'tests') diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 5a8fd203ee..ba33790eda 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -220,31 +220,32 @@ of relevance scores." ('dismiss transaction) (($ name version output (? string? path)) - (match (vhash-assoc name (find-newest-available-packages)) - ((_ candidate-version pkg . rest) - (match (package-superseded pkg) - ((? package? new) - (supersede entry new)) - (#f - (case (version-compare candidate-version version) - ((>) - (manifest-transaction-install-entry - (package->manifest-entry* pkg output) - transaction)) - ((<) - transaction) - ((=) - (let ((candidate-path (derivation->output-path - (package-derivation (%store) pkg)))) - ;; XXX: When there are propagated inputs, assume we need to - ;; upgrade the whole entry. - (if (and (string=? path candidate-path) - (null? (package-propagated-inputs pkg))) - transaction - (manifest-transaction-install-entry - (package->manifest-entry* pkg output) - transaction)))))))) - (#f + (match (find-best-packages-by-name name #f) + ((pkg . rest) + (let ((candidate-version (package-version pkg))) + (match (package-superseded pkg) + ((? package? new) + (supersede entry new)) + (#f + (case (version-compare candidate-version version) + ((>) + (manifest-transaction-install-entry + (package->manifest-entry* pkg output) + transaction)) + ((<) + transaction) + ((=) + (let ((candidate-path (derivation->output-path + (package-derivation (%store) pkg)))) + ;; XXX: When there are propagated inputs, assume we need to + ;; upgrade the whole entry. + (if (and (string=? path candidate-path) + (null? (package-propagated-inputs pkg))) + transaction + (manifest-transaction-install-entry + (package->manifest-entry* pkg output) + transaction))))))))) + (() (warning (G_ "package '~a' no longer exists~%") name) transaction))))) diff --git a/tests/packages.scm b/tests/packages.scm index 237feb7aba..eb8ede3207 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -96,8 +96,8 @@ (test-assert "transaction-upgrade-entry, zero upgrades" (let* ((old (dummy-package "foo" (version "1"))) - (tx (mock ((gnu packages) find-newest-available-packages - (const vlist-null)) + (tx (mock ((gnu packages) find-best-packages-by-name + (const '())) ((@@ (guix scripts package) transaction-upgrade-entry) (manifest-entry (inherit (package->manifest-entry old)) @@ -109,8 +109,8 @@ (test-assert "transaction-upgrade-entry, one upgrade" (let* ((old (dummy-package "foo" (version "1"))) (new (dummy-package "foo" (version "2"))) - (tx (mock ((gnu packages) find-newest-available-packages - (const (vhash-cons "foo" (list "2" new) vlist-null))) + (tx (mock ((gnu packages) find-best-packages-by-name + (const (list new))) ((@@ (guix scripts package) transaction-upgrade-entry) (manifest-entry (inherit (package->manifest-entry old)) @@ -126,8 +126,8 @@ (let* ((old (dummy-package "foo" (version "1"))) (new (dummy-package "bar" (version "2"))) (dep (deprecated-package "foo" new)) - (tx (mock ((gnu packages) find-newest-available-packages - (const (vhash-cons "foo" (list "2" dep) vlist-null))) + (tx (mock ((gnu packages) find-best-packages-by-name + (const (list dep))) ((@@ (guix scripts package) transaction-upgrade-entry) (manifest-entry (inherit (package->manifest-entry old)) -- cgit v1.2.3 From 5fbdc9a5aa63fd51c65d30fe3d30608d01fe1bc8 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 11 Jan 2019 17:23:39 +0100 Subject: channels: Compute a package cache and use it. * gnu/packages.scm (cache-is-authoritative?, load-package-cache) (cache-lookup, generate-package-cache): New procedures. (%package-cache-file): New variable. (find-packages-by-name): Rename to... (find-packages-by-name/direct): ... this. (find-packages-by-name): Rewrite to use the package cache when 'cache-is-authoritative?' returns true. * tests/packages.scm ("find-packages-by-name + version, with cache") ("find-packages-by-name with cache"): New tests. * guix/channels.scm (package-cache-file): New procedure. (%channel-profile-hooks): New variable. (channel-instances->derivation): Use it in #:hooks. * guix/scripts/package.scm (build-and-use-profile): Add #:hooks and honor it. * guix/scripts/pull.scm (build-and-install): Pass #:hooks to UPDATE-PROFILE. --- gnu/packages.scm | 127 +++++++++++++++++++++++++++++++++++++++++++++-- guix/channels.scm | 36 +++++++++++++- guix/scripts/package.scm | 8 +-- guix/scripts/pull.scm | 1 + tests/packages.scm | 18 +++++++ 5 files changed, 181 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/gnu/packages.scm b/gnu/packages.scm index 4a85cf4b87..6796db80a4 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -28,11 +28,14 @@ #:use-module (guix memoization) #:use-module ((guix build utils) #:select ((package-name->name+version - . hyphen-separated-name->name+version))) + . hyphen-separated-name->name+version) + mkdir-p)) #:autoload (guix profiles) (packages->manifest) #:use-module (guix describe) #:use-module (ice-9 vlist) #:use-module (ice-9 match) + #:autoload (ice-9 binary-ports) (put-bytevector) + #:autoload (system base compile) (compile) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) @@ -56,7 +59,9 @@ specification->package specification->package+output - specifications->manifest)) + specifications->manifest + + generate-package-cache)) ;;; Commentary: ;;; @@ -135,6 +140,14 @@ for system '~a'") ;; Default search path for package modules. `((,%distro-root-directory . "gnu/packages"))) +(define (cache-is-authoritative?) + "Return true if the pre-computed package cache is authoritative. It is not +authoritative when entries have been added via GUIX_PACKAGE_PATH or '-L' +flags." + (equal? (%package-module-path) + (append %default-package-module-path + (package-path-entries)))) + (define %package-module-path ;; Search path for package modules. Each item must be either a directory ;; name or a pair whose car is a directory and whose cdr is a sub-directory @@ -183,7 +196,35 @@ is guaranteed to never traverse the same package twice." init modules)) -(define find-packages-by-name +(define %package-cache-file + ;; Location of the package cache. + "/lib/guix/package.cache") + +(define load-package-cache + (mlambda (profile) + "Attempt to load the package cache. On success return a vhash keyed by +package names. Return #f on failure." + (match profile + (#f #f) + (profile + (catch 'system-error + (lambda () + (define lst + (load-compiled (string-append profile %package-cache-file))) + (fold (lambda (item vhash) + (match item + (#(name version module symbol outputs + supported? deprecated? + file line column) + (vhash-cons name item vhash)))) + vlist-null + lst)) + (lambda args + (if (= ENOENT (system-error-errno args)) + #f + (apply throw args)))))))) + +(define find-packages-by-name/direct ;bypass the cache (let ((packages (delay (fold-packages (lambda (p r) (vhash-cons (package-name p) p r)) @@ -202,6 +243,37 @@ decreasing version order." matching) matching))))) +(define (cache-lookup cache name) + "Lookup package NAME in CACHE. Return a list sorted in increasing version +order." + (define (package-version? (vector-ref v2 1) (vector-ref v1 1))) + + (sort (vhash-fold* cons '() name cache) + package-versionbool (member (%current-system) + (package-supported-systems package))) + ,(->bool (package-superseded package)) + ,@(let ((loc (package-location package))) + (if loc + `(,(location-file loc) + ,(location-line loc) + ,(location-column loc)) + '(#f #f #f)))) + result))) + (_ + result))) + + (define exp + (fold-module-public-variables* expand-cache '() + (all-modules (%package-module-path) + #:warn + warn-about-load-error))) + + (mkdir-p (dirname cache-file)) + (call-with-output-file cache-file + (lambda (port) + ;; Store the cache as a '.go' file. This makes loading fast and reduces + ;; heap usage since some of the static data is directly mmapped. + (put-bytevector port + (compile `'(,@exp) + #:to 'bytecode + #:opts '(#:to-file? #t))))) + cache-file) + (define %sigint-prompt ;; The prompt to jump to upon SIGINT. diff --git a/guix/channels.scm b/guix/channels.scm index 6b860f3bd8..cd8a0131bd 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -21,6 +21,7 @@ #:use-module (guix git) #:use-module (guix records) #:use-module (guix gexp) + #:use-module (guix modules) #:use-module (guix discovery) #:use-module (guix monads) #:use-module (guix profiles) @@ -31,7 +32,8 @@ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9) #:use-module (srfi srfi-11) - #:autoload (guix self) (whole-package) + #:autoload (guix self) (whole-package make-config.scm) + #:autoload (guix inferior) (gexp->derivation-in-inferior) ;FIXME: circular dep #:use-module (ice-9 match) #:export (channel channel? @@ -52,6 +54,7 @@ checkout->channel-instance latest-channel-derivation channel-instances->manifest + %channel-profile-hooks channel-instances->derivation)) ;;; Commentary: @@ -416,11 +419,40 @@ channel instances." (zip instances derivations)))) (return (manifest entries)))) +(define (package-cache-file manifest) + "Build a package cache file for the instance in MANIFEST. This is meant to +be used as a profile hook." + (mlet %store-monad ((profile (profile-derivation manifest + #:hooks '()))) + + (define build + #~(begin + (use-modules (gnu packages)) + + (if (defined? 'generate-package-cache) + (begin + ;; Delegate package cache generation to the inferior. + (format (current-error-port) + "Generating package cache for '~a'...~%" + #$profile) + (generate-package-cache #$output)) + (mkdir #$output)))) + + (gexp->derivation-in-inferior "guix-package-cache" build + profile + #:properties '((type . profile-hook) + (hook . package-cache))))) + +(define %channel-profile-hooks + ;; The default channel profile hooks. + (cons package-cache-file %default-profile-hooks)) + (define (channel-instances->derivation instances) "Return the derivation of the profile containing INSTANCES, a list of channel instances." (mlet %store-monad ((manifest (channel-instances->manifest instances))) - (profile-derivation manifest))) + (profile-derivation manifest + #:hooks %channel-profile-hooks))) (define latest-channel-instances* (store-lift latest-channel-instances)) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index ba33790eda..e9bed0be1e 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -120,21 +120,21 @@ denote ranges as interpreted by 'matching-generations'." (define* (build-and-use-profile store profile manifest #:key + (hooks %default-profile-hooks) allow-collisions? bootstrap? use-substitutes? dry-run?) "Build a new generation of PROFILE, a file name, using the packages specified in MANIFEST, a manifest object. When ALLOW-COLLISIONS? is true, -do not treat collisions in MANIFEST as an error." +do not treat collisions in MANIFEST as an error. HOOKS is a list of \"profile +hooks\" run when building the profile." (when (equal? profile %current-profile) (ensure-default-profile)) (let* ((prof-drv (run-with-store store (profile-derivation manifest #:allow-collisions? allow-collisions? - #:hooks (if bootstrap? - '() - %default-profile-hooks) + #:hooks (if bootstrap? '() hooks) #:locales? (not bootstrap?)))) (prof (derivation->output-path prof-drv))) (show-what-to-build store (list prof-drv) diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm index 0339b149fa..513434c5f1 100644 --- a/guix/scripts/pull.scm +++ b/guix/scripts/pull.scm @@ -188,6 +188,7 @@ true, display what would be built without actually building it." (mlet %store-monad ((manifest (channel-instances->manifest instances))) (mbegin %store-monad (update-profile profile manifest + #:hooks %channel-profile-hooks #:dry-run? dry-run?) (munless dry-run? (return (display-profile-news profile)))))) diff --git a/tests/packages.scm b/tests/packages.scm index eb8ede3207..2720ba5a15 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -1005,6 +1005,24 @@ (((? (cut eq? hello <>))) #t) (wrong (pk 'find-packages-by-name wrong #f)))) +(test-equal "find-packages-by-name with cache" + (find-packages-by-name "guile") + (call-with-temporary-directory + (lambda (cache) + (generate-package-cache cache) + (mock ((guix describe) current-profile (const cache)) + (mock ((gnu packages) cache-is-authoritative? (const #t)) + (find-packages-by-name "guile")))))) + +(test-equal "find-packages-by-name + version, with cache" + (find-packages-by-name "guile" "2") + (call-with-temporary-directory + (lambda (cache) + (generate-package-cache cache) + (mock ((guix describe) current-profile (const cache)) + (mock ((gnu packages) cache-is-authoritative? (const #t)) + (find-packages-by-name "guile" "2")))))) + (test-assert "--search-paths with pattern" ;; Make sure 'guix package --search-paths' correctly reports environment ;; variables when file patterns are used (in particular, it must follow -- cgit v1.2.3 From ee8099f5b688ce5f57790db4122f0b5b91a26216 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 13 Jan 2019 14:27:10 +0100 Subject: edit: Use 'specification->location' to read information from the cache. That way 'guix edit' doesn't need to load any package module. * gnu/packages.scm (find-package-locations, specification->location): New procedures. * guix/scripts/edit.scm (package->location-specification): Rename to... (location->location-specification): ... this. Expect a location object instead of a package. (guix-edit): Use 'specification->location' instead of 'specification->package'. * tests/packages.scm ("find-package-locations") ("find-package-locations with cache") ("specification->location"): New tests. --- gnu/packages.scm | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ guix/scripts/edit.scm | 29 +++++++++++------------------ tests/packages.scm | 23 +++++++++++++++++++++++ 3 files changed, 85 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/gnu/packages.scm b/gnu/packages.scm index 6796db80a4..cf655e7448 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -55,10 +55,12 @@ fold-packages find-packages-by-name + find-package-locations find-best-packages-by-name specification->package specification->package+output + specification->location specifications->manifest generate-package-cache)) @@ -274,6 +276,31 @@ decreasing version order." versions modules symbols))) (find-packages-by-name/direct name version))) +(define* (find-package-locations name #:optional version) + "Return a list of version/location pairs corresponding to each package +matching NAME and VERSION." + (define cache + (load-package-cache (current-profile))) + + (if (and cache (cache-is-authoritative?)) + (match (cache-lookup cache name) + (#f '()) + ((#(name versions modules symbols outputs + supported? deprecated? + files lines columns) ...) + (fold (lambda (version* file line column result) + (if (and file + (or (not version) + (version-prefix? version version*))) + (alist-cons version* (location file line column) + result) + result)) + '() + versions files lines columns))) + (map (lambda (package) + (cons (package-version package) (package-location package))) + (find-packages-by-name/direct name version)))) + (define (find-best-packages-by-name name version) "If version is #f, return the list of packages named NAME with the highest version numbers; otherwise, return the list of packages named NAME and at @@ -393,6 +420,30 @@ present, return the preferred newest version." (let-values (((name version) (package-name->name+version spec))) (%find-package spec name version))) +(define (specification->location spec) + "Return the location of the highest-numbered package matching SPEC, a +specification such as \"guile@2\" or \"emacs\"." + (let-values (((name version) (package-name->name+version spec))) + (match (find-package-locations name version) + (() + (if version + (leave (G_ "~A: package not found for version ~a~%") name version) + (leave (G_ "~A: unknown package~%") name))) + (lst + (let* ((highest (match lst (((version . _) _ ...) version))) + (locations (take-while (match-lambda + ((version . location) + (string=? version highest))) + lst))) + (match locations + (((version . location) . rest) + (unless (null? rest) + (warning (G_ "ambiguous package specification `~a'~%") spec) + (warning (G_ "choosing ~a@~a from ~a~%") + name version + (location->string location))) + location))))))) + (define* (specification->package+output spec #:optional (output "out")) "Return the package and output specified by SPEC, or #f and #f; SPEC may optionally contain a version number and an output name, as in these examples: diff --git a/guix/scripts/edit.scm b/guix/scripts/edit.scm index 8b2b61d76a..da3d2775e8 100644 --- a/guix/scripts/edit.scm +++ b/guix/scripts/edit.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2016 Ludovic Courtès +;;; Copyright © 2015, 2016, 2019 Ludovic Courtès ;;; Copyright © 2015 Mathieu Lirzin ;;; ;;; This file is part of GNU Guix. @@ -21,7 +21,6 @@ #:use-module (guix ui) #:use-module (guix scripts) #:use-module (guix utils) - #:use-module (guix packages) #:use-module (gnu packages) #:use-module (srfi srfi-1) #:use-module (srfi srfi-37) @@ -63,14 +62,13 @@ Start $VISUAL or $EDITOR to edit the definitions of PACKAGE...\n")) file path)) absolute-file-name)) -(define (package->location-specification package) - "Return the location specification for PACKAGE for a typical editor command +(define (location->location-specification location) + "Return the location specification for LOCATION for a typical editor command line." - (let ((loc (package-location package))) - (list (string-append "+" - (number->string - (location-line loc))) - (search-path* %load-path (location-file loc))))) + (list (string-append "+" + (number->string + (location-line location))) + (search-path* %load-path (location-file location)))) (define (guix-edit . args) @@ -83,18 +81,13 @@ line." '())) (with-error-handling - (let* ((specs (reverse (parse-arguments))) - (packages (map specification->package specs))) - (for-each (lambda (package) - (unless (package-location package) - (leave (G_ "source location of package '~a' is unknown~%") - (package-full-name package)))) - packages) + (let* ((specs (reverse (parse-arguments))) + (locations (map specification->location specs))) (catch 'system-error (lambda () - (let ((file-names (append-map package->location-specification - packages))) + (let ((file-names (append-map location->location-specification + locations))) ;; Use `system' instead of `exec' in order to sanely handle ;; possible command line arguments in %EDITOR. (exit (system (string-join (cons (%editor) file-names)))))) diff --git a/tests/packages.scm b/tests/packages.scm index 2720ba5a15..8aa117a2e7 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -1131,6 +1131,29 @@ (lambda (key . args) key))) +(test-equal "find-package-locations" + (map (lambda (package) + (cons (package-version package) + (package-location package))) + (find-packages-by-name "guile")) + (find-package-locations "guile")) + +(test-equal "find-package-locations with cache" + (map (lambda (package) + (cons (package-version package) + (package-location package))) + (find-packages-by-name "guile")) + (call-with-temporary-directory + (lambda (cache) + (generate-package-cache cache) + (mock ((guix describe) current-profile (const cache)) + (mock ((gnu packages) cache-is-authoritative? (const #t)) + (find-package-locations "guile")))))) + +(test-equal "specification->location" + (package-location (specification->package "guile@2")) + (specification->location "guile@2")) + (test-end "packages") ;;; Local Variables: -- cgit v1.2.3 From 0ea939fb796fdd4f0d46d3534b2ec6135e0f3dc7 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 13 Jan 2019 15:36:49 +0100 Subject: guix package: '--list-available' can use data from the cache. * gnu/packages.scm (fold-available-packages): New procedure. * guix/scripts/package.scm (process-query): Use it instead of 'fold-packages'. * tests/packages.scm ("fold-available-packages with/without cache"): New test. --- gnu/packages.scm | 45 +++++++++++++++++++++++++++++++++++++++++++++ guix/scripts/package.scm | 45 +++++++++++++++++++++++++-------------------- tests/packages.scm | 22 ++++++++++++++++++++++ 3 files changed, 92 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/gnu/packages.scm b/gnu/packages.scm index cf655e7448..a1814205f9 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -53,6 +53,7 @@ %default-package-module-path fold-packages + fold-available-packages find-packages-by-name find-package-locations @@ -182,6 +183,50 @@ flags." directory)) %load-path))) +(define (fold-available-packages proc init) + "Fold PROC over the list of available packages. For each available package, +PROC is called along these lines: + + (PROC NAME VERSION RESULT + #:outputs OUTPUTS + #:location LOCATION + …) + +PROC can use #:allow-other-keys to ignore the bits it's not interested in. +When a package cache is available, this procedure does not actually load any +package module." + (define cache + (load-package-cache (current-profile))) + + (if (and cache (cache-is-authoritative?)) + (vhash-fold (lambda (name vector result) + (match vector + (#(name version module symbol outputs + supported? deprecated? + file line column) + (proc name version result + #:outputs outputs + #:location (and file + (location file line column)) + #:supported? supported? + #:deprecated? deprecated?)))) + init + cache) + (fold-packages (lambda (package result) + (proc (package-name package) + (package-version package) + result + #:outputs (package-outputs package) + #:location (package-location package) + #:supported? + (->bool + (member (%current-system) + (package-supported-systems package))) + #:deprecated? + (->bool + (package-superseded package)))) + init))) + (define* (fold-packages proc init #:optional (modules (all-modules (%package-module-path) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index e9bed0be1e..a633d2ee6d 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -736,29 +736,34 @@ processed, #f otherwise." (('list-available regexp) (let* ((regexp (and regexp (make-regexp* regexp))) - (available (fold-packages - (lambda (p r) - (let ((n (package-name p))) - (if (and (supported-package? p) - (not (package-superseded p))) - (if regexp - (if (regexp-exec regexp n) - (cons p r) - r) - (cons p r)) - r))) + (available (fold-available-packages + (lambda* (name version result + #:key outputs location + supported? superseded? + #:allow-other-keys) + (if (and supported? (not superseded?)) + (if regexp + (if (regexp-exec regexp name) + (cons `(,name ,version + ,outputs ,location) + result) + result) + (cons `(,name ,version + ,outputs ,location) + result)) + result)) '()))) (leave-on-EPIPE - (for-each (lambda (p) - (format #t "~a\t~a\t~a\t~a~%" - (package-name p) - (package-version p) - (string-join (package-outputs p) ",") - (location->string (package-location p)))) + (for-each (match-lambda + ((name version outputs location) + (format #t "~a\t~a\t~a\t~a~%" + name version + (string-join outputs ",") + (location->string location)))) (sort available - (lambda (p1 p2) - (string))) #t) -- cgit v1.2.3 From 9fe3f11398e858f1d06120bd046cab506efc86dc Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 18 Jan 2019 14:23:31 +0100 Subject: serialization: 'restore-file' errors out upon non-convertible file names. Fixes . Reported by Maxim Cournoyer . * guix/serialization.scm (port-conversion-strategy): New variable. (restore-file): Parameterize it. * tests/nar.scm ("restore-file with non-UTF8 locale"): New test. --- guix/serialization.scm | 13 +++++++++++-- tests/nar.scm | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/guix/serialization.scm b/guix/serialization.scm index 87ad7eeec0..7c0fea552d 100644 --- a/guix/serialization.scm +++ b/guix/serialization.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -380,10 +380,19 @@ which case you can use 'identity'." (&nar-error (file f) (port port)))))) (write-string ")" p))) +(define port-conversion-strategy + (fluid->parameter %default-port-conversion-strategy)) + (define (restore-file port file) "Read a file (possibly a directory structure) in Nar format from PORT. Restore it as FILE." - (parameterize ((currently-restored-file file)) + (parameterize ((currently-restored-file file) + + ;; Error out if we can convert file names to the current + ;; locale. (XXX: We'd prefer UTF-8 encoding for file names + ;; regardless of the locale, but that's what Guile gives us + ;; so far.) + (port-conversion-strategy 'error)) (let ((signature (read-string port))) (unless (equal? signature %archive-version-1) (raise diff --git a/tests/nar.scm b/tests/nar.scm index 5ffe68c9e2..bfc71c69a8 100644 --- a/tests/nar.scm +++ b/tests/nar.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -334,6 +334,40 @@ (lambda () (rmdir input))))) +(test-eq "restore-file with non-UTF8 locale" ; + 'encoding-error + (let* ((file (search-path %load-path "guix.scm")) + (output (string-append %test-dir "/output")) + (locale (setlocale LC_ALL "C"))) + (dynamic-wind + (lambda () #t) + (lambda () + (define-values (port get-bytevector) + (open-bytevector-output-port)) + + (write-file-tree "root" port + #:file-type+size + (match-lambda + ("root" (values 'directory 0)) + ("root/λ" (values 'regular 0))) + #:file-port (const (%make-void-port "r")) + #:symlink-target (const #f) + #:directory-entries (const '("λ"))) + (close-port port) + + (mkdir %test-dir) + (catch 'encoding-error + (lambda () + ;; This show throw to 'encoding-error. + (restore-file (open-bytevector-input-port (get-bytevector)) + output) + (scandir output)) + (lambda args + 'encoding-error))) + (lambda () + (false-if-exception (rm-rf %test-dir)) + (setlocale LC_ALL locale))))) + (test-assert "restore-file-set (signed, valid)" (with-store store (let* ((texts (unfold (cut >= <> 10) -- cgit v1.2.3 From 2d17a904aca81ed91c5a33ba15d244bca78ac4b8 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 20 Jan 2019 01:39:36 +0100 Subject: tests: Adjust to python.scm split. This is a followup to 44d10b1f722856ab8e9b942804aa7ef33e2ef739. * tests/profiles.scm ("package->manifest-entry, search paths"): Adjust module name for PYTHON2-MATPLOTLIB. --- tests/profiles.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/profiles.scm b/tests/profiles.scm index 1f9bbd099d..8816839d16 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -330,7 +330,7 @@ (test-assert "package->manifest-entry, search paths" ;; See . - (let ((mpl (@ (gnu packages python) python2-matplotlib))) + (let ((mpl (@ (gnu packages python-xyz) python2-matplotlib))) (lset= eq? (package-transitive-native-search-paths mpl) (manifest-entry-search-paths -- cgit v1.2.3 From 38b77f34640ff8a491913d29abcd16a846f2d0e4 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 20 Jan 2019 01:33:25 +0100 Subject: profiles: Allow a profile to be added as an entry of another profile. * guix/build/profiles.scm (build-etc/profile): When 'OUTPUT/etc/profile' already exists, delete it first. (build-profile): Likewise for 'OUTPUT/manifest'. * tests/profiles.scm ("profile in profile"): New test. --- guix/build/profiles.scm | 23 +++++++++++++++++++---- tests/profiles.scm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/guix/build/profiles.scm b/guix/build/profiles.scm index 0c23cd300e..1dc7976879 100644 --- a/guix/build/profiles.scm +++ b/guix/build/profiles.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017, 2018 Ludovic Courtès +;;; Copyright © 2015, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -67,8 +67,14 @@ user-friendly name of the profile is, for instance ~/.guix-profile rather than (define (build-etc/profile output search-paths) "Build the 'OUTPUT/etc/profile' shell file containing environment variable definitions for all the SEARCH-PATHS." - (mkdir-p (string-append output "/etc")) - (call-with-output-file (string-append output "/etc/profile") + (define file + (string-append output "/etc/profile")) + + (mkdir-p (dirname file)) + (when (file-exists? file) + (delete-file file)) + + (call-with-output-file file (lambda (port) ;; The use of $GUIX_PROFILE described below is not great. Another ;; option would have been to use "$1" and have users run: @@ -144,13 +150,22 @@ instead make DIRECTORY a \"real\" directory containing symlinks." create symlinks. Write MANIFEST, an sexp, to OUTPUT/manifest. Create OUTPUT/etc/profile with Bash definitions for -all the variables listed in SEARCH-PATHS." + (define manifest-file + (string-append output "/manifest")) + ;; Make the symlinks. (union-build output inputs #:symlink symlink #:log-port (%make-void-port "w")) + ;; If one of the INPUTS provides a '/manifest' file, delete it. That can + ;; happen if MANIFEST contains something such as a Guix instance, which is + ;; ultimately built as a profile. + (when (file-exists? manifest-file) + (delete-file manifest-file)) + ;; Store meta-data. - (call-with-output-file (string-append output "/manifest") + (call-with-output-file manifest-file (lambda (p) (pretty-print manifest p))) diff --git a/tests/profiles.scm b/tests/profiles.scm index 8816839d16..9a05030aff 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014 Alex Kost ;;; ;;; This file is part of GNU Guix. @@ -591,6 +591,36 @@ (built-derivations (list drv)) (return (readlink (readlink (string-append profile "/dangling"))))))) +(test-equalm "profile in profile" + '("foo" "0") + + ;; Make sure we can build a profile that has another profile has one of its + ;; entries. The new profile's /manifest and /etc/profile must override the + ;; other's. + (mlet* %store-monad + ((prof0 (profile-derivation + (manifest + (list (package->manifest-entry %bootstrap-guile))) + #:hooks '() + #:locales? #f)) + (prof1 (profile-derivation + (manifest (list (manifest-entry + (name "foo") + (version "0") + (item prof0)))) + #:hooks '() + #:locales? #f))) + (mbegin %store-monad + (built-derivations (list prof1)) + (let ((out (derivation->output-path prof1))) + (return (and (file-exists? + (string-append out "/bin/guile")) + (let ((manifest (profile-manifest out))) + (match (manifest-entries manifest) + ((entry) + (list (manifest-entry-name entry) + (manifest-entry-version entry))))))))))) + (test-end "profiles") ;;; Local Variables: -- cgit v1.2.3 From 3b98522b28ab1ee591b6282ceb74a28596aad684 Mon Sep 17 00:00:00 2001 From: Efraim Flashner Date: Sun, 20 Jan 2019 11:49:10 +0200 Subject: tests: More adjustments to python.scm split. This is a followup to 44d10b1f722856ab8e9b942804aa7ef33e2ef739. * tests/lint.scm: Update imports. --- tests/lint.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/lint.scm b/tests/lint.scm index 912a78d111..dc2b17aeec 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -38,7 +38,7 @@ #:use-module (gnu packages) #:use-module (gnu packages glib) #:use-module (gnu packages pkg-config) - #:use-module (gnu packages python) + #:use-module (gnu packages python-xyz) #:use-module (web uri) #:use-module (web server) #:use-module (web server http) -- cgit v1.2.3 From ed75bdf35ca494496cdbc7a06b414e1f08e70cac Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 17 Jan 2019 16:57:53 +0100 Subject: channels: Don't pull from the same channel more than once. Previous 'channel-instance->manifest' would call 'latest-channel-derivation', which could trigger another round of 'latest-repository-commit' for no good reason. * guix/channels.scm (resolve-dependencies): New procedure. (channel-instance-derivations)[edges]: New variable. [instance->derivation]: New procedure. * tests/channels.scm (make-instance): Use 'checkout->channel-instance' instead of 'channel-instance'. ("channel-instances->manifest"): New test. --- guix/channels.scm | 64 ++++++++++++++++++++++++++++------------- tests/channels.scm | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/guix/channels.scm b/guix/channels.scm index cd8a0131bd..b9ce2aa024 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -35,6 +35,7 @@ #:autoload (guix self) (whole-package make-config.scm) #:autoload (guix inferior) (gexp->derivation-in-inferior) ;FIXME: circular dep #:use-module (ice-9 match) + #:use-module (ice-9 vlist) #:export (channel channel? channel-name @@ -289,6 +290,34 @@ INSTANCE depends on." #:commit (channel-instance-commit instance) #:dependencies dependencies)) +(define (resolve-dependencies instances) + "Return a procedure that, given one of the elements of INSTANCES, returns +list of instances it depends on." + (define channel-instance-name + (compose channel-name channel-instance-channel)) + + (define table ;map a name to an instance + (fold (lambda (instance table) + (vhash-consq (channel-instance-name instance) + instance table)) + vlist-null + instances)) + + (define edges + (fold (lambda (instance edges) + (fold (lambda (channel edges) + (let ((name (channel-name channel))) + (match (vhash-assq name table) + ((_ . target) + (vhash-consq instance target edges))))) + edges + (channel-instance-dependencies instance))) + vlist-null + instances)) + + (lambda (instance) + (vhash-foldq* cons '() instance edges))) + (define (channel-instance-derivations instances) "Return the list of derivations to build INSTANCES, in the same order as INSTANCES." @@ -310,27 +339,22 @@ INSTANCES." (module-ref (resolve-interface '(gnu packages guile)) 'guile-bytestructures))) - (mlet %store-monad ((core (build-channel-instance core-instance))) - (mapm %store-monad - (lambda (instance) - (if (eq? instance core-instance) - (return core) - (match (channel-instance-dependencies instance) - (() + (define edges + (resolve-dependencies instances)) + + (define (instance->derivation instance) + (mcached (if (eq? instance core-instance) + (build-channel-instance instance) + (mlet %store-monad ((core (instance->derivation core-instance)) + (deps (mapm %store-monad instance->derivation + (edges instance)))) (build-channel-instance instance - (cons core dependencies))) - (channels - (mlet %store-monad ((dependencies-derivation - (latest-channel-derivation - ;; %default-channels is used here to - ;; ensure that the core channel is - ;; available for channels declared as - ;; dependencies. - (append channels %default-channels)))) - (build-channel-instance instance - (cons dependencies-derivation - (cons core dependencies)))))))) - instances))) + (cons core + (append deps + dependencies))))) + instance)) + + (mapm %store-monad instance->derivation instances)) (define (whole-package-for-legacy name modules) "Return a full-blown Guix package for MODULES, a derivation that builds Guix diff --git a/tests/channels.scm b/tests/channels.scm index f3fc383ac3..7df1b8c5fe 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -18,9 +18,15 @@ (define-module (test-channels) #:use-module (guix channels) + #:use-module (guix profiles) #:use-module ((guix build syscalls) #:select (mkdtemp!)) #:use-module (guix tests) + #:use-module (guix store) + #:use-module ((guix grafts) #:select (%graft?)) + #:use-module (guix derivations) + #:use-module (guix gexp) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (srfi srfi-64) #:use-module (ice-9 match)) @@ -34,8 +40,9 @@ (and spec (with-output-to-file (string-append instance-dir "/.guix-channel") (lambda _ (format #t "~a" spec)))) - ((@@ (guix channels) channel-instance) - name commit instance-dir)) + (checkout->channel-instance instance-dir + #:commit commit + #:name name)) (define instance--boring (make-instance)) (define instance--no-deps @@ -136,4 +143,77 @@ 'abc1234))) instances)))))) +(test-assert "channel-instances->manifest" + ;; Compute the manifest for a graph of instances and make sure we get a + ;; derivation graph that mirrors the instance graph. This test also ensures + ;; we don't try to access Git repositores at all at this stage. + (let* ((spec (lambda deps + `(channel (version 0) + (dependencies + ,@(map (lambda (dep) + `(channel + (name ,dep) + (url "http://example.org"))) + deps))))) + (guix (make-instance #:name 'guix)) + (instance0 (make-instance #:name 'a)) + (instance1 (make-instance #:name 'b #:spec (spec 'a))) + (instance2 (make-instance #:name 'c #:spec (spec 'b))) + (instance3 (make-instance #:name 'd #:spec (spec 'c 'a)))) + (%graft? #f) ;don't try to build stuff + + ;; Create 'build-self.scm' so that GUIX is recognized as the 'guix' channel. + (let ((source (channel-instance-checkout guix))) + (mkdir (string-append source "/build-aux")) + (call-with-output-file (string-append source + "/build-aux/build-self.scm") + (lambda (port) + (write '(begin + (use-modules (guix) (gnu packages bootstrap)) + + (lambda _ + (package->derivation %bootstrap-guile))) + port)))) + + (with-store store + (let () + (define manifest + (run-with-store store + (channel-instances->manifest (list guix + instance0 instance1 + instance2 instance3)))) + + (define entries + (manifest-entries manifest)) + + (define (depends? drv in out) + ;; Return true if DRV depends on all of IN and none of OUT. + (let ((lst (map derivation-input-path (derivation-inputs drv))) + (in (map derivation-file-name in)) + (out (map derivation-file-name out))) + (and (every (cut member <> lst) in) + (not (any (cut member <> lst) out))))) + + (define (lookup name) + (run-with-store store + (lower-object + (manifest-entry-item + (manifest-lookup manifest + (manifest-pattern (name name))))))) + + (let ((drv-guix (lookup "guix")) + (drv0 (lookup "a")) + (drv1 (lookup "b")) + (drv2 (lookup "c")) + (drv3 (lookup "d"))) + (and (depends? drv-guix '() (list drv0 drv1 drv2 drv3)) + (depends? drv0 + (list) (list drv1 drv2 drv3)) + (depends? drv1 + (list drv0) (list drv2 drv3)) + (depends? drv2 + (list drv1) (list drv0 drv3)) + (depends? drv3 + (list drv2 drv0) (list drv1)))))))) + (test-end "channels") -- cgit v1.2.3 From 1fafc383b1f04fcdaa49941f5bb64ac3008cfad8 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 18 Jan 2019 10:01:37 +0100 Subject: inferior: 'gexp->derivation-in-inferior' honors EXP's load path. Previously the imported modules and extensions of EXP would be missing from the load path of 'guix repl'. * guix/inferior.scm (gexp->derivation-in-inferior)[script]: New variable. [trampoline]: Write (primitive-load #$script) to PIPE. Add #$output. * tests/channels.scm ("channel-instances->manifest")[depends?]: Check for requisites rather than direct references. Adjust callers accordingly. --- guix/inferior.scm | 13 ++++++++++--- tests/channels.scm | 16 ++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/guix/inferior.scm b/guix/inferior.scm index 4dfb242e44..9f19e7d316 100644 --- a/guix/inferior.scm +++ b/guix/inferior.scm @@ -491,6 +491,10 @@ PACKAGE must be live." "Return a derivation that evaluates EXP with GUIX, an instance of Guix as returned for example by 'channel-instances->derivation'. Other arguments are passed as-is to 'gexp->derivation'." + (define script + ;; EXP wrapped with a proper (set! %load-path …) prologue. + (scheme-file "inferior-script.scm" exp)) + (define trampoline ;; This is a crude way to run EXP on GUIX. TODO: use 'raw-derivation' and ;; make 'guix repl' the "builder"; this will require "opening up" the @@ -501,9 +505,12 @@ passed as-is to 'gexp->derivation'." (let ((pipe (open-pipe* OPEN_WRITE #+(file-append guix "/bin/guix") "repl" "-t" "machine"))) - ;; Unquote EXP right here so that its references to #$output - ;; propagate to the surrounding gexp. - (write '#$exp pipe) ;XXX: load path for EXP? + + ;; XXX: EXP presumably refers to #$output but that reference is lost + ;; so explicitly reference it here. + #$output + + (write `(primitive-load #$script) pipe) (unless (zero? (close-pipe pipe)) (error "inferior failed" #+guix))))) diff --git a/tests/channels.scm b/tests/channels.scm index 7df1b8c5fe..8540aef435 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -24,6 +24,7 @@ #:use-module (guix store) #:use-module ((guix grafts) #:select (%graft?)) #:use-module (guix derivations) + #:use-module (guix sets) #:use-module (guix gexp) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) @@ -187,12 +188,15 @@ (manifest-entries manifest)) (define (depends? drv in out) - ;; Return true if DRV depends on all of IN and none of OUT. - (let ((lst (map derivation-input-path (derivation-inputs drv))) + ;; Return true if DRV depends (directly or indirectly) on all of IN + ;; and none of OUT. + (let ((set (list->set + (requisites store + (list (derivation-file-name drv))))) (in (map derivation-file-name in)) (out (map derivation-file-name out))) - (and (every (cut member <> lst) in) - (not (any (cut member <> lst) out))))) + (and (every (cut set-contains? set <>) in) + (not (any (cut set-contains? set <>) out))))) (define (lookup name) (run-with-store store @@ -212,8 +216,8 @@ (depends? drv1 (list drv0) (list drv2 drv3)) (depends? drv2 - (list drv1) (list drv0 drv3)) + (list drv1) (list drv3)) (depends? drv3 - (list drv2 drv0) (list drv1)))))))) + (list drv2 drv0) (list)))))))) (test-end "channels") -- cgit v1.2.3 From f9e8a12379c6fefc9e5c3c7fc3926599bbefc013 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 21 Jan 2019 17:41:11 +0100 Subject: store: Rename '&nix-error' to '&store-error'. * guix/store.scm (&nix-error): Rename to... (&store-error): ... this, and adjust users. (&nix-connection-error): Rename to... (&store-connection-error): ... this, and adjust users. (&nix-protocol-error): Rename to... (&store-protocol-error): ... this, adjust users. (&nix-error, &nix-connection-error, &nix-protocol-error): Define these condition types and their getters as deprecrated aliases. * build-aux/run-system-tests.scm, guix/derivations.scm, guix/grafts.scm, guix/scripts/challenge.scm, guix/scripts/graph.scm, guix/scripts/lint.scm, guix/scripts/offload.scm, guix/serialization.scm, guix/ssh.scm, guix/tests.scm, guix/ui.scm, tests/derivations.scm, tests/gexp.scm, tests/guix-daemon.sh, tests/packages.scm, tests/store.scm, doc/guix.texi: Adjust to use the new names. --- build-aux/run-system-tests.scm | 2 +- doc/guix.texi | 2 +- guix/derivations.scm | 2 +- guix/grafts.scm | 2 +- guix/scripts/challenge.scm | 2 +- guix/scripts/graph.scm | 2 +- guix/scripts/lint.scm | 4 +-- guix/scripts/offload.scm | 6 ++-- guix/serialization.scm | 2 +- guix/ssh.scm | 6 ++-- guix/store.scm | 77 ++++++++++++++++++++++++++++-------------- guix/tests.scm | 2 +- guix/ui.scm | 10 +++--- tests/derivations.scm | 42 +++++++++++------------ tests/gexp.scm | 4 +-- tests/guix-daemon.sh | 8 ++--- tests/packages.scm | 2 +- tests/store.scm | 46 ++++++++++++------------- 18 files changed, 123 insertions(+), 98 deletions(-) (limited to 'tests') diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scm index bcd7547704..fd1f6653af 100644 --- a/build-aux/run-system-tests.scm +++ b/build-aux/run-system-tests.scm @@ -30,7 +30,7 @@ (define (built-derivations* drv) (lambda (store) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (values #f store))) (values (build-derivations store drv) store)))) diff --git a/doc/guix.texi b/doc/guix.texi index 245a18bc70..e70fed2f1c 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -5027,7 +5027,7 @@ Return @code{#t} when @var{path} designates a valid store item and invalid, for instance because it is the result of an aborted or failed build.) -A @code{&nix-protocol-error} condition is raised if @var{path} is not +A @code{&store-protocol-error} condition is raised if @var{path} is not prefixed by the store directory (@file{/gnu/store}). @end deffn diff --git a/guix/derivations.scm b/guix/derivations.scm index f6176a78fd..fb2fa177be 100644 --- a/guix/derivations.scm +++ b/guix/derivations.scm @@ -113,7 +113,7 @@ ;;; Error conditions. ;;; -(define-condition-type &derivation-error &nix-error +(define-condition-type &derivation-error &store-error derivation-error? (derivation derivation-error-derivation)) diff --git a/guix/grafts.scm b/guix/grafts.scm index db9c6854fd..a3e12f6efd 100644 --- a/guix/grafts.scm +++ b/guix/grafts.scm @@ -189,7 +189,7 @@ available." items))) (define (references* items) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; As a last resort, build DRV and query the references of the ;; build result. diff --git a/guix/scripts/challenge.scm b/guix/scripts/challenge.scm index f0693ed8df..65de42053d 100644 --- a/guix/scripts/challenge.scm +++ b/guix/scripts/challenge.scm @@ -109,7 +109,7 @@ "Return the hash of ITEM, a store item, if ITEM was built locally. Otherwise return #f." (lambda (store) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (values #f store))) (if (locally-built? store item) (values (query-path-hash store item) store) diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm index 145a574dba..8efeef3274 100644 --- a/guix/scripts/graph.scm +++ b/guix/scripts/graph.scm @@ -299,7 +299,7 @@ this type of graph"))))))) information available in the local store or using information about substitutes." (lambda (store) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (match (substitutable-path-info store (list item)) ((info) (values (substitutable-references info) store)) diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm index 665adcfb8d..ddad5b7fd0 100644 --- a/guix/scripts/lint.scm +++ b/guix/scripts/lint.scm @@ -833,11 +833,11 @@ descriptions maintained upstream." (define (try system) (catch #t (lambda () - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (emit-warning package (format #f (G_ "failed to create ~a derivation: ~a") system - (nix-protocol-error-message c)))) + (store-protocol-error-message c)))) ((message-condition? c) (emit-warning package (format #f (G_ "failed to create ~a derivation: ~a") diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm index 30fe69ad6d..2116b38425 100644 --- a/guix/scripts/offload.scm +++ b/guix/scripts/offload.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2017 Ricardo Wurmus ;;; ;;; This file is part of GNU Guix. @@ -358,12 +358,12 @@ MACHINE." (format (current-error-port) "@ build-remote ~a ~a~%" (derivation-file-name drv) (build-machine-name machine)) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (format (current-error-port) (G_ "derivation '~a' offloaded to '~a' failed: ~a~%") (derivation-file-name drv) (build-machine-name machine) - (nix-protocol-error-message c)) + (store-protocol-error-message c)) (let* ((inferior (false-if-exception (remote-inferior session))) (space (false-if-exception (node-free-disk-space inferior)))) diff --git a/guix/serialization.scm b/guix/serialization.scm index 7c0fea552d..e14b7d1b9f 100644 --- a/guix/serialization.scm +++ b/guix/serialization.scm @@ -59,7 +59,7 @@ ;; Similar to serialize.cc in Nix. -(define-condition-type &nar-error &error ; XXX: inherit from &nix-error ? +(define-condition-type &nar-error &error ; XXX: inherit from &store-error ? nar-error? (file nar-error-file) ; file we were restoring, or #f (port nar-error-port)) ; port from which we read diff --git a/guix/ssh.scm b/guix/ssh.scm index 77329618d5..2b286a67b2 100644 --- a/guix/ssh.scm +++ b/guix/ssh.scm @@ -328,17 +328,17 @@ Return the list of store items actually sent." missing) (('protocol-error message) (raise (condition - (&nix-protocol-error (message message) (status 42))))) + (&store-protocol-error (message message) (status 42))))) (('error key args ...) (raise (condition - (&nix-protocol-error + (&store-protocol-error (message (call-with-output-string (lambda (port) (print-exception port #f key args)))) (status 43))))) (_ (raise (condition - (&nix-protocol-error + (&store-protocol-error (message "unknown error while sending files over SSH") (status 44))))))))) diff --git a/guix/store.scm b/guix/store.scm index f8c79788b8..d079147529 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -68,6 +68,15 @@ current-store-protocol-version ;for internal use mcached + &store-error store-error? + &store-connection-error store-connection-error? + store-connection-error-file + store-connection-error-code + &store-protocol-error store-protocol-error? + store-protocol-error-message + store-protocol-error-status + + ;; Deprecated forms for '&store-error' et al. &nix-error nix-error? &nix-connection-error nix-connection-error? nix-connection-error-file @@ -377,34 +386,50 @@ (define-deprecated/alias nix-server-socket store-connection-socket) -(define-condition-type &nix-error &error - nix-error?) +(define-condition-type &store-error &error + store-error?) -(define-condition-type &nix-connection-error &nix-error - nix-connection-error? - (file nix-connection-error-file) - (errno nix-connection-error-code)) +(define-condition-type &store-connection-error &store-error + store-connection-error? + (file store-connection-error-file) + (errno store-connection-error-code)) + +(define-condition-type &store-protocol-error &store-error + store-protocol-error? + (message store-protocol-error-message) + (status store-protocol-error-status)) + +(define-deprecated/alias &nix-error &store-error) +(define-deprecated/alias nix-error? store-error?) +(define-deprecated/alias &nix-connection-error &store-connection-error) +(define-deprecated/alias nix-connection-error? store-connection-error?) +(define-deprecated/alias nix-connection-error-file + store-connection-error-file) +(define-deprecated/alias nix-connection-error-code + store-connection-error-code) +(define-deprecated/alias &nix-protocol-error &store-protocol-error) +(define-deprecated/alias nix-protocol-error? store-protocol-error?) +(define-deprecated/alias nix-protocol-error-message + store-protocol-error-message) +(define-deprecated/alias nix-protocol-error-status + store-protocol-error-status) -(define-condition-type &nix-protocol-error &nix-error - nix-protocol-error? - (message nix-protocol-error-message) - (status nix-protocol-error-status)) (define-syntax-rule (system-error-to-connection-error file exp ...) "Catch 'system-error' exceptions and translate them to -'&nix-connection-error'." +'&store-connection-error'." (catch 'system-error (lambda () exp ...) (lambda args (let ((errno (system-error-errno args))) - (raise (condition (&nix-connection-error + (raise (condition (&store-connection-error (file file) (errno errno)))))))) (define (open-unix-domain-socket file) "Connect to the Unix-domain socket at FILE and return it. Raise a -'&nix-connection-error' upon error." +'&store-connection-error' upon error." (let ((s (with-fluids ((%default-port-encoding #f)) ;; This trick allows use of the `scm_c_read' optimization. (socket PF_UNIX SOCK_STREAM 0))) @@ -420,7 +445,7 @@ (define (open-inet-socket host port) "Connect to the Unix-domain socket at HOST:PORT and return it. Raise a -'&nix-connection-error' upon error." +'&store-connection-error' upon error." (let ((sock (with-fluids ((%default-port-encoding #f)) ;; This trick allows use of the `scm_c_read' optimization. (socket PF_UNIX SOCK_STREAM 0)))) @@ -452,7 +477,7 @@ ;; Connection failed, so try one of the other addresses. (close s) (if (null? rest) - (raise (condition (&nix-connection-error + (raise (condition (&store-connection-error (file host) (errno (system-error-errno args))))) (loop rest)))))))))) @@ -461,7 +486,7 @@ "Connect to the daemon at URI, a string that may be an actual URI or a file name." (define (not-supported) - (raise (condition (&nix-connection-error + (raise (condition (&store-connection-error (file uri) (errno ENOTSUP))))) @@ -510,8 +535,8 @@ for this connection will be pinned. Return a server object." ;; One of the 'write-' or 'read-' calls below failed, but this is ;; really a connection error. (raise (condition - (&nix-connection-error (file (or port uri)) - (errno EPROTO)) + (&store-connection-error (file (or port uri)) + (errno EPROTO)) (&message (message "build daemon handshake failed")))))) (let*-values (((port) (or port (connect-to-daemon uri))) @@ -689,14 +714,14 @@ encoding conversion errors." (not (eof-object? (lookahead-u8 p)))) (read-int p) 1))) - (raise (condition (&nix-protocol-error + (raise (condition (&store-protocol-error (message error) (status status)))))) ((= k %stderr-last) ;; The daemon is done (see `stopWork' in `nix-worker.cc'.) #t) (else - (raise (condition (&nix-protocol-error + (raise (condition (&store-protocol-error (message "invalid error code") (status k)))))))) @@ -926,7 +951,7 @@ bytevector) as its internal buffer, and a thunk to flush this output port." invalid item may exist on disk but still be invalid, for instance because it is the result of an aborted or failed build.) -A '&nix-protocol-error' condition is raised if PATH is not prefixed by the +A '&store-protocol-error' condition is raised if PATH is not prefixed by the store directory (/gnu/store)." boolean) @@ -1141,7 +1166,7 @@ Return #t on success." (build store things mode) (if (= mode (build-mode normal)) (build/old store things) - (raise (condition (&nix-protocol-error + (raise (condition (&store-protocol-error (message "unsupported build mode") (status 1)))))))))) @@ -1201,12 +1226,12 @@ error if there is no such root." (define (references/substitutes store items) "Return the list of list of references of ITEMS; the result has the same length as ITEMS. Query substitute information for any item missing from the -store at once. Raise a '&nix-protocol-error' exception if reference +store at once. Raise a '&store-protocol-error' exception if reference information for one of ITEMS is missing." (let* ((requested items) (local-refs (map (lambda (item) (or (hash-ref %reference-cache item) - (guard (c ((nix-protocol-error? c) #f)) + (guard (c ((store-protocol-error? c) #f)) (references store item)))) items)) (missing (fold-right (lambda (item local-ref result) @@ -1222,7 +1247,7 @@ information for one of ITEMS is missing." '() (substitutable-path-info store missing)))) (when (< (length substs) (length missing)) - (raise (condition (&nix-protocol-error + (raise (condition (&store-protocol-error (message "cannot determine \ the list of references") (status 1))))) @@ -1673,7 +1698,7 @@ where FILE is the entry's absolute file name and STAT is the result of "Monadic version of 'query-path-info' that returns #f when ITEM is not in the store." (lambda (store) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; ITEM is not in the store; return #f. (values #f store))) (values (query-path-info store item) store)))) diff --git a/guix/tests.scm b/guix/tests.scm index f4948148c4..16a426c4f9 100644 --- a/guix/tests.scm +++ b/guix/tests.scm @@ -64,7 +64,7 @@ (define* (open-connection-for-tests #:optional (uri (%daemon-socket-uri))) "Open a connection to the build daemon for tests purposes and return it." - (guard (c ((nix-error? c) + (guard (c ((store-error? c) (format (current-error-port) "warning: build daemon error: ~s~%" c) #f)) diff --git a/guix/ui.scm b/guix/ui.scm index 1e089753e1..9ff56ea85c 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -684,14 +684,14 @@ or remove one of them from the profile.") file (or (port-filename* port) port)) (leave (G_ "corrupt input while restoring archive from ~s~%") (or (port-filename* port) port))))) - ((nix-connection-error? c) + ((store-connection-error? c) (leave (G_ "failed to connect to `~a': ~a~%") - (nix-connection-error-file c) - (strerror (nix-connection-error-code c)))) - ((nix-protocol-error? c) + (store-connection-error-file c) + (strerror (store-connection-error-code c)))) + ((store-protocol-error? c) ;; FIXME: Server-provided error messages aren't i18n'd. (leave (G_ "build failed: ~a~%") - (nix-protocol-error-message c))) + (store-protocol-error-message c))) ((derivation-missing-output-error? c) (leave (G_ "reference to invalid output '~a' of derivation '~a'~%") (derivation-missing-output c) diff --git a/tests/derivations.scm b/tests/derivations.scm index 5f294c1827..c0601c0e88 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -185,9 +185,9 @@ (set-build-options %store #:use-substitutes? #f #:keep-going? #t) - (guard (c ((nix-protocol-error? c) - (and (= 100 (nix-protocol-error-status c)) - (string-contains (nix-protocol-error-message c) + (guard (c ((store-protocol-error? c) + (and (= 100 (store-protocol-error-status c)) + (string-contains (store-protocol-error-message c) (derivation-file-name d1)) (not (valid-path? %store (derivation->output-path d1))) (valid-path? %store (derivation->output-path d2))))) @@ -222,8 +222,8 @@ (test-assert "unknown built-in builder" (let ((drv (derivation %store "ohoh" "builtin:does-not-exist" '()))) - (guard (c ((nix-protocol-error? c) - (string-contains (nix-protocol-error-message c) "failed"))) + (guard (c ((store-protocol-error? c) + (string-contains (store-protocol-error-message c) "failed"))) (build-derivations %store (list drv)) #f))) @@ -253,8 +253,8 @@ . ,(object->string (%local-url)))) #:hash-algo 'sha256 #:hash (sha256 (random-bytevector 100))))) ;wrong - (guard (c ((nix-protocol-error? c) - (string-contains (nix-protocol-error-message c) "failed"))) + (guard (c ((store-protocol-error? c) + (string-contains (store-protocol-error-message c) "failed"))) (build-derivations %store (list drv)) #f)))) @@ -268,8 +268,8 @@ . ,(object->string (%local-url)))) #:hash-algo 'sha256 #:hash (sha256 (random-bytevector 100))))) - (guard (c ((nix-protocol-error? c) - (string-contains (nix-protocol-error-message (pk c)) "failed"))) + (guard (c ((store-protocol-error? c) + (string-contains (store-protocol-error-message (pk c)) "failed"))) (build-derivations %store (list drv)) #f)))) @@ -279,8 +279,8 @@ (drv (derivation %store "world" "builtin:download" '() #:env-vars `(("url" . ,(object->string url)))))) - (guard (c ((nix-protocol-error? c) - (string-contains (nix-protocol-error-message c) "failed"))) + (guard (c ((store-protocol-error? c) + (string-contains (store-protocol-error-message c) "failed"))) (build-derivations %store (list drv)) #f))) @@ -607,7 +607,7 @@ `("-c" ,(string-append "echo " txt "> $out")) #:inputs `((,%bash) (,txt)) #:allowed-references '()))) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; There's no specific error message to check for. #t)) (build-derivations %store (list drv)) @@ -625,7 +625,7 @@ `("-c" ,"echo $out > $out") #:inputs `((,%bash)) #:allowed-references '()))) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; There's no specific error message to check for. #t)) (build-derivations %store (list drv)) @@ -644,7 +644,7 @@ `("-c" ,(string-append "echo " txt "> $out")) #:inputs `((,%bash) (,txt)) #:disallowed-references (list txt)))) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; There's no specific error message to check for. #t)) (build-derivations %store (list drv)) @@ -765,8 +765,8 @@ (builder '(begin (sleep 100) (mkdir %output) #t)) (drv (build-expression->derivation store "silent" builder)) (out-path (derivation->output-path drv))) - (guard (c ((nix-protocol-error? c) - (and (string-contains (nix-protocol-error-message c) + (guard (c ((store-protocol-error? c) + (and (string-contains (store-protocol-error-message c) "failed") (not (valid-path? store out-path))))) (build-derivations store (list drv)) @@ -779,8 +779,8 @@ (builder '(begin (sleep 100) (mkdir %output) #t)) (drv (build-expression->derivation store "slow" builder)) (out-path (derivation->output-path drv))) - (guard (c ((nix-protocol-error? c) - (and (string-contains (nix-protocol-error-message c) + (guard (c ((store-protocol-error? c) + (and (string-contains (store-protocol-error-message c) "failed") (not (valid-path? store out-path))))) (build-derivations store (list drv)) @@ -942,11 +942,11 @@ #f)) ; fail! (drv (build-expression->derivation %store "fail" builder)) (out-path (derivation->output-path drv))) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; Note that the output path may exist at this point, but it ;; is invalid. (and (string-match "build .* failed" - (nix-protocol-error-message c)) + (store-protocol-error-message c)) (not (valid-path? %store out-path))))) (build-derivations %store (list drv)) #f))) diff --git a/tests/gexp.scm b/tests/gexp.scm index c4b437cd49..cee2c96610 100644 --- a/tests/gexp.scm +++ b/tests/gexp.scm @@ -919,7 +919,7 @@ (chdir #$output) (symlink #$%bootstrap-guile "guile")) #:allowed-references '())))) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list drv)) #f))) @@ -943,7 +943,7 @@ (chdir #$output) (symlink #$%bootstrap-guile "guile")) #:disallowed-references (list %bootstrap-guile))))) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list drv)) #f))) diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh index 9ae6e0b77a..4c19a55722 100644 --- a/tests/guix-daemon.sh +++ b/tests/guix-daemon.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +# Copyright © 2012, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès # # This file is part of GNU Guix. # @@ -109,7 +109,7 @@ guile -c " (define (build-without-failing drv) (lambda (store) - (guard (c ((nix-protocol-error? c) (values #t store))) + (guard (c ((store-protocol-error? c) (values #t store))) (build-derivations store (list drv)) (values #f store)))) @@ -177,9 +177,9 @@ client_code=' `("-e" ,build) #:inputs `((,bash) (,build)) #:env-vars `(("x" . ,(random-text)))))) - (exit (guard (c ((nix-protocol-error? c) + (exit (guard (c ((store-protocol-error? c) (->bool - (string-contains (pk (nix-protocol-error-message c)) + (string-contains (pk (store-protocol-error-message c)) "failed")))) (build-derivations store (list drv)) #f))))' diff --git a/tests/packages.scm b/tests/packages.scm index ed635d9011..29e5e4103c 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -570,7 +570,7 @@ (symlink %output (string-append %output "/self")) #t))))) (d (package-derivation %store p))) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list d)) #f))) diff --git a/tests/store.scm b/tests/store.scm index 5ff9308d7d..e28c0c5aaa 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -63,9 +63,9 @@ (test-equal "connection handshake error" EPROTO (let ((port (%make-void-port "rw"))) - (guard (c ((nix-connection-error? c) - (and (eq? port (nix-connection-error-file c)) - (nix-connection-error-code c)))) + (guard (c ((store-connection-error? c) + (and (eq? port (store-connection-error-file c)) + (store-connection-error-code c)))) (open-connection #f #:port port) 'broken))) @@ -120,7 +120,7 @@ (test-assert "valid-path? error" (with-store s - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (valid-path? s "foo") #f))) @@ -133,7 +133,7 @@ (with-store s (let-syntax ((true-if-error (syntax-rules () ((_ exp) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) exp #f))))) (and (true-if-error (valid-path? s "foo")) (true-if-error (valid-path? s "bar")) @@ -274,7 +274,7 @@ (test-assert "references/substitutes missing reference info" (with-store s (set-build-options s #:use-substitutes? #f) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (let* ((b (add-to-store s "bash" #t "sha256" (search-bootstrap-binary "bash" (%current-system)))) @@ -422,7 +422,7 @@ %store "foo" `(display ,s) #:guile-for-build (package-derivation s %bootstrap-guile (%current-system))))) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list d)))))))) "Here’s a Greek letter: λ.")) @@ -442,7 +442,7 @@ (display "lambda: λ\n")) #:guile-for-build (package-derivation %store %bootstrap-guile)))) - (guard (c ((nix-protocol-error? c) #t)) + (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list d)))))))) "garbage: �lambda: λ")) @@ -620,12 +620,12 @@ #:fallback? #f #:substitute-urls (%test-substitute-urls)) (and (has-substitutes? s o) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; XXX: the daemon writes "hash mismatch in downloaded ;; path", but the actual error returned to the client ;; doesn't mention that. (pk 'corrupt c) - (not (zero? (nix-protocol-error-status c))))) + (not (zero? (store-protocol-error-status c))))) (build-derivations s (list d)) #f)))))) @@ -646,7 +646,7 @@ (set-build-options s #:use-substitutes? #t #:substitute-urls (%test-substitute-urls)) (and (has-substitutes? s o) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) ;; The substituter failed as expected. Now make ;; sure that #:fallback? #t works correctly. (set-build-options s @@ -712,9 +712,9 @@ (dump (call-with-bytevector-output-port (cute export-paths %store (list file2) <>)))) (delete-paths %store (list file0 file1 file2)) - (guard (c ((nix-protocol-error? c) - (and (not (zero? (nix-protocol-error-status c))) - (string-contains (nix-protocol-error-message c) + (guard (c ((store-protocol-error? c) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) "not valid")))) ;; Here we get an exception because DUMP does not include FILE0 and ;; FILE1, which are dependencies of FILE2. @@ -816,10 +816,10 @@ (bytevector-u8-set! dump index (logxor #xff byte))) (and (not (file-exists? file)) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (pk 'c c) - (and (not (zero? (nix-protocol-error-status c))) - (string-contains (nix-protocol-error-message c) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) "corrupt")))) (let* ((source (open-bytevector-input-port dump)) (imported (import-paths %store source))) @@ -906,10 +906,10 @@ (begin (write (random-text) entropy-port) (force-output entropy-port) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (pk 'determinism-exception c) - (and (not (zero? (nix-protocol-error-status c))) - (string-contains (nix-protocol-error-message c) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) "deterministic")))) ;; This one will produce a different result. Since we're in ;; 'check' mode, this must fail. @@ -945,10 +945,10 @@ #:guile-for-build (package-derivation store %bootstrap-guile (%current-system)))) (file (derivation->output-path drv))) - (guard (c ((nix-protocol-error? c) + (guard (c ((store-protocol-error? c) (pk 'multiple-build c) - (and (not (zero? (nix-protocol-error-status c))) - (string-contains (nix-protocol-error-message c) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) "deterministic")))) ;; This one will produce a different result on the second run. (current-build-output-port (current-error-port)) -- cgit v1.2.3 From f61e6e5238ff43b959c258ed92531029a1c82fa7 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 21 Jan 2019 22:17:17 +0100 Subject: tests: Adjust for removal of 'device' field in . This is a followup to commit 5f7467f046c3c1648cdf6eb81b3ec041bfc1f9bb. * tests/guix-system.sh: For records, use 'target' rather than 'device'. --- tests/guix-system.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/guix-system.sh b/tests/guix-system.sh index adb623d244..9903677a02 100644 --- a/tests/guix-system.sh +++ b/tests/guix-system.sh @@ -109,7 +109,7 @@ cat > "$tmpfile" < +;;; Copyright © 2018 Mark H Weaver ;;; ;;; This file is part of GNU Guix. ;;; @@ -52,6 +53,22 @@ ((weird _ ...) ;weird! (syntax-violation name "invalid field specifier" #'weird))))) +(define (report-duplicate-field-specifier name ctor) + "Report the first duplicate identifier among the bindings in CTOR." + (syntax-case ctor () + ((_ bindings ...) + (let loop ((bindings #'(bindings ...)) + (seen '())) + (syntax-case bindings () + (((field value) rest ...) + (not (memq (syntax->datum #'field) seen)) + (loop #'(rest ...) (cons (syntax->datum #'field) seen))) + ((duplicate rest ...) + (syntax-violation name "duplicate field initializer" + #'duplicate)) + (() + #t)))))) + (eval-when (expand load eval) ;; The procedures below are needed both at run time and at expansion time. @@ -169,6 +186,9 @@ of TYPE matches the expansion-time ABI." #'(field (... ...))) (wrap-field-value f (field-default-value f)))) + ;; Pass S to make sure source location info is preserved. + (report-duplicate-field-specifier 'name s) + (let ((fields (append fields (map car default-values)))) (cond ((lset= eq? fields '(expected ...)) #`(let* #,(field-bindings diff --git a/tests/records.scm b/tests/records.scm index 09ada70c2d..d9469a78bd 100644 --- a/tests/records.scm +++ b/tests/records.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -288,6 +288,30 @@ (and (string-match "extra.*initializer.*baz" message) (eq? proc 'foo))))) +(test-assert "define-record-type* & duplicate initializers" + (let ((exp '(begin + (define-record-type* foo make-foo + foo? + (bar foo-bar (default 42))) + + (foo (bar 1) + (bar 2)))) + (loc (current-source-location))) ;keep this alignment! + (catch 'syntax-error + (lambda () + (eval exp (test-module)) + #f) + (lambda (key proc message location form . args) + (and (string-match "duplicate.*initializer" message) + (eq? proc 'foo) + + ;; Make sure the location is that of the field specifier. + (lset= equal? + (pk 'expected-loc + `((line . ,(- (assq-ref loc 'line) 1)) + ,@(alist-delete 'line loc))) + (pk 'actual-loc location))))))) + (test-assert "ABI checks" (let ((module (test-module))) (eval '(begin -- cgit v1.2.3 From 2c5ee9bba4067fb0a9e68fb2af3a6e7fe36960cb Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 24 Jan 2019 19:18:10 +0100 Subject: tests: Remove duplicate field initializers. Fixes a regression introduced in c2dcff41c2e47f5f978f467864d5ed7829939884, whereby many tests in 'tests/packages.scm' would trigger a syntax error due to duplicate field intializers in forms like: (dummy-package "foo" (version "0")) * guix/tests.scm (dummy-package, dummy-origin): Rewrite to inherit from a base record. This restores the semantics from before c2dcff41c2e47f5f978f467864d5ed7829939884. * tests/services.scm ("instantiate-missing-services, indirect"): Remove duplicate 'extensions' field. --- guix/tests.scm | 19 ++++++++++--------- tests/services.scm | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/guix/tests.scm b/guix/tests.scm index 16a426c4f9..749a4edd7a 100644 --- a/guix/tests.scm +++ b/guix/tests.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -334,18 +334,19 @@ CONTENTS." (define-syntax-rule (dummy-package name* extra-fields ...) "Return a \"dummy\" package called NAME*, with all its compulsory fields initialized with default values, and with EXTRA-FIELDS set as specified." - (package extra-fields ... - (name name*) (version "0") (source #f) - (build-system gnu-build-system) - (synopsis #f) (description #f) - (home-page #f) (license #f))) + (let ((p (package + (name name*) (version "0") (source #f) + (build-system gnu-build-system) + (synopsis #f) (description #f) + (home-page #f) (license #f)))) + (package (inherit p) extra-fields ...))) (define-syntax-rule (dummy-origin extra-fields ...) "Return a \"dummy\" origin, with all its compulsory fields initialized with default values, and with EXTRA-FIELDS set as specified." - (origin extra-fields ... - (method #f) (uri "http://www.example.com") - (sha256 (base32 (make-string 52 #\x))))) + (let ((o (origin (method #f) (uri "http://www.example.com") + (sha256 (base32 (make-string 52 #\x)))))) + (origin (inherit o) extra-fields ...))) ;; Local Variables: ;; eval: (put 'call-with-derivation-narinfo 'scheme-indent-function 1) diff --git a/tests/services.scm b/tests/services.scm index 5827dee80d..44ad0022c6 100644 --- a/tests/services.scm +++ b/tests/services.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -143,7 +143,7 @@ (default-value 'dflt) (compose concatenate) (extend cons))) - (t2 (service-type (name 't2) (extensions '()) + (t2 (service-type (name 't2) (default-value 'dflt2) (compose concatenate) (extend cons) -- cgit v1.2.3 From 3e223a22a70138b8c57e742ad8ec737131249820 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 25 Jan 2019 10:05:31 +0100 Subject: packages: Add 'package-closure'. * guix/packages.scm (package-closure): New procedure. * tests/packages.scm ("package-closure"): New test. --- guix/packages.scm | 25 ++++++++++++++++++++++++- tests/packages.scm | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/guix/packages.scm b/guix/packages.scm index e4c2ac3be5..f191327718 100644 --- a/guix/packages.scm +++ b/guix/packages.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014, 2015, 2017, 2018 Mark H Weaver ;;; Copyright © 2015 Eric Bavier ;;; Copyright © 2016 Alex Kost @@ -133,6 +133,7 @@ bag-transitive-host-inputs bag-transitive-build-inputs bag-transitive-target-inputs + package-closure default-guile default-guile-derivation @@ -798,6 +799,28 @@ dependencies are known to build on SYSTEM." "Return the \"target inputs\" of BAG, recursively." (transitive-inputs (bag-target-inputs bag))) +(define* (package-closure packages #:key (system (%current-system))) + "Return the closure of PACKAGES on SYSTEM--i.e., PACKAGES and the list of +packages they depend on, recursively." + (let loop ((packages packages) + (visited vlist-null) + (closure (list->setq packages))) + (match packages + (() + (set->list closure)) + ((package . rest) + (if (vhash-assq package visited) + (loop rest visited closure) + (let* ((bag (package->bag package system)) + (dependencies (filter-map (match-lambda + ((label (? package? package) . _) + package) + (_ #f)) + (bag-direct-inputs bag)))) + (loop (append dependencies rest) + (vhash-consq package #t visited) + (fold set-insert closure dependencies)))))))) + (define* (package-mapping proc #:optional (cut? (const #f))) "Return a procedure that, given a package, applies PROC to all the packages depended on and returns the resulting package. The procedure stops recursion diff --git a/tests/packages.scm b/tests/packages.scm index 29e5e4103c..e5704ae4b9 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -249,6 +249,28 @@ (package-transitive-supported-systems d) (package-transitive-supported-systems e)))) +(test-assert "package-closure" + (let-syntax ((dummy-package/no-implicit + (syntax-rules () + ((_ name rest ...) + (package + (inherit (dummy-package name rest ...)) + (build-system trivial-build-system)))))) + (let* ((a (dummy-package/no-implicit "a")) + (b (dummy-package/no-implicit "b" + (propagated-inputs `(("a" ,a))))) + (c (dummy-package/no-implicit "c" + (inputs `(("a" ,a))))) + (d (dummy-package/no-implicit "d" + (native-inputs `(("b" ,b))))) + (e (dummy-package/no-implicit "e" + (inputs `(("c" ,c) ("d" ,d)))))) + (lset= eq? + (list a b c d e) + (package-closure (list e)) + (package-closure (list e d)) + (package-closure (list e c b)))))) + (test-equal "origin-actual-file-name" "foo-1.tar.gz" (let ((o (dummy-origin (uri "http://www.example.com/foo-1.tar.gz")))) @@ -1180,4 +1202,5 @@ ;;; Local Variables: ;;; eval: (put 'dummy-package 'scheme-indent-function 1) +;;; eval: (put 'dummy-package/no-implicit 'scheme-indent-function 1) ;;; End: -- cgit v1.2.3 From ea6fb108f6a3a53d48ea187b1f82b5f7ffce00a7 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 28 Jan 2019 22:20:20 +0100 Subject: upstream: Temporarily skip failing test. * tests/upstream.scm ("coalesce-sources same version"): Skip. --- tests/upstream.scm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests') diff --git a/tests/upstream.scm b/tests/upstream.scm index 6c86abe817..e431956960 100644 --- a/tests/upstream.scm +++ b/tests/upstream.scm @@ -24,6 +24,9 @@ (test-begin "upstream") +;; FIXME: Temporarily skipping this test; see . +(test-skip 1) + (test-equal "coalesce-sources same version" (list (upstream-source (package "foo") (version "1") -- cgit v1.2.3 From 976ef2d97887d16eab8d4eb9dad811786b04d690 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 27 Jan 2019 22:10:13 +0100 Subject: status: Record more information about builds. * guix/status.scm (): New record type. (build, matching-build): New procedures. (compute-status): Adjust to manipulate records instead of derivation file names in 'build-status-builds-completed' and 'build-status-building'. (build-event-output-port)[process-line]: Use 'string-split' to preserve spaces. * tests/status.scm ("compute-status, builds + substitutes") ("compute-status, missing events"): Adjust to expect records. Produce complete "build-started" events. ("compute-status, multiplexed build output"): Likewise, and remove "bar.drv" from 'builds-completed'. --- guix/status.scm | 76 +++++++++++++++++++++++++++++++++++++++++++------------- tests/status.scm | 28 +++++++++++---------- 2 files changed, 74 insertions(+), 30 deletions(-) (limited to 'tests') diff --git a/guix/status.scm b/guix/status.scm index 93e119bed1..0a5ff59236 100644 --- a/guix/status.scm +++ b/guix/status.scm @@ -50,6 +50,11 @@ build-status-builds-completed build-status-downloads-completed + build? + build + build-derivation + build-system + download? download download-item @@ -85,15 +90,28 @@ ;; Builds and substitutions performed by the daemon. (define-record-type* build-status make-build-status build-status? - (building build-status-building ;list of drv + (building build-status-building ;list of (default '())) (downloading build-status-downloading ;list of (default '())) - (builds-completed build-status-builds-completed ;list of drv + (builds-completed build-status-builds-completed ;list of (default '())) - (downloads-completed build-status-downloads-completed ;list of store items + (downloads-completed build-status-downloads-completed ;list of (default '()))) +;; On-going or completed build. +(define-record-type + (%build derivation id system log-file) + build? + (derivation build-derivation) ;string (.drv file name) + (id build-id) ;#f | integer + (system build-system) ;string + (log-file build-log-file)) ;#f | string + +(define* (build derivation system #:key id log-file) + "Return a new build." + (%build derivation id system log-file)) + ;; On-going or completed downloads. Downloads can be stem from substitutes ;; and from "builtin:download" fixed-output derivations. (define-record-type @@ -113,6 +131,11 @@ "Return a new download." (%download item uri size start end transferred)) +(define (matching-build drv) + "Return a predicate that matches builds of DRV." + (lambda (build) + (string=? drv (build-derivation build)))) + (define (matching-download item) "Return a predicate that matches downloads of ITEM." (lambda (download) @@ -126,15 +149,29 @@ "Given EVENT, a tuple like (build-started \"/gnu/store/...-foo.drv\" ...), compute a new status based on STATUS." (match event - (('build-started drv _ ...) - (build-status - (inherit status) - (building (cons drv (build-status-building status))))) + (('build-started drv "-" system log-file . rest) + (let ((build (build drv system + #:id (match rest + ((pid . _) (string->number pid)) + (_ #f)) + #:log-file (if (string-null? log-file) + #f + log-file)))) + (build-status + (inherit status) + (building (cons build (build-status-building status)))))) (((or 'build-succeeded 'build-failed) drv _ ...) - (build-status - (inherit status) - (building (delete drv (build-status-building status))) - (builds-completed (cons drv (build-status-builds-completed status))))) + (let ((build (find (matching-build drv) + (build-status-building status)))) + ;; If BUILD is #f, this may be because DRV corresponds to a + ;; fixed-output derivation that is listed as a download. + (if build + (build-status + (inherit status) + (building (delq build (build-status-building status))) + (builds-completed + (cons build (build-status-builds-completed status)))) + status))) ;; Note: Ignore 'substituter-started' and 'substituter-succeeded' because ;; they're not as informative as 'download-started' and @@ -146,10 +183,11 @@ compute a new status based on STATUS." ;; because ITEM is different from DRV's output. (build-status (inherit status) - (building (remove (lambda (drv) - (equal? (false-if-exception - (derivation-path->output-path drv)) - item)) + (building (remove (lambda (build) + (let ((drv (build-derivation build))) + (equal? (false-if-exception + (derivation-path->output-path drv)) + item))) (build-status-building status))) (downloading (cons (download item uri #:size size #:start (current-time time-monotonic)) @@ -394,7 +432,7 @@ addition to build events." (N_ "The following build is still in progress:~%~{ ~a~%~}~%" "The following builds are still in progress:~%~{ ~a~%~}~%" (length ongoing)) - ongoing)))) + (map build-derivation ongoing))))) (('build-failed drv . _) (format port (failure (G_ "build of ~a failed")) drv) (newline port) @@ -570,7 +608,11 @@ The second return value is a thunk to retrieve the current state." (define (process-line line) (cond ((string-prefix? "@ " line) - (match (string-tokenize (string-drop line 2)) + ;; Note: Drop the trailing \n, and use 'string-split' to preserve + ;; spaces (the log file part of 'build-started' events can be the + ;; empty string.) + (match (string-split (string-drop (string-drop-right line 1) 2) + #\space) (("build-log" (= string->number pid) (= string->number len)) (set! %build-output-pid pid) (set! %build-output '()) diff --git a/tests/status.scm b/tests/status.scm index 08a3153218..e3ea768968 100644 --- a/tests/status.scm +++ b/tests/status.scm @@ -36,18 +36,18 @@ (test-equal "compute-status, builds + substitutes" (list (build-status - (building '("foo.drv")) + (building (list (build "foo.drv" "x86_64-linux"))) (downloading (list (download "bar" "http://example.org/bar" #:size 500 #:start 'now)))) (build-status - (building '("foo.drv")) + (building (list (build "foo.drv" "x86_64-linux"))) (downloading (list (download "bar" "http://example.org/bar" #:size 500 #:transferred 42 #:start 'now)))) (build-status - (builds-completed '("foo.drv")) + (builds-completed (list (build "foo.drv" "x86_64-linux"))) (downloads-completed (list (download "bar" "http://example.org/bar" #:size 500 #:transferred 500 @@ -58,7 +58,7 @@ (compute-status event status #:current-time (const 'now)))))) - (display "@ build-started foo.drv\n" port) + (display "@ build-started foo.drv - x86_64-linux \n" port) (display "@ substituter-started bar\n" port) (display "@ download-started bar http://example.org/bar 500\n" port) (display "various\nthings\nget\nwritten\n" port) @@ -76,7 +76,8 @@ (test-equal "compute-status, missing events" (list (build-status - (building '("foo.drv")) + (building (list (build "foo.drv" "x86_64-linux" + #:log-file "foo.log"))) (downloading (list (download "baz" "http://example.org/baz" #:size 500 #:transferred 42 @@ -86,7 +87,8 @@ #:transferred 0 #:start 'now)))) (build-status - (builds-completed '("foo.drv")) + (builds-completed (list (build "foo.drv" "x86_64-linux" + #:log-file "foo.log"))) (downloads-completed (list (download "baz" "http://example.org/baz" #:size 500 #:transferred 500 @@ -103,7 +105,7 @@ (compute-status event status #:current-time (const 'now)))))) - (display "@ build-started foo.drv\n" port) + (display "@ build-started foo.drv - x86_64-linux foo.log\n" port) (display "@ download-started bar http://example.org/bar 999\n" port) (display "various\nthings\nget\nwritten\n" port) (display "@ download-progress baz http://example.org/baz 500 42\n" @@ -136,19 +138,19 @@ (test-equal "compute-status, multiplexed build output" (list (build-status - (building '("foo.drv")) + (building (list (build "foo.drv" "x86_64-linux" #:id 121))) (downloading (list (download "bar" "http://example.org/bar" #:size 999 #:start 'now)))) (build-status - (building '("foo.drv")) + (building (list (build "foo.drv" "x86_64-linux" #:id 121))) (downloading (list (download "bar" "http://example.org/bar" #:size 999 #:transferred 42 #:start 'now)))) (build-status - ;; XXX: Should "bar.drv" be present twice? - (builds-completed '("bar.drv" "foo.drv")) + ;; "bar" is now only listed as a download. + (builds-completed (list (build "foo.drv" "x86_64-linux" #:id 121))) (downloads-completed (list (download "bar" "http://example.org/bar" #:size 999 #:transferred 999 @@ -162,8 +164,8 @@ #:derivation-path->output-path (match-lambda ("bar.drv" "bar"))))))) - (display "@ build-started foo.drv 121\n" port) - (display "@ build-started bar.drv 144\n" port) + (display "@ build-started foo.drv - x86_64-linux 121\n" port) + (display "@ build-started bar.drv - armhf-linux bar.log 144\n" port) (display "@ build-log 121 6\nHello!" port) (display "@ build-log 144 50 @ download-started bar http://example.org/bar 999\n" port) -- cgit v1.2.3 From 73a8681a16869a2b3a9da1c7ba9434e07a204e19 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 27 Jan 2019 22:33:16 +0100 Subject: status: Keep track of build completion as reported by build tools. * guix/status.scm ()[completion]: New field. (build): Add #:completion parameter. (%percentage-line-rx, %fraction-line-rx): New variables. (update-build): New procedure. (compute-status): Add 'build-log' case. * tests/status.scm ("compute-status, build completion"): New test. --- guix/status.scm | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- tests/status.scm | 31 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/guix/status.scm b/guix/status.scm index 0a5ff59236..0435d14d6a 100644 --- a/guix/status.scm +++ b/guix/status.scm @@ -101,16 +101,17 @@ ;; On-going or completed build. (define-record-type - (%build derivation id system log-file) + (%build derivation id system log-file 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 + (log-file build-log-file) ;#f | string + (completion build-completion)) ;#f | integer (percentage) -(define* (build derivation system #:key id log-file) +(define* (build derivation system #:key id log-file completion) "Return a new build." - (%build derivation id system log-file)) + (%build derivation id system log-file completion)) ;; On-going or completed downloads. Downloads can be stem from substitutes ;; and from "builtin:download" fixed-output derivations. @@ -141,6 +142,57 @@ (lambda (download) (string=? item (download-item download)))) +(define %percentage-line-rx + ;; Things like CMake write lines like "[ 10%] gcc -c …". This regexp + ;; matches them. + (make-regexp "^[[:space:]]*\\[ *([0-9]+)%\\]")) + +(define %fraction-line-rx + ;; The 'compiled-modules' derivations and Ninja produce reports like + ;; "[ 1/32]" at the beginning of each line, while GHC prints "[ 6 of 45]". + ;; This regexp matches these. + (make-regexp "^[[:space:]]*\\[ *([0-9]+) *(/|of) *([0-9]+)\\]")) + +(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) + (= (build-id build) id))) + (build-status-building status))) + + (define (update %) + (let ((build (find-build))) + (build-status + (inherit status) + (building (cons (set-completion build %) + (delq build (build-status-building status))))))) + + (cond ((string-any #\nul line) + ;; Don't try to match a regexp here. + status) + ((regexp-exec %percentage-line-rx line) + => + (lambda (match) + (let ((% (string->number (match:substring match 1)))) + (update %)))) + ((regexp-exec %fraction-line-rx line) + => + (lambda (match) + (let ((done (string->number (match:substring match 1))) + (total (string->number (match:substring match 3)))) + (update (* 100. (/ done total)))))) + (else + status))) + (define* (compute-status event status #:key (current-time current-time) @@ -242,6 +294,8 @@ compute a new status based on STATUS." (current-time time-monotonic)) #:transferred transferred) downloads))))) + (('build-log (? integer? pid) line) + (update-build status pid line)) (_ status))) diff --git a/tests/status.scm b/tests/status.scm index e3ea768968..f3afadfcd0 100644 --- a/tests/status.scm +++ b/tests/status.scm @@ -180,4 +180,35 @@ (display "@ build-succeeded bar.drv\n" port) (list first second (get-status)))))) +(test-equal "compute-status, build completion" + (list (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121)))) + (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121 + #:completion 0.)))) + (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121 + #:completion 50.)))) + (build-status + (builds-completed (list (build "foo.drv" "x86_64-linux" #:id 121 + #:completion 100.))))) + (let-values (((port get-status) + (build-event-output-port (lambda (event status) + (compute-status event status + #:current-time + (const 'now)))))) + (display "@ build-started foo.drv - x86_64-linux 121\n" port) + (display "@ build-log 121 6\nHello!" port) + (let ((first (get-status))) + (display "@ build-log 121 20\n[ 0/100] building X\n" port) + (display "@ build-log 121 6\nHello!" port) + (let ((second (get-status))) + (display "@ build-log 121 20\n[50/100] building Y\n" port) + (display "@ build-log 121 6\nHello!" port) + (let ((third (get-status))) + (display "@ build-log 121 21\n[100/100] building Z\n" port) + (display "@ build-log 121 6\nHello!" port) + (display "@ build-succeeded foo.drv\n" port) + (list first second third (get-status))))))) + (test-end "status") -- cgit v1.2.3 From a87d66f371da2a84d7bba1cae58b71c9c9af73aa Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 3 Feb 2019 22:10:06 +0100 Subject: daemon: Rename 'NIX_STATE_DIR' and 'NIX_DB_DIR' environment variables. Fixes . Reported by Jeff Mickey . * guix/config.scm.in (%state-directory): Change NIX_STATE_DIR to GUIX_STATE_DIRECTORY. (%store-database-directory): Change NIX_DB_DIR to GUIX_DATABASE_DIRECTORY. * nix/libstore/globals.cc (Settings::processEnvironment): Likewise. * guix/self.scm (make-config.scm): Likewise. * build-aux/build-self.scm (make-config.scm): Likewise. * build-aux/test-env.in: Likewise. * tests/derivations.scm ("derivation #:leaked-env-vars"): Likewise. * tests/guix-build.sh (GUIX_DAEMON_SOCKET): Likewise. * tests/guix-daemon.sh (socket): Likewise. --- build-aux/build-self.scm | 4 ++-- build-aux/test-env.in | 22 +++++++++++----------- guix/config.scm.in | 6 +++--- guix/self.scm | 4 ++-- nix/libstore/globals.cc | 6 +++--- tests/derivations.scm | 15 ++++++++------- tests/guix-build.sh | 4 ++-- tests/guix-daemon.sh | 2 +- 8 files changed, 32 insertions(+), 31 deletions(-) (limited to 'tests') diff --git a/build-aux/build-self.scm b/build-aux/build-self.scm index f70c3d91ff..d18b4504cf 100644 --- a/build-aux/build-self.scm +++ b/build-aux/build-self.scm @@ -114,11 +114,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/build-aux/test-env.in b/build-aux/test-env.in index aaadcf205b..b1470bb953 100644 --- a/build-aux/test-env.in +++ b/build-aux/test-env.in @@ -1,7 +1,7 @@ #!/bin/sh # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès +# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès # # This file is part of GNU Guix. # @@ -51,19 +51,19 @@ then NIX_STORE_DIR="`cd "@GUIX_TEST_ROOT@/store"; pwd -P`" NIX_LOCALSTATE_DIR="@GUIX_TEST_ROOT@/var" - NIX_LOG_DIR="@GUIX_TEST_ROOT@/var/log/guix" - NIX_DB_DIR="@GUIX_TEST_ROOT@/db" + GUIX_LOG_DIRECTORY="@GUIX_TEST_ROOT@/var/log/guix" + GUIX_DATABASE_DIRECTORY="@GUIX_TEST_ROOT@/db" NIX_ROOT_FINDER="@abs_top_builddir@/nix/scripts/list-runtime-roots" # Choose a PID-dependent name to allow for parallel builds. Note # that the directory name must be chosen so that the socket's file # name is less than 108-char long (the size of `sun_path' in glibc). # Currently, in Nix builds, we're at ~106 chars... - NIX_STATE_DIR="@GUIX_TEST_ROOT@/var/$$" + GUIX_STATE_DIRECTORY="@GUIX_TEST_ROOT@/var/$$" # We can't exit when we reach the limit, because perhaps the test doesn't # actually rely on the daemon, but at least warn. - if test "`echo -n "$NIX_STATE_DIR/daemon-socket/socket" | wc -c`" -ge 108 + if test "`echo -n "$GUIX_STATE_DIRECTORY/daemon-socket/socket" | wc -c`" -ge 108 then echo "warning: exceeding socket file name limit; test may fail!" >&2 fi @@ -82,22 +82,22 @@ then fi # A place to store data of the substituter. - GUIX_BINARY_SUBSTITUTE_URL="file://$NIX_STATE_DIR/substituter-data" - rm -rf "$NIX_STATE_DIR/substituter-data" - mkdir -p "$NIX_STATE_DIR/substituter-data" + GUIX_BINARY_SUBSTITUTE_URL="file://$GUIX_STATE_DIRECTORY/substituter-data" + rm -rf "$GUIX_STATE_DIRECTORY/substituter-data" + mkdir -p "$GUIX_STATE_DIRECTORY/substituter-data" # For a number of tests, we want to allow unsigned narinfos, for # simplicity. GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES=yes # Place for the substituter's cache. - XDG_CACHE_HOME="$NIX_STATE_DIR/cache-$$" + XDG_CACHE_HOME="$GUIX_STATE_DIRECTORY/cache-$$" # For the (guix import snix) tests. NIXPKGS="@NIXPKGS@" export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ - NIX_LOCALSTATE_DIR NIX_LOG_DIR NIX_STATE_DIR NIX_DB_DIR \ + NIX_LOCALSTATE_DIR GUIX_LOG_DIRECTORY GUIX_STATE_DIRECTORY GUIX_DATABASE_DIRECTORY \ NIX_ROOT_FINDER GUIX_BINARY_SUBSTITUTE_URL \ GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES \ GUIX_CONFIGURATION_DIRECTORY XDG_CACHE_HOME NIXPKGS @@ -109,7 +109,7 @@ then --substitute-urls="$GUIX_BINARY_SUBSTITUTE_URL" & daemon_pid=$! - trap "kill $daemon_pid ; rm -rf $NIX_STATE_DIR" EXIT + trap "kill $daemon_pid ; rm -rf $GUIX_STATE_DIRECTORY" EXIT # The test suite expects the 'guile-bootstrap' package to be available. # Normally the Guile bootstrap tarball is downloaded by a fixed-output 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 +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019 Ludovic Courtès ;;; Copyright © 2017 Caleb Ristvedt ;;; ;;; 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/self.scm b/guix/self.scm index f028bdbfdd..68f5641fec 100644 --- a/guix/self.scm +++ b/guix/self.scm @@ -786,11 +786,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/nix/libstore/globals.cc b/nix/libstore/globals.cc index 25f80da2dd..ac92971887 100644 --- a/nix/libstore/globals.cc +++ b/nix/libstore/globals.cc @@ -67,9 +67,9 @@ void Settings::processEnvironment() { nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR))); nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR)); - nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR)); - nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR)); - nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db"); + nixLogDir = canonPath(getEnv("GUIX_LOG_DIRECTORY", NIX_LOG_DIR)); + nixStateDir = canonPath(getEnv("GUIX_STATE_DIRECTORY", NIX_STATE_DIR)); + nixDBPath = getEnv("GUIX_DATABASE_DIRECTORY", nixStateDir + "/db"); nixConfDir = canonPath(getEnv("GUIX_CONFIGURATION_DIRECTORY", GUIX_CONFIGURATION_DIRECTORY)); nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR)); nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR)); diff --git a/tests/derivations.scm b/tests/derivations.scm index c0601c0e88..dbb5b584eb 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -650,18 +650,19 @@ (build-derivations %store (list drv)) #f))) -;; Here we should get the value of $NIX_STATE_DIR that the daemon sees, which -;; is a unique value for each test process; this value is the same as the one -;; we see in the process executing this file since it is set by 'test-env'. +;; Here we should get the value of $GUIX_STATE_DIRECTORY that the daemon sees, +;; which is a unique value for each test process; this value is the same as +;; the one we see in the process executing this file since it is set by +;; 'test-env'. (test-equal "derivation #:leaked-env-vars" - (getenv "NIX_STATE_DIR") - (let* ((value (getenv "NIX_STATE_DIR")) + (getenv "GUIX_STATE_DIRECTORY") + (let* ((value (getenv "GUIX_STATE_DIRECTORY")) (drv (derivation %store "leaked-env-vars" %bash - '("-c" "echo -n $NIX_STATE_DIR > $out") + '("-c" "echo -n $GUIX_STATE_DIRECTORY > $out") #:hash (sha256 (string->utf8 value)) #:hash-algo 'sha256 #:inputs `((,%bash)) - #:leaked-env-vars '("NIX_STATE_DIR")))) + #:leaked-env-vars '("GUIX_STATE_DIRECTORY")))) (and (build-derivations %store (list drv)) (call-with-input-file (derivation->output-path drv) get-string-all)))) diff --git a/tests/guix-build.sh b/tests/guix-build.sh index 7842ce87c6..66bf6be8d0 100644 --- a/tests/guix-build.sh +++ b/tests/guix-build.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2016, 2017, 2018 Ludovic Courtès +# Copyright © 2012, 2013, 2014, 2016, 2017, 2018, 2019 Ludovic Courtès # # This file is part of GNU Guix. # @@ -37,7 +37,7 @@ guix build hello -d | \ grep -e '-hello-[0-9\.]\+\.drv$' # Passing a URI. -GUIX_DAEMON_SOCKET="file://$NIX_STATE_DIR/daemon-socket/socket" \ +GUIX_DAEMON_SOCKET="file://$GUIX_STATE_DIRECTORY/daemon-socket/socket" \ guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)' ( if GUIX_DAEMON_SOCKET="weird://uri" \ diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh index 4c19a55722..ce82cfd1e6 100644 --- a/tests/guix-daemon.sh +++ b/tests/guix-daemon.sh @@ -63,7 +63,7 @@ guile -c " (exit (has-substitutes? store \"$out\"))" # Now, run guix-daemon --no-substitutes. -socket="$NIX_STATE_DIR/alternate-socket" +socket="$GUIX_STATE_DIRECTORY/alternate-socket" guix-daemon --no-substitutes --listen="$socket" --disable-chroot & daemon_pid=$! trap 'kill $daemon_pid' EXIT -- cgit v1.2.3 From ba514b601ba6be15b823e0a12d4b6e42f9d2489e Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Tue, 5 Feb 2019 11:24:44 +0100 Subject: status: Keep track of the current build phase. * guix/status.scm ()[phase]: New field. (%phase-start-rx): New variable. (update-build): Add clause to match %PHASE-START-RX and adjust the 'phase' field accordingly. * tests/status.scm ("compute-status, build phase"): Add test --- guix/status.scm | 28 +++++++++++++++++++++++++--- tests/status.scm | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/guix/status.scm b/guix/status.scm index 070071d46f..c3c219219d 100644 --- a/guix/status.scm +++ b/guix/status.scm @@ -55,6 +55,9 @@ build build-derivation build-system + build-log-file + build-phase + build-completion download? download @@ -102,18 +105,20 @@ ;; On-going or completed build. (define-immutable-record-type - (%build derivation id system log-file completion) + (%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 + (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. @@ -144,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. @@ -185,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))) diff --git a/tests/status.scm b/tests/status.scm index f3afadfcd0..01a61f7345 100644 --- a/tests/status.scm +++ b/tests/status.scm @@ -211,4 +211,37 @@ (display "@ build-succeeded foo.drv\n" port) (list first second third (get-status))))))) +(test-equal "compute-status, build phase" + (list (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121 + #:phase 'configure)))) + (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121 + #:phase 'configure + #:completion 50.)))) + (build-status + (building (list (build "foo.drv" "x86_64-linux" #:id 121 + #:phase 'install)))) + (build-status + (builds-completed (list (build "foo.drv" "x86_64-linux" #:id 121 + #:phase 'install))))) + (let-values (((port get-status) + (build-event-output-port (lambda (event status) + (compute-status event status + #:current-time + (const 'now)))))) + (display "@ build-started foo.drv - x86_64-linux 121\n" port) + (display "@ build-log 121 27\nstarting phase `configure'\n" port) + (display "@ build-log 121 6\nabcde!" port) + (let ((first (get-status))) + (display "@ build-log 121 20\n[50/100] building Y\n" port) + (display "@ build-log 121 6\nfghik!" port) + (let ((second (get-status))) + (display "@ build-log 121 21\n[100/100] building Z\n" port) + (display "@ build-log 121 25\nstarting phase `install'\n" port) + (display "@ build-log 121 6\nlmnop!" port) + (let ((third (get-status))) + (display "@ build-succeeded foo.drv\n" port) + (list first second third (get-status))))))) + (test-end "status") -- cgit v1.2.3