Subject: [PATCH v3] scripts: archive: Check compatibility of command line options.

From: Simon Tournier <[email-masked]>
Date: Thu, 30 Nov 2023 11:46:13 +0100

Fixes <https://issues.guix.gnu.org/66358>.
Reported by Perry, Daniel J <[email-masked]>.

* guix/scripts/archive.scm (guix-archive)[compatible-option]: New procedure.
and use it.
* tests/guix-archive.sh: Test it.
---
 guix/scripts/archive.scm | 18 +++++++++++++++++-
 tests/guix-archive.sh    |  5 +++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index 2b5a55a23f..b9cf78f981 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020, 2021 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2020 Tobias Geerinckx-Rice <[email-masked]>
+;;; Copyright © 2023 Simon Tournier <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -375,8 +376,23 @@ (define-command (guix-archive . args)
           (loop (read-line port)
                 (cons line result)))))
 
+  (define* (compatible-option options #:key actions)
+  "Return the OPTIONS if it is compatible with the list of ACTIONS."
+  (let ((some-actions (filter (lambda (action)
+                                (assoc-ref options action))
+                              actions)))
+    (match some-actions
+      ((action)
+       options)
+      ((action other-actions ...)
+       (leave (G_ "the options ~{'~s' ~}are exclusive~%") some-actions))
+      (_
+       options))))
+
   (with-error-handling
-    (let ((opts (parse-command-line args %options (list %default-options))))
+    (let* ((opts (parse-command-line args %options (list %default-options)))
+           (opts (compatible-option opts
+                                    #:actions (list 'authorize 'export 'import))))
       (parameterize ((%graft? (assoc-ref opts 'graft?)))
         (cond ((assoc-ref opts 'generate-key)
                =>
diff --git a/tests/guix-archive.sh b/tests/guix-archive.sh
index 0866b5a4d8..08c07684ad 100644
--- a/tests/guix-archive.sh
+++ b/tests/guix-archive.sh
@@ -79,4 +79,9 @@ guix archive -t < "$archive" | grep "^r /share/guile.*/boot-9\.scm"
 
 echo foo | guix archive --authorize && false
 
+# Check incompatible command-line options
+guix archive --authorize --export --import && false
+guix archive --export guile-bootstrap --authorize > "$archive" && false
+guix archive --authorize --import < "$archive" && false
+
 exit 0

base-commit: cd46757c1a0f886848fbb6828c028dd2a2532767
-- 
2.41.0