swh: Add a directory download procedure.

* guix/swh.scm (swh-directory-download): New procedure (with
implementation extracted from 'swh-download').
(swh-download): Use it to download the revision directory.
This commit is contained in:
Timothy Sample 2021-03-18 16:49:40 -04:00
parent 3802bb0ba0
commit 4f59ef3edb
No known key found for this signature in database
GPG key ID: 2AC6A5EC1C357C59

View file

@ -108,6 +108,7 @@ (define-module (guix swh)
commit-id? commit-id?
swh-download-directory
swh-download)) swh-download))
;;; Commentary: ;;; Commentary:
@ -558,12 +559,6 @@ (define* (vault-fetch id kind
;;; High-level interface. ;;; High-level interface.
;;; ;;;
(define (commit-id? reference)
"Return true if REFERENCE is likely a commit ID, false otherwise---e.g., if
it is a tag name. This is based on a simple heuristic so use with care!"
(and (= (string-length reference) 40)
(string-every char-set:hex-digit reference)))
(define (call-with-temporary-directory proc) ;FIXME: factorize (define (call-with-temporary-directory proc) ;FIXME: factorize
"Call PROC with a name of a temporary directory; close the directory and "Call PROC with a name of a temporary directory; close the directory and
delete it when leaving the dynamic extent of this call." delete it when leaving the dynamic extent of this call."
@ -577,6 +572,39 @@ (define (call-with-temporary-directory proc) ;FIXME: factorize
(lambda () (lambda ()
(false-if-exception (delete-file-recursively tmp-dir)))))) (false-if-exception (delete-file-recursively tmp-dir))))))
(define* (swh-download-directory id output
#:key (log-port (current-error-port)))
"Download from Software Heritage the directory with the given ID, and
unpack it to OUTPUT. Return #t on success and #f on failure"
(call-with-temporary-directory
(lambda (directory)
(match (vault-fetch id 'directory #:log-port log-port)
(#f
(format log-port
"SWH: directory ~a could not be fetched from the vault~%"
id)
#f)
((? port? input)
(let ((tar (open-pipe* OPEN_WRITE "tar" "-C" directory "-xzvf" "-")))
(dump-port input tar)
(close-port input)
(let ((status (close-pipe tar)))
(unless (zero? status)
(error "tar extraction failure" status)))
(match (scandir directory)
(("." ".." sub-directory)
(copy-recursively (string-append directory "/" sub-directory)
output
#:log (%make-void-port "w"))
#t))))))))
(define (commit-id? reference)
"Return true if REFERENCE is likely a commit ID, false otherwise---e.g., if
it is a tag name. This is based on a simple heuristic so use with care!"
(and (= (string-length reference) 40)
(string-every char-set:hex-digit reference)))
(define* (swh-download url reference output (define* (swh-download url reference output
#:key (log-port (current-error-port))) #:key (log-port (current-error-port)))
"Download from Software Heritage a checkout of the Git tag or commit "Download from Software Heritage a checkout of the Git tag or commit
@ -593,28 +621,7 @@ (define* (swh-download url reference output
(format log-port "SWH: found revision ~a with directory at '~a'~%" (format log-port "SWH: found revision ~a with directory at '~a'~%"
(revision-id revision) (revision-id revision)
(swh-url (revision-directory-url revision))) (swh-url (revision-directory-url revision)))
(call-with-temporary-directory (swh-download-directory (revision-directory revision) output
(lambda (directory) #:log-port log-port))
(match (vault-fetch (revision-directory revision) 'directory
#:log-port log-port)
(#f
(format log-port
"SWH: directory ~a could not be fetched from the vault~%"
(revision-directory revision))
#f)
((? port? input)
(let ((tar (open-pipe* OPEN_WRITE "tar" "-C" directory "-xzvf" "-")))
(dump-port input tar)
(close-port input)
(let ((status (close-pipe tar)))
(unless (zero? status)
(error "tar extraction failure" status)))
(match (scandir directory)
(("." ".." sub-directory)
(copy-recursively (string-append directory "/" sub-directory)
output
#:log (%make-void-port "w"))
#t))))))))
(#f (#f
#f))) #f)))