From bf9206d8edb06cc4c62fe5559504cf1518c2de9e Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Wed, 20 Nov 2019 12:08:56 +0100 Subject: package: Allow multiple '--manifest' options. * guix/scripts/package.scm (manifest-action): Remove. (%actions): Remove it. (load-manifest): New procedure. (process-actions): Handle 'manifest' options. Define 'files' from 'manifest' options. Define 'manifest' based on FILES. Define 'trans' to represent the final transaction. * tests/guix-package.sh: Test it. * doc/guix.texi (Invoking guix package): Mention --- doc/guix.texi | 3 ++- guix/scripts/package.scm | 50 +++++++++++++++++++++++++----------------------- tests/guix-package.sh | 13 +++++++++++++ 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 0dc49c3cda..7ef77015cc 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -2830,7 +2830,8 @@ $ guix package --upgrade . --do-not-upgrade emacs @cindex profile declaration @cindex profile manifest Create a new generation of the profile from the manifest object -returned by the Scheme code in @var{file}. +returned by the Scheme code in @var{file}. This option can be repeated +several times, in which case the manifests are concatenated. This allows you to @emph{declare} the profile's contents rather than constructing it through a sequence of @code{--install} and similar diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index bcd03a1df9..eb578f7642 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -832,32 +832,17 @@ (define* (delete-generations-action store profile pattern opts (unless dry-run? (delete-matching-generations store profile pattern))) -(define* (manifest-action store profile file opts - #:key dry-run?) - "Change PROFILE to contain the packages specified in FILE." - (let* ((user-module (make-user-module '((guix profiles) (gnu)))) - (manifest (load* file user-module)) - (bootstrap? (assoc-ref opts 'bootstrap?)) - (substitutes? (assoc-ref opts 'substitutes?)) - (allow-collisions? (assoc-ref opts 'allow-collisions?))) - (if dry-run? - (format #t (G_ "would install new manifest from '~a' with ~d entries~%") - file (length (manifest-entries manifest))) - (format #t (G_ "installing new manifest from '~a' with ~d entries~%") - file (length (manifest-entries manifest)))) - (build-and-use-profile store profile manifest - #:allow-collisions? allow-collisions? - #:bootstrap? bootstrap? - #:use-substitutes? substitutes? - #:dry-run? dry-run?))) +(define (load-manifest file) + "Load the user-profile manifest (Scheme code) from FILE and return it." + (let ((user-module (make-user-module '((guix profiles) (gnu))))) + (load* file user-module))) (define %actions ;; List of actions that may be processed. The car of each pair is the ;; action's symbol in the option list; the cdr is the action's procedure. `((roll-back? . ,roll-back-action) (switch-generation . ,switch-generation-action) - (delete-generations . ,delete-generations-action) - (manifest . ,manifest-action))) + (delete-generations . ,delete-generations-action))) (define (process-actions store opts) "Process any install/remove/upgrade action from OPTS." @@ -896,7 +881,13 @@ (define (transform-entry entry) opts) ;; Then, process normal package removal/installation/upgrade. - (let* ((manifest (profile-manifest profile)) + (let* ((files (filter-map (match-lambda + (('manifest . file) file) + (_ #f)) + opts)) + (manifest (match files + (() (profile-manifest profile)) + (_ (concatenate-manifests (map load-manifest files))))) (step1 (options->removable opts manifest (manifest-transaction))) (step2 (options->installable opts manifest step1)) @@ -904,12 +895,23 @@ (define (transform-entry entry) (inherit step2) (install (map transform-entry (manifest-transaction-install step2))))) - (new (manifest-perform-transaction manifest step3))) + (new (manifest-perform-transaction manifest step3)) + (trans (if (null? files) + step3 + (fold manifest-transaction-install-entry + step3 + (manifest-entries manifest))))) (warn-about-old-distro) - (unless (manifest-transaction-null? step3) - (show-manifest-transaction store manifest step3 + (unless (manifest-transaction-null? trans) + ;; When '--manifest' is used, display information about TRANS as if we + ;; were starting from an empty profile. + (show-manifest-transaction store + (if (null? files) + manifest + (make-manifest '())) + trans #:dry-run? dry-run?) (build-and-use-profile store profile new #:allow-collisions? allow-collisions? diff --git a/tests/guix-package.sh b/tests/guix-package.sh index 7ad0699380..6d081d58be 100644 --- a/tests/guix-package.sh +++ b/tests/guix-package.sh @@ -394,6 +394,19 @@ guix package -I | grep guile test `guix package -I | wc -l` -eq 1 guix package --rollback --bootstrap +# Applying two manifests. +cat > "$module_dir/manifest2.scm"<manifest (list p)) +EOF +guix package --bootstrap \ + -m "$module_dir/manifest.scm" -m "$module_dir/manifest2.scm" +guix package -I | grep guile +guix package -I | grep eliug +test `guix package -I | wc -l` -eq 2 +guix package --rollback --bootstrap + # Applying a manifest file with inferior packages. cat > "$module_dir/manifest.scm"<