aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/scripts/package.scm145
1 files changed, 81 insertions, 64 deletions
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index 12a57efdab..6cf0b02ac3 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -624,6 +624,11 @@ doesn't need it."
(add-indirect-root store absolute))
+
+;;;
+;;; Queries and actions.
+;;;
+
(define (process-query opts)
"Process any query specified by OPTS. Return #t when a query was actually
processed, #f otherwise."
@@ -729,6 +734,58 @@ processed, #f otherwise."
(_ #f))))
+
+(define* (roll-back-action store profile arg opts
+ #:key dry-run?)
+ "Roll back PROFILE to its previous generation."
+ (unless dry-run?
+ (roll-back* store profile)))
+
+(define* (switch-generation-action store profile spec opts
+ #:key dry-run?)
+ "Switch PROFILE to the generation specified by SPEC."
+ (unless dry-run?
+ (let* ((number (string->number spec))
+ (number (and number
+ (case (string-ref spec 0)
+ ((#\+ #\-)
+ (relative-generation profile number))
+ (else number)))))
+ (if number
+ (switch-to-generation* profile number)
+ (leave (_ "cannot switch to generation '~a'~%") spec)))))
+
+(define* (delete-generations-action store profile pattern opts
+ #:key dry-run?)
+ "Delete PROFILE's generations that match PATTERN."
+ (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?)))
+ (if dry-run?
+ (format #t (_ "would install new manifest from '~a' with ~d entries~%")
+ file (length (manifest-entries manifest)))
+ (format #t (_ "installing new manifest from '~a' with ~d entries~%")
+ file (length (manifest-entries manifest))))
+ (build-and-use-profile store profile manifest
+ #:bootstrap? bootstrap?
+ #:use-substitutes? substitutes?
+ #:dry-run? dry-run?)))
+
+(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)))
+
;;;
;;; Entry point.
@@ -749,70 +806,30 @@ processed, #f otherwise."
(define substitutes? (assoc-ref opts 'substitutes?))
(define profile (or (assoc-ref opts 'profile) %current-profile))
- ;; First roll back if asked to.
- (cond ((and (assoc-ref opts 'roll-back?)
- (not dry-run?))
- (roll-back* (%store) profile)
- (process-actions (alist-delete 'roll-back? opts)))
- ((and (assoc-ref opts 'switch-generation)
- (not dry-run?))
- (for-each
- (match-lambda
- (('switch-generation . pattern)
- (let* ((number (string->number pattern))
- (number (and number
- (case (string-ref pattern 0)
- ((#\+ #\-)
- (relative-generation profile number))
- (else number)))))
- (if number
- (switch-to-generation* profile number)
- (leave (_ "cannot switch to generation '~a'~%")
- pattern)))
- (process-actions (alist-delete 'switch-generation opts)))
- (_ #f))
- opts))
- ((and (assoc-ref opts 'delete-generations)
- (not dry-run?))
- (for-each
- (match-lambda
- (('delete-generations . pattern)
- (delete-matching-generations (%store) profile pattern)
-
- (process-actions
- (alist-delete 'delete-generations opts)))
- (_ #f))
- opts))
- ((assoc-ref opts 'manifest)
- (let* ((file-name (assoc-ref opts 'manifest))
- (user-module (make-user-module '((guix profiles)
- (gnu))))
- (manifest (load* file-name user-module)))
- (if dry-run?
- (format #t (_ "would install new manifest from '~a' with ~d entries~%")
- file-name (length (manifest-entries manifest)))
- (format #t (_ "installing new manifest from '~a' with ~d entries~%")
- file-name (length (manifest-entries manifest))))
- (build-and-use-profile (%store) profile manifest
- #:bootstrap? bootstrap?
- #:use-substitutes? substitutes?
- #:dry-run? dry-run?)))
- (else
- (let* ((manifest (profile-manifest profile))
- (install (options->installable opts manifest))
- (remove (options->removable opts manifest))
- (transaction (manifest-transaction (install install)
- (remove remove)))
- (new (manifest-perform-transaction
- manifest transaction)))
-
- (unless (and (null? install) (null? remove))
- (show-manifest-transaction (%store) manifest transaction
- #:dry-run? dry-run?)
- (build-and-use-profile (%store) profile new
- #:bootstrap? bootstrap?
- #:use-substitutes? substitutes?
- #:dry-run? dry-run?))))))
+ ;; First, process roll-backs, generation removals, etc.
+ (for-each (match-lambda
+ ((key . arg)
+ (and=> (assoc-ref %actions key)
+ (lambda (proc)
+ (proc (%store) profile arg opts
+ #:dry-run? dry-run?)))))
+ opts)
+
+ ;; Then, process normal package installation/removal/upgrade.
+ (let* ((manifest (profile-manifest profile))
+ (install (options->installable opts manifest))
+ (remove (options->removable opts manifest))
+ (transaction (manifest-transaction (install install)
+ (remove remove)))
+ (new (manifest-perform-transaction manifest transaction)))
+
+ (unless (and (null? install) (null? remove))
+ (show-manifest-transaction (%store) manifest transaction
+ #:dry-run? dry-run?)
+ (build-and-use-profile (%store) profile new
+ #:bootstrap? bootstrap?
+ #:use-substitutes? substitutes?
+ #:dry-run? dry-run?))))
(let ((opts (parse-command-line args %options (list %default-options #f)
#:argument-handler handle-argument)))