[bug#78580,v2] 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 | 11 +++++++++--
guix/scripts/pull.scm | 42 ++++++++++++++++++++++++++++++++++--------
2 files changed, 43 insertions(+), 10 deletions(-)
base-commit: 096dedd0bb13523002c814b001429c2f65b6f10d
@@ -4656,8 +4656,15 @@ 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. The channel named @dfn{guix}
+is always pulled.
@table @code
@item --url=@var{url}
@@ -81,8 +81,13 @@ (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).
+The channel named 'guix' is always pulled.\n"))
(display (G_ "
-C, --channels=FILE deploy the channels defined in FILE"))
(display (G_ "
@@ -839,21 +844,41 @@ (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 (filter-channels channels names)
+ "Filter 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)))
+ (for-each (lambda (name)
+ (unless (member name available-names)
+ (warning (G_ "Channel '~a' not present in channel list~%")
+ name)))
+ names)
+ (filter (lambda (ch)
+ (member (channel-name ch)
+ ;; A channel named guix must always be present.
+ (cons* 'guix names)))
+ 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 +902,8 @@ (define-command (guix-pull . args)
(ensure-default-profile)
(honor-x509-certificates store)
- (let* ((channels (channel-list opts))
+ (let* ((channels (filter-channels (channel-list opts)
+ selected-channels))
(instances
(latest-channel-instances store channels
#:current-channels