summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
Diffstat (limited to 'guix')
-rw-r--r--guix/android-repo-download.scm5
-rw-r--r--guix/build-system/asdf.scm18
-rw-r--r--guix/build/asdf-build-system.scm15
-rw-r--r--guix/build/download.scm84
-rw-r--r--guix/build/emacs-build-system.scm79
-rw-r--r--guix/ci.scm4
-rw-r--r--guix/cvs-download.scm12
-rw-r--r--guix/download.scm19
-rw-r--r--guix/hg-download.scm9
-rw-r--r--guix/import/pypi.scm4
-rw-r--r--guix/packages.scm5
-rw-r--r--guix/profiles.scm99
-rw-r--r--guix/scripts/perform-download.scm7
-rw-r--r--guix/scripts/system.scm1
-rw-r--r--guix/scripts/weather.scm29
-rw-r--r--guix/self.scm3
-rw-r--r--guix/ssh.scm30
-rw-r--r--guix/status.scm18
-rw-r--r--guix/store.scm72
-rw-r--r--guix/swh.scm65
-rw-r--r--guix/ui.scm7
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