[bug#78580,v4] pull: allow filtering which channels to pull from the CLI
Commit Message
* guix/scripts/pull.scm (guix-pull): treat non-prefix CLI arguments as a list
of channels to pull.
Change-Id: I5d08c4b1cc84ab58a9c4e7600eb86468f92d10f0
---
doc/guix.texi | 10 ++++++--
guix/scripts/pull.scm | 53 ++++++++++++++++++++++++++++++++++++-------
2 files changed, 53 insertions(+), 10 deletions(-)
base-commit: 096dedd0bb13523002c814b001429c2f65b6f10d
@@ -4656,8 +4656,14 @@ Invoking guix pull
deleting /var/guix/profiles/per-user/charlie/current-guix-1-link
@end example
-The @command{guix pull} command is usually invoked with no arguments,
-but it supports the following options:
+The general syntax is:
+
+@example
+guix pull [@var{options}] [@var{CHANNELS}@dots{}]
+@end example
+
+The optional @var{channels} argument filters the list of pulled channels
+to those whose names match the given list.
@table @code
@item --url=@var{url}
@@ -81,8 +81,12 @@ (define %default-options
(validate-pull . ,ensure-forward-channel-update)))
(define (show-help)
- (display (G_ "Usage: guix pull [OPTION]...
-Download and deploy the latest version of Guix.\n"))
+ (display (G_ "Usage: guix pull [OPTION]... [CHANNELS...]
+Download and deploy the latest version of Guix.
+
+If CHANNELS are specified, pull only from channels with those names (e.g.:
+'guix pull rde nonguix' pulls only from the 'guix', 'rde', and 'nonguix'
+channels as defined in your channel configuration).\n"))
(display (G_ "
-C, --channels=FILE deploy the channels defined in FILE"))
(display (G_ "
@@ -839,21 +843,52 @@ (define (validate-cache-directory-ownership)
(define-command (guix-pull . args)
(synopsis "pull the latest revision of Guix")
- (define (no-arguments arg _)
- (leave (G_ "~A: extraneous argument~%") arg))
+ (define (unpin-channels channels current-channels names)
+ "Unpin CHANNELS whose name symbol is present in NAMES list.
+If NAMES is an empty list, don't filter anything. Warn when a name is not
+available in the channels list."
+ (if (null? names)
+ channels
+ (let ((available-names (map channel-name
+ channels))
+ (selected-channels (filter (lambda (ch)
+ (member (channel-name ch)
+ names))
+ channels)))
+ (for-each (lambda (name)
+ (unless (member name available-names)
+ (warning (G_ "Channel '~a' not present in channel list~%")
+ name)))
+ names)
+
+ (map (lambda (cur-ch)
+ (let ((selected-channel (find (lambda (ch)
+ (eq? (channel-name ch)
+ (channel-name cur-ch)))
+ selected-channels)))
+ ;; If the user selected this channel. Follow channel file
+ ;; specification. Otherwise, leave the channel pinned as
+ ;; defined by the current profile.
+ (or selected-channel
+ cur-ch)))
+ current-channels))))
(with-error-handling
(with-git-error-handling
(let* ((opts (parse-command-line args %options
- (list %default-options)
- #:argument-handler no-arguments))
+ (list %default-options)))
(substitutes? (assoc-ref opts 'substitutes?))
(dry-run? (assoc-ref opts 'dry-run?))
(profile (or (assoc-ref opts 'profile) %current-profile))
(current-channels (profile-channels profile))
(validate-pull (assoc-ref opts 'validate-pull))
(authenticate? (assoc-ref opts 'authenticate-channels?))
- (verify-certificate? (assoc-ref opts 'verify-certificate?)))
+ (verify-certificate? (assoc-ref opts 'verify-certificate?))
+ (selected-channels (filter-map
+ (match-lambda
+ (('argument . name) (string->symbol name))
+ (_ #f))
+ opts)))
(cond
((assoc-ref opts 'query)
(process-query opts profile))
@@ -877,7 +912,9 @@ (define-command (guix-pull . args)
(ensure-default-profile)
(honor-x509-certificates store)
- (let* ((channels (channel-list opts))
+ (let* ((channels (unpin-channels (channel-list opts)
+ current-channels
+ selected-channels))
(instances
(latest-channel-instances store channels
#:current-channels