guix hash: Support several files.

* 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 <ludo@gnu.org>
This commit is contained in:
zimoun 2021-11-18 01:20:21 +01:00 committed by Ludovic Courtès
parent 155fc235b5
commit 6e08f07f20
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 35 additions and 20 deletions

View file

@ -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

View file

@ -3,6 +3,7 @@
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2018 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -149,27 +150,35 @@ (define (vcs-file? file stat)
(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)))))

View file

@ -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"