diff options
Diffstat (limited to 'guix')
-rw-r--r-- | guix/android-repo-download.scm | 5 | ||||
-rw-r--r-- | guix/build-system/asdf.scm | 18 | ||||
-rw-r--r-- | guix/build/asdf-build-system.scm | 15 | ||||
-rw-r--r-- | guix/build/download.scm | 84 | ||||
-rw-r--r-- | guix/build/emacs-build-system.scm | 79 | ||||
-rw-r--r-- | guix/ci.scm | 4 | ||||
-rw-r--r-- | guix/cvs-download.scm | 12 | ||||
-rw-r--r-- | guix/download.scm | 19 | ||||
-rw-r--r-- | guix/hg-download.scm | 9 | ||||
-rw-r--r-- | guix/import/pypi.scm | 4 | ||||
-rw-r--r-- | guix/packages.scm | 5 | ||||
-rw-r--r-- | guix/profiles.scm | 99 | ||||
-rw-r--r-- | guix/scripts/perform-download.scm | 7 | ||||
-rw-r--r-- | guix/scripts/system.scm | 1 | ||||
-rw-r--r-- | guix/scripts/weather.scm | 29 | ||||
-rw-r--r-- | guix/self.scm | 3 | ||||
-rw-r--r-- | guix/ssh.scm | 30 | ||||
-rw-r--r-- | guix/status.scm | 18 | ||||
-rw-r--r-- | guix/store.scm | 72 | ||||
-rw-r--r-- | guix/swh.scm | 65 | ||||
-rw-r--r-- | guix/ui.scm | 7 |
21 files changed, 435 insertions, 150 deletions
diff --git a/guix/android-repo-download.scm b/guix/android-repo-download.scm index 5ff3e7edd4..1c3502e673 100644 --- a/guix/android-repo-download.scm +++ b/guix/android-repo-download.scm @@ -78,6 +78,9 @@ generic name if unset." (define zlib (module-ref (resolve-interface '(gnu packages compression)) 'zlib)) + (define guile-json + (module-ref (resolve-interface '(gnu packages guile)) 'guile-json-4)) + (define gnutls (module-ref (resolve-interface '(gnu packages tls)) 'gnutls)) @@ -99,7 +102,7 @@ generic name if unset." (define build (with-imported-modules modules - (with-extensions (list gnutls) + (with-extensions (list gnutls guile-json) ;for (guix swh) #~(begin (use-modules (guix build android-repo) (guix build utils) diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm index 28403a1960..b4e40ee8c2 100644 --- a/guix/build-system/asdf.scm +++ b/guix/build-system/asdf.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2017 Andy Patterson <ajpatter@uwaterloo.ca> -;;; Copyright © 2019, 2020 Guillaume Le Vaillant <glv@posteo.net> +;;; Copyright © 2019, 2020, 2021 Guillaume Le Vaillant <glv@posteo.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -291,16 +291,16 @@ set up using CL source package conventions." (imported-modules %asdf-build-system-modules) (modules %asdf-build-modules)) - ;; FIXME: The definition of 'systems' is pretty hacky. - ;; Is there a more elegant way to do it? (define systems (if (null? (cadr asd-systems)) - `(quote - ,(list - (string-drop - ;; NAME is the value returned from `package-full-name'. - (hyphen-separated-name->name+version name) - (1+ (string-length lisp-type))))) ; drop the "<lisp>-" prefix. + ;; FIXME: Find a more reliable way to get the main system name. + (let* ((lisp-prefix (string-append lisp-type "-")) + (package-name (hyphen-separated-name->name+version + (if (string-prefix? lisp-prefix name) + (string-drop name + (string-length lisp-prefix)) + name)))) + `(quote ,(list package-name))) asd-systems)) (define builder diff --git a/guix/build/asdf-build-system.scm b/guix/build/asdf-build-system.scm index 6ad855cab2..7f1037c4f9 100644 --- a/guix/build/asdf-build-system.scm +++ b/guix/build/asdf-build-system.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2017 Andy Patterson <ajpatter@uwaterloo.ca> -;;; Copyright © 2020 Guillaume Le Vaillant <glv@posteo.net> +;;; Copyright © 2020, 2021 Guillaume Le Vaillant <glv@posteo.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -52,12 +52,13 @@ (string-append %source-install-prefix "/systems")) (define (main-system-name output) - (let ((package-name (package-name->name+version - (strip-store-file-name output))) - (lisp-prefix (string-append (%lisp-type) "-"))) - (if (string-prefix? lisp-prefix package-name) - (string-drop package-name (string-length lisp-prefix)) - package-name))) + ;; FIXME: Find a more reliable way to get the main system name. + (let* ((full-name (strip-store-file-name output)) + (lisp-prefix (string-append (%lisp-type) "-")) + (package-name (if (string-prefix? lisp-prefix full-name) + (string-drop full-name (string-length lisp-prefix)) + full-name))) + (package-name->name+version package-name))) (define (lisp-source-directory output name) (string-append output (%lisp-source-install-prefix) "/" name)) diff --git a/guix/build/download.scm b/guix/build/download.scm index a22d4064ca..b14db42352 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr> +;;; Copyright © 2021 Timothy Sample <samplet@ngyro.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -34,6 +35,8 @@ #:use-module (srfi srfi-19) #:use-module (srfi srfi-26) #:autoload (ice-9 ftw) (scandir) + #:autoload (guix base16) (bytevector->base16-string) + #:autoload (guix swh) (swh-download-directory) #:use-module (ice-9 match) #:use-module (ice-9 format) #:export (open-socket-for-uri @@ -626,10 +629,54 @@ Return a list of URIs." (else (list uri)))) +(define* (disarchive-fetch/any uris file + #:key (timeout 10) (verify-certificate? #t)) + "Fetch a Disarchive specification from any of URIS, assemble it, +and write the output to FILE." + (define (fetch-specification uris) + (any (lambda (uri) + (false-if-exception* + (let-values (((port size) (http-fetch uri + #:verify-certificate? + verify-certificate? + #:timeout timeout))) + (let ((specification (read port))) + (close-port port) + specification)))) + uris)) + + (define (resolve addresses output) + (any (match-lambda + (('swhid swhid) + (match (string-split swhid #\:) + (("swh" "1" "dir" id) + (format #t "Downloading ~a from Software Heritage...~%" file) + (false-if-exception* + (swh-download-directory id output))) + (_ #f))) + (_ #f)) + addresses)) + + (format #t "Trying to use Disarchive to assemble ~a...~%" file) + (match (and=> (resolve-module '(disarchive) #:ensure #f) + (lambda (disarchive) + (cons (module-ref disarchive '%disarchive-log-port) + (module-ref disarchive 'disarchive-assemble)))) + (#f (format #t "could not load Disarchive~%") + #f) + ((%disarchive-log-port . disarchive-assemble) + (match (fetch-specification uris) + (#f (format #t "could not find its Disarchive specification~%") + #f) + (spec (parameterize ((%disarchive-log-port (current-output-port))) + (false-if-exception* + (disarchive-assemble spec file #:resolver resolve)))))))) + (define* (url-fetch url file #:key (timeout 10) (verify-certificate? #t) (mirrors '()) (content-addressed-mirrors '()) + (disarchive-mirrors '()) (hashes '()) print-build-trace?) "Fetch FILE from URL; URL may be either a single string, or a list of @@ -693,6 +740,18 @@ otherwise simply ignore them." hashes)) content-addressed-mirrors)) + (define disarchive-uris + (append-map (match-lambda + ((? string? mirror) + (map (match-lambda + ((hash-algo . hash) + (string->uri + (string-append mirror + (symbol->string hash-algo) "/" + (bytevector->base16-string hash))))) + hashes))) + disarchive-mirrors)) + ;; 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) 'none) @@ -705,15 +764,20 @@ otherwise simply ignore them." (or (fetch uri file) (try tail))) (() - (format (current-error-port) "failed to download ~s from ~s~%" - file url) - - ;; Remove FILE in case we made an incomplete download, for example due - ;; to ENOSPC. - (catch 'system-error - (lambda () - (delete-file file)) - (const #f)) - #f)))) + ;; If we are looking for a software archive, one last thing we + ;; can try is to use Disarchive to assemble it. + (or (disarchive-fetch/any disarchive-uris file + #:verify-certificate? verify-certificate? + #:timeout timeout) + (begin + (format (current-error-port) "failed to download ~s from ~s~%" + file url) + ;; Remove FILE in case we made an incomplete download, for + ;; example due to ENOSPC. + (catch 'system-error + (lambda () + (delete-file file)) + (const #f)) + #f)))))) ;;; download.scm ends here diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm index 26ea59bc25..e41e9a6595 100644 --- a/guix/build/emacs-build-system.scm +++ b/guix/build/emacs-build-system.scm @@ -26,13 +26,16 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) + #:use-module (ice-9 format) + #:use-module (ice-9 ftw) #:use-module (ice-9 rdelim) #:use-module (ice-9 regex) #:use-module (ice-9 match) #:export (%standard-phases %default-include %default-exclude - emacs-build)) + emacs-build + elpa-directory)) ;; Commentary: ;; @@ -40,9 +43,12 @@ ;; ;; Code: -;;; All the packages are installed directly under site-lisp, which means that -;;; having that directory in the EMACSLOADPATH is enough to have them found by -;;; Emacs. +;;; The location in which Emacs looks for packages. Emacs Lisp code that is +;;; installed there directly will be found when that directory is added to +;;; EMACSLOADPATH. To avoid clashes between packages (particularly considering +;;; auxiliary files), we install them one directory level below, however. +;;; This indirection is handled by ‘expand-load-path’ during build and a +;;; profile hook otherwise. (define %install-dir "/share/emacs/site-lisp") ;; These are the default inclusion/exclusion regexps for the install phase. @@ -73,33 +79,43 @@ archive, a directory, or an Emacs Lisp file." #t) (gnu:unpack #:source source))) -(define* (add-source-to-load-path #:key dummy #:allow-other-keys) - "Augment the EMACSLOADPATH environment variable with the source directory." +(define* (expand-load-path #:key (prepend-source? #t) #:allow-other-keys) + "Expand EMACSLOADPATH, so that inputs, whose code resides in subdirectories, +are properly found. +If @var{prepend-source?} is @code{#t} (the default), also add the current +directory to EMACSLOADPATH in front of any other directories." (let* ((source-directory (getcwd)) (emacs-load-path (string-split (getenv "EMACSLOADPATH") #\:)) - ;; XXX: Make sure the Emacs core libraries appear at the end of - ;; EMACSLOADPATH, to avoid shadowing any other libraries depended - ;; upon. - (emacs-load-path-non-core (filter (cut string-contains <> - "/share/emacs/site-lisp") - emacs-load-path)) + (emacs-load-path* + (map + (lambda (dir) + (match (scandir dir (negate (cute member <> '("." "..")))) + ((sub) (string-append dir "/" sub)) + (_ dir))) + emacs-load-path)) (emacs-load-path-value (string-append - (string-join (cons source-directory - emacs-load-path-non-core) - ":") + (string-join + (if prepend-source? + (cons source-directory emacs-load-path*) + emacs-load-path*) + ":") ":"))) (setenv "EMACSLOADPATH" emacs-load-path-value) - (format #t "source directory ~s prepended to the `EMACSLOADPATH' \ -environment variable\n" source-directory))) + (when prepend-source? + (format #t "source directory ~s prepended to the `EMACSLOADPATH' \ +environment variable\n" source-directory)) + (let ((diff (lset-difference string=? emacs-load-path* emacs-load-path))) + (unless (null? diff) + (format #t "expanded load paths for ~{~a~^, ~}\n" + (map basename diff)))))) (define* (build #:key outputs inputs #:allow-other-keys) "Compile .el files." (let* ((emacs (string-append (assoc-ref inputs "emacs") "/bin/emacs")) - (out (assoc-ref outputs "out")) - (site-lisp (string-append out %install-dir))) + (out (assoc-ref outputs "out"))) (setenv "SHELL" "sh") (parameterize ((%emacs emacs)) - (emacs-byte-compile-directory site-lisp)))) + (emacs-byte-compile-directory (elpa-directory out))))) (define* (patch-el-files #:key outputs #:allow-other-keys) "Substitute the absolute \"/bin/\" directory with the right location in the @@ -116,7 +132,8 @@ store in '.el' files." #:binary #t)) (let* ((out (assoc-ref outputs "out")) - (site-lisp (string-append out %install-dir)) + (elpa-name-ver (store-directory->elpa-name-version out)) + (el-dir (string-append out %install-dir "/" elpa-name-ver)) ;; (ice-9 regex) uses libc's regexp routines, which cannot deal with ;; strings containing NULs. Filter out such files. TODO: Remove ;; this workaround when <https://bugs.gnu.org/30116> is fixed. @@ -130,7 +147,7 @@ store in '.el' files." (error "patch-el-files: unable to locate " cmd-name)) (string-append "\"" cmd "\""))))) - (with-directory-excursion site-lisp + (with-directory-excursion el-dir ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still ;; ISO-8859-1-encoded. (unless (false-if-exception (substitute-program-names)) @@ -181,14 +198,14 @@ parallel. PARALLEL-TESTS? is ignored when using a non-make TEST-COMMAND." (not (any (cut match-stripped-file "excluded" <>) exclude))))) (let* ((out (assoc-ref outputs "out")) - (site-lisp (string-append out %install-dir)) + (el-dir (elpa-directory out)) (files-to-install (find-files source install-file?))) (cond ((not (null? files-to-install)) (for-each (lambda (file) (let* ((stripped-file (string-drop file (string-length source))) - (target-file (string-append site-lisp stripped-file))) + (target-file (string-append el-dir stripped-file))) (format #t "`~a' -> `~a'~%" file target-file) (install-file file (dirname target-file)))) files-to-install) @@ -219,11 +236,11 @@ parallel. PARALLEL-TESTS? is ignored when using a non-make TEST-COMMAND." "Generate the autoloads file." (let* ((emacs (string-append (assoc-ref inputs "emacs") "/bin/emacs")) (out (assoc-ref outputs "out")) - (site-lisp (string-append out %install-dir)) (elpa-name-ver (store-directory->elpa-name-version out)) - (elpa-name (package-name->name+version elpa-name-ver))) + (elpa-name (package-name->name+version elpa-name-ver)) + (el-dir (elpa-directory out))) (parameterize ((%emacs emacs)) - (emacs-generate-autoloads elpa-name site-lisp)))) + (emacs-generate-autoloads elpa-name el-dir)))) (define* (enable-autoloads-compilation #:key outputs #:allow-other-keys) "Remove the NO-BYTE-COMPILATION local variable embedded in the generated @@ -258,10 +275,16 @@ second hyphen. This corresponds to 'name-version' as used in ELPA packages." strip-store-file-name) store-dir)) +(define (elpa-directory store-dir) + "Given the store directory STORE-DIR return the absolute install directory +for libraries following the ELPA convention." + (string-append store-dir %install-dir "/" + (store-directory->elpa-name-version store-dir))) + (define %standard-phases (modify-phases gnu:%standard-phases (replace 'unpack unpack) - (add-after 'unpack 'add-source-to-load-path add-source-to-load-path) + (add-after 'unpack 'expand-load-path expand-load-path) (delete 'bootstrap) (delete 'configure) (delete 'build) diff --git a/guix/ci.scm b/guix/ci.scm index f04109112c..c70e5bb9e6 100644 --- a/guix/ci.scm +++ b/guix/ci.scm @@ -43,7 +43,7 @@ checkout? checkout-commit - checkout-input + checkout-channel evaluation? evaluation-id @@ -94,7 +94,7 @@ (define-json-mapping <checkout> make-checkout checkout? json->checkout (commit checkout-commit) ;string (SHA1) - (input checkout-input)) ;string (name) + (channel checkout-channel)) ;string (name) (define-json-mapping <evaluation> make-evaluation evaluation? json->evaluation diff --git a/guix/cvs-download.scm b/guix/cvs-download.scm index 76b3eac739..943d971622 100644 --- a/guix/cvs-download.scm +++ b/guix/cvs-download.scm @@ -28,7 +28,8 @@ #:use-module (ice-9 match) #:export (cvs-reference cvs-reference? - cvs-reference-url + cvs-reference-root-directory + cvs-reference-module cvs-reference-revision cvs-fetch)) @@ -63,13 +64,20 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." (define guile-zlib (module-ref (resolve-interface '(gnu packages guile)) 'guile-zlib)) + (define guile-json + (module-ref (resolve-interface '(gnu packages guile)) 'guile-json-4)) + + (define gnutls + (module-ref (resolve-interface '(gnu packages tls)) 'gnutls)) + (define modules (delete '(guix config) (source-module-closure '((guix build cvs) (guix build download-nar))))) (define build (with-imported-modules modules - (with-extensions (list guile-zlib) + (with-extensions (list guile-json gnutls ;for (guix swh) + guile-zlib) #~(begin (use-modules (guix build cvs) (guix build download-nar)) diff --git a/guix/download.scm b/guix/download.scm index 30f69c0325..72094e7318 100644 --- a/guix/download.scm +++ b/guix/download.scm @@ -406,12 +406,19 @@ (plain-file "content-addressed-mirrors" (object->string %content-addressed-mirrors))) +(define %disarchive-mirrors + '("https://disarchive.ngyro.com/")) + +(define %disarchive-mirror-file + (plain-file "disarchive-mirrors" (object->string %disarchive-mirrors))) + (define built-in-builders* (store-lift built-in-builders)) (define* (built-in-download file-name url #:key system hash-algo hash mirrors content-addressed-mirrors + disarchive-mirrors executable? (guile 'unused)) "Download FILE-NAME from URL using the built-in 'download' builder. When @@ -422,13 +429,16 @@ explicitly depend on Guile, GnuTLS, etc. Instead, the daemon performs the download by itself using its own dependencies." (mlet %store-monad ((mirrors (lower-object mirrors)) (content-addressed-mirrors - (lower-object content-addressed-mirrors))) + (lower-object content-addressed-mirrors)) + (disarchive-mirrors (lower-object disarchive-mirrors))) (raw-derivation file-name "builtin:download" '() #:system system #:hash-algo hash-algo #:hash hash #:recursive? executable? - #:sources (list mirrors content-addressed-mirrors) + #:sources (list mirrors + content-addressed-mirrors + disarchive-mirrors) ;; Honor the user's proxy and locale settings. #:leaked-env-vars '("http_proxy" "https_proxy" @@ -439,6 +449,7 @@ download by itself using its own dependencies." ("mirrors" . ,mirrors) ("content-addressed-mirrors" . ,content-addressed-mirrors) + ("disarchive-mirrors" . ,disarchive-mirrors) ,@(if executable? '(("executable" . "1")) '())) @@ -492,7 +503,9 @@ name in the store." #:executable? executable? #:mirrors %mirror-file #:content-addressed-mirrors - %content-addressed-mirror-file))))) + %content-addressed-mirror-file + #:disarchive-mirrors + %disarchive-mirror-file))))) (define* (url-fetch/executable url hash-algo hash #:optional name diff --git a/guix/hg-download.scm b/guix/hg-download.scm index bd55946523..c6cee2dbb8 100644 --- a/guix/hg-download.scm +++ b/guix/hg-download.scm @@ -65,6 +65,12 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." (define guile-zlib (module-ref (resolve-interface '(gnu packages guile)) 'guile-zlib)) + (define guile-json + (module-ref (resolve-interface '(gnu packages guile)) 'guile-json-4)) + + (define gnutls + (module-ref (resolve-interface '(gnu packages tls)) 'gnutls)) + (define modules (delete '(guix config) (source-module-closure '((guix build hg) @@ -72,7 +78,8 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." (define build (with-imported-modules modules - (with-extensions (list guile-zlib) + (with-extensions (list guile-json gnutls ;for (guix swh) + guile-zlib) #~(begin (use-modules (guix build hg) (guix build download-nar)) diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm index bf4dc50138..6731d50891 100644 --- a/guix/import/pypi.scm +++ b/guix/import/pypi.scm @@ -229,8 +229,8 @@ the input field." '("test" "dev"))) (define (parse-requires.txt requires.txt) - "Given REQUIRES.TXT, a Setuptools requires.txt file, return a list of lists -of requirements. + "Given REQUIRES.TXT, a path to a Setuptools requires.txt file, return a list +of lists of requirements. The first list contains the required dependencies while the second the optional test dependencies. Note that currently, optional, non-test diff --git a/guix/packages.scm b/guix/packages.scm index 55e5e70b8c..c825f427d8 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, 2019, 2020 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2014, 2015, 2017, 2018 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2016 Alex Kost <alezost@gmail.com> @@ -790,7 +790,8 @@ specifies modules in scope when evaluating SNIPPET." "Return package ORIGINAL with PATCHES applied." (package (inherit original) (source (origin (inherit (package-source original)) - (patches patches))))) + (patches patches))) + (location (package-location original)))) (define (package-with-extra-patches original patches) "Return package ORIGINAL with all PATCHES appended to its list of patches." diff --git a/guix/profiles.scm b/guix/profiles.scm index 67d90532c1..0044851dc2 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -4,7 +4,7 @@ ;;; Copyright © 2014, 2016 Alex Kost <alezost@gmail.com> ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com> -;;; Copyright © 2016, 2018, 2019 Ricardo Wurmus <rekado@elephly.net> +;;; Copyright © 2016, 2018, 2019, 2021 Ricardo Wurmus <rekado@elephly.net> ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Huang Ying <huang.ying.caritas@gmail.com> ;;; Copyright © 2017 Maxim Cournoyer <maxim.cournoyer@gmail.com> @@ -1115,6 +1115,46 @@ MANIFEST. Single-file bundles are required by programs such as Git and Lynx." `((type . profile-hook) (hook . ca-certificate-bundle)))) +(define (emacs-subdirs manifest) + (define build + (with-imported-modules (source-module-closure + '((guix build profiles) + (guix build utils))) + #~(begin + (use-modules (guix build utils) + (guix build profiles) + (ice-9 ftw) ; scandir + (srfi srfi-1) ; append-map + (srfi srfi-26)) + + (let ((destdir (string-append #$output "/share/emacs/site-lisp")) + (subdirs + (append-map + (lambda (dir) + (filter + file-is-directory? + (map (cute string-append dir "/" <>) + (scandir dir (negate (cute member <> '("." ".."))))))) + (filter file-exists? + (map (cute string-append <> "/share/emacs/site-lisp") + '#$(manifest-inputs manifest)))))) + (mkdir-p destdir) + (with-directory-excursion destdir + (call-with-output-file "subdirs.el" + (lambda (port) + (write + `(normal-top-level-add-to-load-path + (list ,@subdirs)) + port) + (newline port) + #t))))))) + (gexp->derivation "emacs-subdirs" build + #:local-build? #t + #:substitutable? #f + #:properties + `((type . profile-hook) + (hook . emacs-subdirs)))) + (define (glib-schemas manifest) "Return a derivation that unions all schemas from manifest entries and creates the Glib 'gschemas.compiled' file." @@ -1627,12 +1667,22 @@ MANIFEST." (cons (gexp-input thing output) (append-map entry->texlive-input deps)) '())))) + (define texlive-bin + (module-ref (resolve-interface '(gnu packages tex)) 'texlive-bin)) + (define coreutils + (module-ref (resolve-interface '(gnu packages base)) 'coreutils)) + (define sed + (module-ref (resolve-interface '(gnu packages base)) 'sed)) + (define updmap.cfg + (module-ref (resolve-interface '(gnu packages tex)) + 'texlive-default-updmap.cfg)) (define build (with-imported-modules '((guix build utils) (guix build union)) #~(begin (use-modules (guix build utils) - (guix build union)) + (guix build union) + (ice-9 popen)) ;; Build a modifiable union of all texlive inputs. We do this so ;; that TeX live can resolve the parent and grandparent directories @@ -1650,7 +1700,49 @@ MANIFEST." (("^TEXMFROOT = .*") (string-append "TEXMFROOT = " #$output "/share\n")) (("^TEXMF = .*") - "TEXMF = $TEXMFROOT/share/texmf-dist\n")))) + "TEXMF = $TEXMFROOT/share/texmf-dist\n")) + + ;; XXX: This is annoying, but it's necessary because texlive-bin + ;; does not provide wrapped executables. + (setenv "PATH" + (string-append #$(file-append coreutils "/bin") + ":" + #$(file-append sed "/bin"))) + (setenv "PERL5LIB" #$(file-append texlive-bin "/share/tlpkg")) + (setenv "TEXMF" (string-append #$output "/share/texmf-dist")) + + ;; Remove invalid maps from config file. + (let* ((web2c (string-append #$output "/share/texmf-config/web2c/")) + (maproot (string-append #$output "/share/texmf-dist/fonts/map/")) + (updmap.cfg (string-append web2c "updmap.cfg"))) + (mkdir-p web2c) + + ;; Some profiles may already have this file, which prevents us + ;; from copying it. Since we need to generate it from scratch + ;; anyway, we delete it here. + (when (file-exists? updmap.cfg) + (delete-file updmap.cfg)) + (copy-file #$updmap.cfg updmap.cfg) + (make-file-writable updmap.cfg) + (let* ((port (open-pipe* OPEN_WRITE + #$(file-append texlive-bin "/bin/updmap-sys") + "--syncwithtrees" + "--nohash" + "--force" + (string-append "--cnffile=" web2c "updmap.cfg")))) + (display "Y\n" port) + (when (not (zero? (status:exit-val (close-pipe port)))) + (error "failed to filter updmap.cfg"))) + + ;; Generate font maps. + (invoke #$(file-append texlive-bin "/bin/updmap-sys") + (string-append "--cnffile=" web2c "updmap.cfg") + (string-append "--dvipdfmxoutputdir=" + maproot "updmap/dvipdfmx/") + (string-append "--dvipsoutputdir=" + maproot "updmap/dvips/") + (string-append "--pdftexoutputdir=" + maproot "updmap/pdftex/"))))) #t))) (with-monad %store-monad @@ -1672,6 +1764,7 @@ MANIFEST." fonts-dir-file ghc-package-cache-file ca-certificate-bundle + emacs-subdirs glib-schemas gtk-icon-themes gtk-im-modules diff --git a/guix/scripts/perform-download.scm b/guix/scripts/perform-download.scm index 8d409092ba..6889bcef79 100644 --- a/guix/scripts/perform-download.scm +++ b/guix/scripts/perform-download.scm @@ -54,7 +54,8 @@ actual output is different from that when we're doing a 'bmCheck' or (output* "out") (executable "executable") (mirrors "mirrors") - (content-addressed-mirrors "content-addressed-mirrors")) + (content-addressed-mirrors "content-addressed-mirrors") + (disarchive-mirrors "disarchive-mirrors")) (unless url (leave (G_ "~a: missing URL~%") (derivation-file-name drv))) @@ -79,6 +80,10 @@ actual output is different from that when we're doing a 'bmCheck' or (lambda (port) (eval (read port) %user-module))) '()) + #:disarchive-mirrors + (if disarchive-mirrors + (call-with-input-file disarchive-mirrors read) + '()) #:hashes `((,algo . ,hash)) ;; Since DRV's output hash is known, X.509 certificate diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 0a051ee4e3..40401d7e03 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -717,6 +717,7 @@ checking this by themselves in their 'check' procedure." (lower-object (system-image image))) ((docker-image) (system-docker-image os + #:memory-size 1024 #:shared-network? container-shared-network?))))) (define (maybe-suggest-running-guix-pull) diff --git a/guix/scripts/weather.scm b/guix/scripts/weather.scm index 5164fe0494..6d925d416c 100644 --- a/guix/scripts/weather.scm +++ b/guix/scripts/weather.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net> ;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com> ;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com> @@ -171,6 +171,16 @@ about the derivations queued, as is the case with Hydra." #f ;no derivation information (lset-intersection string=? queued items))) +(define (store-item-system store item) + "Return the system (a string such as \"aarch64-linux\")) ITEM targets, +or #f if it could not be determined." + (match (valid-derivers store item) + ((drv . _) + (and=> (false-if-exception (read-derivation-from-file drv)) + derivation-system)) + (() + #f))) + (define* (report-server-coverage server items #:key display-missing?) "Report the subset of ITEMS available as substitutes on SERVER. @@ -270,7 +280,22 @@ are queued~%") (when (and display-missing? (not (null? missing))) (newline) (format #t (G_ "Substitutes are missing for the following items:~%")) - (format #t "~{ ~a~%~}" missing)) + + ;; Display two columns: store items, and their system type. + (format #t "~:{ ~a ~a~%~}" + (zip (map (let ((width (max (- (current-terminal-columns) + 20) + 0))) + (lambda (item) + (if (> (string-length item) width) + item + (string-pad-right item width)))) + missing) + (with-store store + (map (lambda (item) + (or (store-item-system store item) + (G_ "unknown system"))) + missing))))) ;; Return the coverage ratio. (let ((total (length items))) diff --git a/guix/self.scm b/guix/self.scm index 3154d180ac..7181205610 100644 --- a/guix/self.scm +++ b/guix/self.scm @@ -878,7 +878,8 @@ itself." ("guix/store/schema.sql" ,(local-file "../guix/store/schema.sql"))) - #:extensions (list guile-gcrypt) + #:extensions (list guile-gcrypt + guile-json) ;for (guix swh) #:guile-for-build guile-for-build)) (define *extra-modules* diff --git a/guix/ssh.scm b/guix/ssh.scm index 457d1890f9..232b6bfe94 100644 --- a/guix/ssh.scm +++ b/guix/ssh.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2021 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -253,7 +253,22 @@ EXP never returns or calls 'primitive-exit' when it's done." (use-modules (ice-9 match) (rnrs io ports) (rnrs bytevectors)) - (let ((sock (socket AF_UNIX SOCK_STREAM 0)) + (define connect-to-daemon + ;; XXX: 'connect-to-daemon' used to be private and before that it + ;; didn't even exist, hence these shenanigans. + (let ((connect-to-daemon + (false-if-exception (module-ref (resolve-module '(guix store)) + 'connect-to-daemon)))) + (lambda (uri) + (if connect-to-daemon + (connect-to-daemon uri) + (let ((sock (socket AF_UNIX SOCK_STREAM 0))) + (connect sock AF_UNIX ,socket-name) + sock))))) + + ;; Use 'connect-to-daemon' to honor GUIX_DAEMON_SOCKET. + (let ((sock (connect-to-daemon (or (getenv "GUIX_DAEMON_SOCKET") + ,socket-name))) (stdin (current-input-port)) (stdout (current-output-port)) (select* (lambda (read write except) @@ -272,8 +287,6 @@ EXP never returns or calls 'primitive-exit' when it's done." (setvbuf stdin 'block 65536) (setvbuf sock 'block 65536) - (connect sock AF_UNIX ,socket-name) - (let loop () (match (select* (list stdin sock) '() '()) ((reads () ()) @@ -302,8 +315,13 @@ EXP never returns or calls 'primitive-exit' when it's done." "/var/guix/daemon-socket/socket")) "Connect to the remote build daemon listening on SOCKET-NAME over SESSION, an SSH session. Return a <store-connection> object." - (open-connection #:port (remote-daemon-channel session socket-name))) - + (guard (c ((store-connection-error? c) + ;; Raise a more focused error condition. + (raise (formatted-message + (G_ "failed to connect over SSH to daemon at '~a', socket ~a") + (session-get session 'host) + socket-name)))) + (open-connection #:port (remote-daemon-channel session socket-name)))) (define (store-import-channel session) "Return an output port to which archives to be exported to SESSION's store diff --git a/guix/status.scm b/guix/status.scm index 362ae2882c..1164c2a6e3 100644 --- a/guix/status.scm +++ b/guix/status.scm @@ -379,6 +379,8 @@ the current build phase." (G_ "building GHC package cache...")) ('ca-certificate-bundle (G_ "building CA certificate bundle...")) + ('emacs-subdirs + (G_ "listing Emacs sub-directories...")) ('glib-schemas (G_ "generating GLib schema cache...")) ('gtk-icon-themes @@ -552,12 +554,16 @@ substitutes being downloaded." (download-start download) #:transferred transferred)))))) (('substituter-succeeded item _ ...) - ;; If there are no jobs running, we already reported download completion - ;; so there's nothing left to do. - (unless (and (zero? (simultaneous-jobs status)) - (extended-build-trace-supported?)) - (format port (success (G_ "substitution of ~a complete")) item) - (newline port))) + (when (extended-build-trace-supported?) + ;; If there are no jobs running, we already reported download completion + ;; so there's nothing left to do. + (unless (zero? (simultaneous-jobs status)) + (format port (success (G_ "substitution of ~a complete")) item)) + + (when (and print-urls? (zero? (simultaneous-jobs status))) + ;; Leave a blank line after the "downloading ..." line and the + ;; progress bar (that's three lines in total). + (newline port)))) (('substituter-failed item _ ...) (format port (failure (G_ "substitution of ~a failed")) item) (newline port)) diff --git a/guix/store.scm b/guix/store.scm index 37ae6cfedd..9d706ae590 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -90,6 +90,7 @@ hash-algo build-mode + connect-to-daemon open-connection port->connection close-connection @@ -501,7 +502,10 @@ (define (connect-to-daemon uri) "Connect to the daemon at URI, a string that may be an actual URI or a file -name." +name, and return an input/output port. + +This is a low-level procedure that does not perform the initial handshake with +the daemon. Use 'open-connection' for that." (define (not-supported) (raise (condition (&store-connection-error (file uri) @@ -548,13 +552,16 @@ space on the file system so that the garbage collector can still operate, should the disk become full. When CPU-AFFINITY is true, it must be an integer corresponding to an OS-level CPU number to which the daemon's worker process for this connection will be pinned. Return a server object." + (define (handshake-error) + (raise (condition + (&store-connection-error (file (or port uri)) + (errno EPROTO)) + (&message (message "build daemon handshake failed"))))) + (guard (c ((nar-error? c) ;; One of the 'write-' or 'read-' calls below failed, but this is ;; really a connection error. - (raise (condition - (&store-connection-error (file (or port uri)) - (errno EPROTO)) - (&message (message "build daemon handshake failed")))))) + (handshake-error))) (let*-values (((port) (or port (connect-to-daemon uri))) ((output flush) @@ -562,32 +569,35 @@ for this connection will be pinned. Return a server object." (make-bytevector 8192)))) (write-int %worker-magic-1 port) (let ((r (read-int port))) - (and (= r %worker-magic-2) - (let ((v (read-int port))) - (and (= (protocol-major %protocol-version) - (protocol-major v)) - (begin - (write-int %protocol-version port) - (when (>= (protocol-minor v) 14) - (write-int (if cpu-affinity 1 0) port) - (when cpu-affinity - (write-int cpu-affinity port))) - (when (>= (protocol-minor v) 11) - (write-int (if reserve-space? 1 0) port)) - (letrec* ((built-in-builders - (delay (%built-in-builders conn))) - (conn - (%make-store-connection port - (protocol-major v) - (protocol-minor v) - output flush - (make-hash-table 100) - (make-hash-table 100) - vlist-null - built-in-builders))) - (let loop ((done? (process-stderr conn))) - (or done? (process-stderr conn))) - conn))))))))) + (unless (= r %worker-magic-2) + (handshake-error)) + + (let ((v (read-int port))) + (unless (= (protocol-major %protocol-version) + (protocol-major v)) + (handshake-error)) + + (write-int %protocol-version port) + (when (>= (protocol-minor v) 14) + (write-int (if cpu-affinity 1 0) port) + (when cpu-affinity + (write-int cpu-affinity port))) + (when (>= (protocol-minor v) 11) + (write-int (if reserve-space? 1 0) port)) + (letrec* ((built-in-builders + (delay (%built-in-builders conn))) + (conn + (%make-store-connection port + (protocol-major v) + (protocol-minor v) + output flush + (make-hash-table 100) + (make-hash-table 100) + vlist-null + built-in-builders))) + (let loop ((done? (process-stderr conn))) + (or done? (process-stderr conn))) + conn)))))) (define* (port->connection port #:key (version %protocol-version)) diff --git a/guix/swh.scm b/guix/swh.scm index 658bdedc66..3005323fd1 100644 --- a/guix/swh.scm +++ b/guix/swh.scm @@ -108,6 +108,7 @@ commit-id? + swh-download-directory swh-download)) ;;; Commentary: @@ -566,12 +567,6 @@ requested bundle cooking, waiting for completion...~%")) ;;; High-level interface. ;;; -(define (commit-id? reference) - "Return true if REFERENCE is likely a commit ID, false otherwise---e.g., if -it is a tag name. This is based on a simple heuristic so use with care!" - (and (= (string-length reference) 40) - (string-every char-set:hex-digit reference))) - (define (call-with-temporary-directory proc) ;FIXME: factorize "Call PROC with a name of a temporary directory; close the directory and delete it when leaving the dynamic extent of this call." @@ -585,6 +580,39 @@ delete it when leaving the dynamic extent of this call." (lambda () (false-if-exception (delete-file-recursively tmp-dir)))))) +(define* (swh-download-directory id output + #:key (log-port (current-error-port))) + "Download from Software Heritage the directory with the given ID, and +unpack it to OUTPUT. Return #t on success and #f on failure" + (call-with-temporary-directory + (lambda (directory) + (match (vault-fetch id 'directory #:log-port log-port) + (#f + (format log-port + "SWH: directory ~a could not be fetched from the vault~%" + id) + #f) + ((? port? input) + (let ((tar (open-pipe* OPEN_WRITE "tar" "-C" directory "-xzvf" "-"))) + (dump-port input tar) + (close-port input) + (let ((status (close-pipe tar))) + (unless (zero? status) + (error "tar extraction failure" status))) + + (match (scandir directory) + (("." ".." sub-directory) + (copy-recursively (string-append directory "/" sub-directory) + output + #:log (%make-void-port "w")) + #t)))))))) + +(define (commit-id? reference) + "Return true if REFERENCE is likely a commit ID, false otherwise---e.g., if +it is a tag name. This is based on a simple heuristic so use with care!" + (and (= (string-length reference) 40) + (string-every char-set:hex-digit reference))) + (define* (swh-download url reference output #:key (log-port (current-error-port))) "Download from Software Heritage a checkout of the Git tag or commit @@ -601,28 +629,7 @@ wait until it becomes available, which could take several minutes." (format log-port "SWH: found revision ~a with directory at '~a'~%" (revision-id revision) (swh-url (revision-directory-url revision))) - (call-with-temporary-directory - (lambda (directory) - (match (vault-fetch (revision-directory revision) 'directory - #:log-port log-port) - (#f - (format log-port - "SWH: directory ~a could not be fetched from the vault~%" - (revision-directory revision)) - #f) - ((? port? input) - (let ((tar (open-pipe* OPEN_WRITE "tar" "-C" directory "-xzvf" "-"))) - (dump-port input tar) - (close-port input) - (let ((status (close-pipe tar))) - (unless (zero? status) - (error "tar extraction failure" status))) - - (match (scandir directory) - (("." ".." sub-directory) - (copy-recursively (string-append directory "/" sub-directory) - output - #:log (%make-void-port "w")) - #t)))))))) + (swh-download-directory (revision-directory revision) output + #:log-port log-port)) (#f #f))) diff --git a/guix/ui.scm b/guix/ui.scm index 334dce2c68..e2cf2f1f5e 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -492,12 +492,11 @@ part." (lambda _ (setlocale LC_ALL "")) (lambda args - (display-hint (G_ "Consider installing the @code{glibc-utf8-locales} or -@code{glibc-locales} package and defining @code{GUIX_LOCPATH}, along these -lines: + (display-hint (G_ "Consider installing the @code{glibc-locales} package +and defining @code{GUIX_LOCPATH}, along these lines: @example -guix install glibc-utf8-locales +guix install glibc-locales export GUIX_LOCPATH=\"$HOME/.guix-profile/lib/locale\" @end example |