Toggle diff (283 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 9f1e4bf0f0..c2c68d313b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15321,7 +15321,12 @@ Invoking guix refresh
@item interactive
When a package signed with an unknown OpenPGP key is encountered, ask
-the user whether to download it or not. This is the default behavior.
+the user whether to download it or not.
+
+@item auto
+Automatically selects the @code{interactive} policy when the standard
+input is connected to a pseudo terminal (TTY), else @code{always}. This
+is the default behavior.
@end table
@item --key-server=@var{host}
diff --git a/etc/completion/fish/guix.fish b/etc/completion/fish/guix.fish
index e6c290256f..9e3b3211ea 100644
--- a/etc/completion/fish/guix.fish
+++ b/etc/completion/fish/guix.fish
@@ -284,7 +284,7 @@ complete -f -c guix -n '__fish_guix_using_command refresh' -l list-updaters -d '
complete -f -c guix -n '__fish_guix_using_command refresh' -l list-dependent -d 'list top-level dependent packages that would need to be rebuilt as a result of upgrading PACKAGE'
complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-server=" -d 'use HOST as the OpenPGP key server'
complete -f -c guix -n '__fish_guix_using_command refresh' -a "--gpg=" -d 'use COMMAND as the GnuPG 2.x command'
-complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY.' --exclusive --arguments "always never interactive"
+complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY.' --exclusive --arguments "always auto never interactive"
#### publish
set -l remotecommands port= listen= user= compression ttl= repl
@@ -321,7 +321,7 @@ set -l remotecommands import gnu nix pypi cpan hackage elpa gem cran crate texli
complete -f -c guix -n '__fish_guix_needs_command' -a import -d 'Run IMPORTER with ARGS'
##### import gnu
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a gnu -d 'Return a package declaration template for PACKAGE, a GNU package.'
-complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "never", and "interactive", which is also used when "key-download" is not specified.'
+complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "auto", "never", and "interactive", which is also used when "key-download" is not specified.'
##### import pypi
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a pypi -d 'Import and convert the PyPI package for PACKAGE-NAME.'
##### import cpan
diff --git a/etc/completion/zsh/_guix b/etc/completion/zsh/_guix
index 9b1f16c664..42b92475a9 100644
--- a/etc/completion/zsh/_guix
+++ b/etc/completion/zsh/_guix
@@ -507,7 +507,7 @@ _guix_list_installed_packages()
'--keyring=[use FILE as the keyring of upstream OpenPGP keys]:FILE:_files' \
'--key-server=[use HOST as the OpenPGP key server]:HOST_hosts' \
'--gpg=[use COMMAND as the GnuPG 2.x command]:COMMAND' \
- '--key-download=[handle missing OpenPGP keys according to POLICY:]:POLICY:(always interactive never)' \
+ '--key-download=[handle missing OpenPGP keys according to POLICY:]:POLICY:(always auto interactive never)' \
'--load-path=[prepend DIR to the package module search path]:DIR:_files -/' \
{-V,--version}'[display version information and exit]' \
'*:package:->packages'
diff --git a/guix/gnupg.scm b/guix/gnupg.scm
index 088bebc0de..ef9b71a2cb 100644
--- a/guix/gnupg.scm
+++ b/guix/gnupg.scm
@@ -2,7 +2,7 @@
;;; Copyright © 2010, 2011, 2013, 2014, 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
-;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021, 2025 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -26,6 +26,8 @@ (define-module (guix gnupg)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 i18n)
#:use-module (srfi srfi-1)
+ #:use-module ((srfi srfi-34) #:select (raise))
+ #:use-module (guix diagnostics)
#:use-module (guix i18n)
#:use-module ((guix utils) #:select (config-directory))
#:use-module ((guix build utils) #:select (mkdir-p))
@@ -201,7 +203,7 @@ (define* (gnupg-receive-keys fingerprint/key-id
(define* (gnupg-verify* sig file
#:key
- (key-download 'interactive)
+ (key-download 'auto)
server
(keyring (current-keyring)))
"Like `gnupg-verify', but try downloading the public key if it's missing.
@@ -210,9 +212,29 @@ (define* (gnupg-verify* sig file
'invalid-signature with a fingerprint if the signature is invalid.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'always', 'never', and 'interactive' (default). Return a
+values: 'auto', 'always', 'never', and 'interactive' The default policy is
+auto, which automatically selects the interactive policy when a TTY is
+connected to the standard input, or the always policy otherwise. Return a
fingerprint/user name pair on success and #f otherwise."
- (let ((status (gnupg-verify sig file)))
+ (let* ((interactive? (isatty? (current-input-port)))
+ ;; Validate or compute (in the case of 'auto) the KEY-DOWNLOAD
+ ;; argument.
+ (key-download (match key-download
+ ('auto (if interactive?
+ 'interactive
+ 'always))
+ ('interactive
+ (unless interactive?
+ (raise (formatted-message
+ (G_ "cannot use interactive policy\
+ without TTY input")))))
+ ((or 'always 'never)
+ key-download)
+ (_
+ (raise (formatted-message
+ (G_ "invalid key-download policy: ~a")
+ key-download)))))
+ (status (gnupg-verify sig file)))
(match (gnupg-status-good-signature? status)
((fingerprint . user)
(values 'valid-signature (cons fingerprint user)))
@@ -236,7 +258,10 @@ (define* (gnupg-verify* sig file
(format #t (G_ "Would you like to add this key \
to keyring '~a'?~%")
keyring)
- (read-line))))
+ (match (read-line)
+ ((? eof-object?)
+ (error "read-line unexpectedly returned #<eof>"))
+ (other other)))))
(string-match (locale-yes-regexp) answer)))
(case key-download
@@ -244,7 +269,7 @@ (define* (gnupg-verify* sig file
(values 'missing-key missing))
((always)
(download-and-try-again))
- (else
+ (else ;interactive
(if (receive?)
(download-and-try-again)
(values 'missing-key missing)))))))))
diff --git a/guix/import/gnu.scm b/guix/import/gnu.scm
index fb61332fb8..e68dc06824 100644
--- a/guix/import/gnu.scm
+++ b/guix/import/gnu.scm
@@ -1,7 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
-;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021, 2025 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -54,7 +54,7 @@ (define (preferred-archive-type release)
'("xz" "lz" "bz2" "tbz2" "gz" "tgz" "Z")))
(define* (gnu-package->sexp package release
- #:key (key-download 'interactive))
+ #:key (key-download 'auto))
"Return the 'package' sexp for the RELEASE (a <gnu-release>) of PACKAGE (a
<gnu-package>), or #f upon failure. Use KEY-DOWNLOAD as the OpenPGP key
download policy (see 'download-tarball' for details.)"
@@ -106,7 +106,7 @@ (define* (gnu-package->sexp package release
#f))))
(define* (gnu->guix-package name
- #:key (key-download 'interactive)
+ #:key (key-download 'auto)
#:allow-other-keys)
"Return the package declaration for NAME as an s-expression. Use
KEY-DOWNLOAD as the OpenPGP key download policy (see 'download-tarball' for
diff --git a/guix/scripts/import/gnu.scm b/guix/scripts/import/gnu.scm
index 344e363abe..93ab6043c7 100644
--- a/guix/scripts/import/gnu.scm
+++ b/guix/scripts/import/gnu.scm
@@ -35,7 +35,7 @@ (define-module (guix scripts import gnu)
;;;
(define %default-options
- '((key-download . interactive)))
+ '((key-download . auto)))
(define (show-help)
(display (G_ "Usage: guix import gnu [OPTION...] PACKAGE
@@ -44,8 +44,8 @@ (define (show-help)
(display (G_ "
--key-download=POLICY
handle missing OpenPGP keys according to POLICY:
- 'always', 'never', and 'interactive', which is also
- used when 'key-download' is not specified"))
+ 'auto' (default), 'always', 'never', and
+ 'interactive'"))
(newline)
(display (G_ "
-h, --help display this help and exit"))
@@ -66,7 +66,7 @@ (define %options
(option '("key-download") #t #f ;from (guix scripts refresh)
(lambda (opt name arg result)
(match arg
- ((or "interactive" "always" "never")
+ ((or "auto" "interactive" "always" "never")
(alist-cons 'key-download (string->symbol arg)
result))
(x
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index 8c72d0c545..6532feef25 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -10,7 +10,7 @@
;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
-;;; Copyright © 2023 Maxim Cournoyer maxim.cournoyer@gmail.com>
+;;; Copyright © 2023, 2025 Maxim Cournoyer maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -193,8 +193,9 @@ (define (show-help)
(display (G_ "
--key-download=POLICY
handle missing OpenPGP keys according to POLICY:
- 'always', 'never', and 'interactive', which is also
- used when 'key-download' is not specified"))
+ 'auto', 'always', 'never', and 'interactive'.
+ When left unspecified, the default policy is 'auto',
+ which automatically selects interactive or always."))
(newline)
(display (G_ "
-L, --load-path=DIR prepend DIR to the package module search path"))
@@ -364,12 +365,12 @@ (define (warn-no-updater package)
(package-name package)))
(define* (update-package store package version updaters
- #:key (key-download 'interactive) key-server
+ #:key (key-download 'auto) key-server
warn?)
"Update the source file that defines PACKAGE with the new version.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'interactive' (default), 'always', and 'never'. When WARN? is true,
-warn about packages that have no matching updater."
+values: 'auto' (default), interactive', 'always', and 'never'. When WARN? is
+true, warn about packages that have no matching updater."
(if (lookup-updater package updaters)
(let ((version output source
(package-update store package updaters
diff --git a/guix/upstream.scm b/guix/upstream.scm
index 62ba6c9d39..169d260c2d 100644
--- a/guix/upstream.scm
+++ b/guix/upstream.scm
@@ -314,14 +314,14 @@ (define (uncompressed-tarball name tarball)
#$output)))))
(define* (download-tarball store url signature-url
- #:key (key-download 'interactive) key-server)
+ #:key (key-download 'auto) key-server)
"Download the tarball at URL to the store; check its OpenPGP signature at
SIGNATURE-URL, unless SIGNATURE-URL is false. On success, return the tarball
file name; return #f on failure (network failure or authentication failure).
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'interactive' (default), 'always', and 'never'; KEY-SERVER specifies
-the OpenPGP key server where the key should be looked up."
+values: 'auto' (default), 'always', 'interactive' and 'never'; KEY-SERVER
+specifies the OpenPGP key server where the key should be looked up."
(let ((tarball (download-to-store store url)))
(if (not signature-url)
tarball
@@ -512,12 +512,12 @@ (define %method-updates
(define* (package-update store package
#:optional (updaters (force %updaters))
#:key (version #f)
- (key-download 'interactive) key-server)
+ (key-download 'auto) key-server)
"Return the new version, the file name of the new version tarball, and input
changes for PACKAGE; return #f (three values) when PACKAGE is up-to-date;
raise an error when the updater could not determine available releases.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'always', 'never', and 'interactive' (default).
+values: 'always', 'auto' (default), 'never', and 'interactive'.
When VERSION is specified, update PACKAGE to that version, even if that is a
downgrade."
base-commit: 220ef58440668c39ddf7c6434c0fbfc82d3dd507
--
2.48.1