~ruther/guix-local

6e08f07f2032cd85cd67beadf7a91b5c26d0619d — zimoun 4 years ago 155fc23
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>
3 files changed, 35 insertions(+), 20 deletions(-)

M doc/guix.texi
M guix/scripts/hash.scm
M tests/guix-hash.sh
M doc/guix.texi => doc/guix.texi +2 -2
@@ 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

M guix/scripts/hash.scm => guix/scripts/hash.scm +27 -18
@@ 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 @@ 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)))))

M tests/guix-hash.sh => tests/guix-hash.sh +6 -0
@@ 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"