scripts: hash: Handle repository with different VCS folders.

Fixes <https://issues.guix.gnu.org/issue/65979>.

* guix/hash.scm (%vcs-directories): New variable.
(vcs-file?): Add optional argument for passing VCS kind of the
file/repository.
(file-hash*): Adjust accordingly.
(vcs-file-predicate): New procedure and export it.
* guix/scripts/hash.scm (guix-hash)[file-hash]: Use it.

Change-Id: I8e286c3426ddefd664dc3a471d5a09e309824faa
This commit is contained in:
Simon Tournier 2023-12-02 14:11:20 +01:00
parent ffdcef5f36
commit d007b64356
No known key found for this signature in database
GPG key ID: 92F1D22C608EE7E5
2 changed files with 34 additions and 11 deletions

View file

@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev> ;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be> ;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
;;; Copyright © 2023 Simon Tournier <zimon.toutoune@gmail.com>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -23,23 +24,45 @@
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
#:export (vcs-file? #:export (vcs-file?
vcs-file-predicate
file-hash*)) file-hash*))
(define (vcs-file? file stat) (define %vcs-directories
"Returns true if FILE is a version control system file." ;; Directory used for determining the kind of VCS.
(list ".bzr" ".git" ".hg" ".svn" "CVS"))
(define* (vcs-file? file stat
#:optional
(vcs-directories %vcs-directories))
"Return true if FILE matches a version control system from the list
VCSES-DIRECTORIES."
(case (stat:type stat) (case (stat:type stat)
((directory) ((directory)
(member (basename file) '(".bzr" ".git" ".hg" ".svn" "CVS"))) (member (basename file) vcs-directories))
((regular) ((regular)
;; Git sub-modules have a '.git' file that is a regular text file. (if (member ".git" vcs-directories)
(string=? (basename file) ".git")) ;; Git sub-modules have a '.git' file that is a regular text file.
(string=? (basename file) ".git")
#f))
(else (else
#f))) #f)))
(define (vcs-file-predicate directory)
"Return a two-argument procedure that returns true when version-control
metadata directories such as '.git' is found in DIRECTORY."
(define vcs-directories
(filter (lambda (vcs)
(file-exists? (in-vicinity directory vcs)))
%vcs-directories))
(lambda (file stat)
(vcs-file? file stat vcs-directories)))
(define* (file-hash* file #:key (define* (file-hash* file #:key
(algorithm (hash-algorithm sha256)) (algorithm (hash-algorithm sha256))
(recursive? 'auto) (recursive? 'auto)
(select? (negate vcs-file?))) (select? (negate (lambda (file stat)
(vcs-file? file stat)))))
"Compute the hash of FILE with ALGORITHM. "Compute the hash of FILE with ALGORITHM.
Symbolic links are only dereferenced if RECURSIVE? is false. Symbolic links are only dereferenced if RECURSIVE? is false.

View file

@ -3,7 +3,7 @@
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2018 Tim Gesthuizen <tim.gesthuizen@yahoo.de> ;;; Copyright © 2018 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2021, 2023 Simon Tournier <zimon.toutoune@gmail.com>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev> ;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -181,9 +181,6 @@ use '--serializer=nar' instead~%")))
(_ #f)) (_ #f))
(reverse opts))) (reverse opts)))
(fmt (assq-ref opts 'format)) (fmt (assq-ref opts 'format))
(select? (if (assq-ref opts 'exclude-vcs?)
(negate vcs-file?)
(const #t)))
(algorithm (assoc-ref opts 'hash-algorithm)) (algorithm (assoc-ref opts 'hash-algorithm))
(serializer (assoc-ref opts 'serializer))) (serializer (assoc-ref opts 'serializer)))
@ -193,7 +190,10 @@ use '--serializer=nar' instead~%")))
(catch 'system-error (catch 'system-error
(lambda _ (lambda _
(with-error-handling (with-error-handling
(serializer file algorithm select?))) (let ((select? (if (assq-ref opts 'exclude-vcs?)
(negate (vcs-file-predicate file))
(const #t))))
(serializer file algorithm select?))))
(lambda args (lambda args
(leave (G_ "~a ~a~%") (leave (G_ "~a ~a~%")
file file