~ruther/guix-local

6c365eca6dafca37f0ac34d55221bcf197df49a3 — Nikita Karetnikov 13 years ago bfda299
Add 'guix hash'.

* guix/scripts/hash.scm: New file.
* Makefile.am (MODULES): Add it.
* po/POTFILES.in: Add it.
* doc/guix.texi (Invoking guix hash): New node.
  (Defining Packages): Add a cross-reference to the 'Invoking guix
  hash' node.
4 files changed, 157 insertions(+), 2 deletions(-)

M Makefile.am
M doc/guix.texi
A guix/scripts/hash.scm
M po/POTFILES.in
M Makefile.am => Makefile.am +1 -0
@@ 30,6 30,7 @@ MODULES =					\
  guix/scripts/import.scm			\
  guix/scripts/package.scm			\
  guix/scripts/gc.scm				\
  guix/scripts/hash.scm				\
  guix/scripts/pull.scm				\
  guix/scripts/substitute-binary.scm		\
  guix/base32.scm				\

M doc/guix.texi => doc/guix.texi +35 -2
@@ 814,8 814,9 @@ the GNU mirrors defined in @code{(guix download)}.
The @code{sha256} field specifies the expected SHA256 hash of the file
being downloaded.  It is mandatory, and allows Guix to check the
integrity of the file.  The @code{(base32 @dots{})} form introduces the
base32 representation of the hash.  A convenient way to obtain this
information is with the @code{guix download} tool.
base32 representation of the hash.  You can obtain this information with
the @code{guix hash} (@pxref{Invoking guix hash}) and @code{guix
download} tools.

@item
@cindex GNU Build System


@@ 1094,6 1095,7 @@ space.

@menu
* Invoking guix build:: Building packages from the command line.
* Invoking guix hash:: Computing the cryptographic hash of a file.
@end menu

@node Invoking guix build


@@ 1189,6 1191,37 @@ the @code{package-derivation} procedure of the @code{(guix packages)}
module, and to the @code{build-derivations} procedure of the @code{(guix
store)} module.

@node Invoking guix hash
@section Invoking @command{guix hash}

The @command{guix hash} command allows to check the integrity 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
used in the definition of a package (@pxref{Defining Packages}).

The general syntax is:

@example
guix hash @var{option} @var{file}
@end example

@command{guix hash} has the following option:

@table @code

@item --format=@var{fmt}
@itemx -f @var{fmt}
Write the hash in the given format.

Supported formats: @code{nix-base32}, @code{base32}, @code{base16}
(@code{hex} and @code{hexadecimal} can be used as well).

If the @option{--format} option is not specified, @command{guix hash}
will output the hash in @code{nix-base32}.  This representation is used
in the definitions of packages.

@end table

@c *********************************************************************
@node GNU Distribution
@chapter GNU Distribution

A guix/scripts/hash.scm => guix/scripts/hash.scm +120 -0
@@ 0,0 1,120 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix scripts hash)
    #:use-module (guix base32)
    #:use-module (guix ui)
    #:use-module (guix utils)
    #:use-module (rnrs io ports)
    #:use-module (rnrs files)
    #:use-module (ice-9 match)
    #:use-module (srfi srfi-1)
    #:use-module (srfi srfi-26)
    #:use-module (srfi srfi-37)
    #:export (guix-hash))


;;;
;;; Command-line options.
;;;

(define %default-options
  ;; Alist of default option values.
  `((format . ,bytevector->nix-base32-string)))

(define (show-help)
  (display (_ "Usage: guix hash [OPTION] FILE
Return the cryptographic hash of FILE.

Supported formats: 'nix-base32' (default), 'base32', and 'base16'
('hex' and 'hexadecimal' can be used as well).\n"))
  (format #t (_ "
  -f, --format=FMT       write the hash in the given format"))
  (newline)
  (display (_ "
  -h, --help             display this help and exit"))
  (display (_ "
  -V, --version          display version information and exit"))
  (newline)
  (show-bug-report-information))

(define %options
  ;; Specification of the command-line options.
  (list (option '(#\f "format") #t #f
                (lambda (opt name arg result)
                  (define fmt-proc
                    (match arg
                      ("nix-base32"
                       bytevector->nix-base32-string)
                      ("base32"
                       bytevector->base32-string)
                      ((or "base16" "hex" "hexadecimal")
                       bytevector->base16-string)
                      (x
                       (leave (_ "unsupported hash format: ~a~%")
                              arg))))

                  (alist-cons 'format fmt-proc
                              (alist-delete 'format result))))

        (option '(#\h "help") #f #f
                (lambda args
                  (show-help)
                  (exit 0)))
        (option '(#\V "version") #f #f
                (lambda args
                  (show-version-and-exit "guix hash")))))



;;;
;;; Entry point.
;;;

(define (guix-hash . args)
  (define (parse-options)
    ;; Return the alist of option values.
    (args-fold args %options
               (lambda (opt name arg result)
                 (leave (_ "unrecognized option: ~a~%")
                        name))
               (lambda (arg result)
                 (alist-cons 'argument arg result))
               %default-options))

    (let* ((opts (parse-options))
           (args (filter-map (match-lambda
                              (('argument . value)
                               value)
                              (_ #f))
                             (reverse opts)))
           (fmt  (assq-ref opts 'format)))

      (match args
        ((file)
         (catch 'system-error
           (lambda ()
             (format #t "~a~%"
                     (call-with-input-file file
                       (compose fmt sha256 get-bytevector-all))))
           (lambda args
             (leave (_ "~a~%")
                    (strerror (system-error-errno args))))))
        (_
         (leave (_ "wrong number of arguments~%"))))))

M po/POTFILES.in => po/POTFILES.in +1 -0
@@ 8,6 8,7 @@ guix/scripts/build.scm
guix/scripts/download.scm
guix/scripts/package.scm
guix/scripts/gc.scm
guix/scripts/hash.scm
guix/scripts/pull.scm
guix/gnu-maintenance.scm
guix/ui.scm