[bug#78580] pull: allow filtering which channels to pull from the CLI

Message ID e6dd2ed103f3474b5c1f66d8391b910a4dd81d67.1748106755.git.sergio.pastorperez@gmail.com
State New
Headers
Series [bug#78580] pull: allow filtering which channels to pull from the CLI |

Commit Message

Sergio Pastor Pérez May 24, 2025, 5:12 p.m. UTC
  * guix/scripts/pull.scm (guix-pull): treat non-prefix CLI arguments as a list
of channels to pull.

Change-Id: I5d08c4b1cc84ab58a9c4e7600eb86468f92d10f0
---
 guix/scripts/pull.scm | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)


base-commit: 096dedd0bb13523002c814b001429c2f65b6f10d
  

Patch

diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm
index 76aed0b5cc..61a68b8d70 100644
--- a/guix/scripts/pull.scm
+++ b/guix/scripts/pull.scm
@@ -839,21 +839,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 +897,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