From 6e08f07f2032cd85cd67beadf7a91b5c26d0619d Mon Sep 17 00:00:00 2001 From: zimoun Date: Thu, 18 Nov 2021 01:20:21 +0100 Subject: guix hash: Support several files. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * guix/scripts/hash.scm (guix-hash): Allow several files. [file-hash]: Catch system-error. [formatted-hash]: New procedure. * tests/guix-hash.sh: Add test. * doc/guix.texi (Invoking guix hash): Mention "one or more files". Co-authored-by: Ludovic Courtès --- doc/guix.texi | 4 ++-- guix/scripts/hash.scm | 45 +++++++++++++++++++++++++++------------------ tests/guix-hash.sh | 6 ++++++ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 7b1a64deb9..f531985ee7 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -11713,13 +11713,13 @@ store. @cindex @command{guix hash} The @command{guix hash} command computes the hash of a file. It is primarily a convenience tool for anyone contributing to the -distribution: it computes the cryptographic hash of a file, which can be +distribution: it computes the cryptographic hash of one or more files, which can be used in the definition of a package (@pxref{Defining Packages}). The general syntax is: @example -guix hash @var{option} @var{file} +guix hash @var{option} @var{file} ... @end example When @var{file} is @code{-} (a hyphen), @command{guix hash} computes the diff --git a/guix/scripts/hash.scm b/guix/scripts/hash.scm index b8622373cc..d3b293d02e 100644 --- a/guix/scripts/hash.scm +++ b/guix/scripts/hash.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2013 Nikita Karetnikov ;;; Copyright © 2016 Jan Nieuwenhuizen ;;; Copyright © 2018 Tim Gesthuizen +;;; Copyright © 2021 Simon Tournier ;;; ;;; This file is part of GNU Guix. ;;; @@ -149,27 +150,35 @@ and 'base16' ('hex' and 'hexadecimal' can be used as well).\n")) (define (file-hash file) ;; Compute the hash of FILE. ;; Catch and gracefully report possible '&nar-error' conditions. - (with-error-handling - (if (assoc-ref opts 'recursive?) + (if (assoc-ref opts 'recursive?) + (with-error-handling (let-values (((port get-hash) (open-hash-port (assoc-ref opts 'hash-algorithm)))) (write-file file port #:select? select?) (force-output port) - (get-hash)) - (match file - ("-" (port-hash (assoc-ref opts 'hash-algorithm) - (current-input-port))) - (_ (call-with-input-file file - (cute port-hash (assoc-ref opts 'hash-algorithm) - <>))))))) + (get-hash))) + (catch 'system-error + (lambda _ + (call-with-input-file file + (cute port-hash (assoc-ref opts 'hash-algorithm) + <>))) + (lambda args + (leave (G_ "~a ~a~%") + file + (strerror (system-error-errno args))))))) + + (define (formatted-hash thing) + (match thing + ("-" (with-error-handling + (fmt (port-hash (assoc-ref opts 'hash-algorithm) + (current-input-port))))) + (_ + (fmt (file-hash thing))))) (match args - ((file) - (catch 'system-error - (lambda () - (format #t "~a~%" (fmt (file-hash file)))) - (lambda args - (leave (G_ "~a~%") - (strerror (system-error-errno args)))))) - (x - (leave (G_ "wrong number of arguments~%")))))) + (() + (leave (G_ "no arguments specified~%"))) + (_ + (for-each + (compose (cute format #t "~a~%" <>) formatted-hash) + args))))) diff --git a/tests/guix-hash.sh b/tests/guix-hash.sh index c4461fa955..1e9a0ec734 100644 --- a/tests/guix-hash.sh +++ b/tests/guix-hash.sh @@ -34,6 +34,12 @@ test `guix hash -f base32 /dev/null` = 4oymiquy7qobjgx36tejs35zeqt24qpemsnzgtfes test `guix hash -H sha512 -f hex /dev/null` = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e test `guix hash -H sha1 -f base64 /dev/null` = "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" +# Several files. +test "`guix hash /dev/null "$abs_top_srcdir/README"`" = "`guix hash /dev/null ; guix hash "$abs_top_srcdir/README"`" + +# Zero files. +! guix hash + ! guix hash -H abcd1234 /dev/null mkdir "$tmpdir" -- cgit v1.2.3