summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi12
-rw-r--r--guix/scripts/archive.scm45
-rw-r--r--tests/guix-archive.sh7
3 files changed, 62 insertions, 2 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 01980bf2d38..cb518780041 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4598,6 +4598,18 @@ unsafe.
4598The primary purpose of this operation is to facilitate inspection of 4598The primary purpose of this operation is to facilitate inspection of
4599archive contents coming from possibly untrusted substitute servers. 4599archive contents coming from possibly untrusted substitute servers.
4600 4600
4601@item --list
4602@itemx -t
4603Read a single-item archive as served by substitute servers
4604(@pxref{Substitutes}) and print the list of files it contains, as in
4605this example:
4606
4607@example
4608$ wget -O - \
4609 https://@value{SUBSTITUTE-SERVER}/nar/lzip/@dots{}-emacs-26.3 \
4610 | lzip -d | guix archive -t
4611@end example
4612
4601@end table 4613@end table
4602 4614
4603 4615
diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index 3318ef08891..2b4d39c7b80 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -21,7 +21,8 @@
21 #:use-module (guix utils) 21 #:use-module (guix utils)
22 #:use-module (guix combinators) 22 #:use-module (guix combinators)
23 #:use-module ((guix build utils) #:select (mkdir-p)) 23 #:use-module ((guix build utils) #:select (mkdir-p))
24 #:use-module ((guix serialization) #:select (restore-file)) 24 #:use-module ((guix serialization)
25 #:select (fold-archive restore-file))
25 #:use-module (guix store) 26 #:use-module (guix store)
26 #:use-module ((guix status) #:select (with-status-verbosity)) 27 #:use-module ((guix status) #:select (with-status-verbosity))
27 #:use-module (guix grafts) 28 #:use-module (guix grafts)
@@ -43,6 +44,7 @@
43 #:use-module (srfi srfi-26) 44 #:use-module (srfi srfi-26)
44 #:use-module (srfi srfi-37) 45 #:use-module (srfi srfi-37)
45 #:use-module (ice-9 binary-ports) 46 #:use-module (ice-9 binary-ports)
47 #:use-module (rnrs bytevectors)
46 #:export (guix-archive 48 #:export (guix-archive
47 options->derivations+files)) 49 options->derivations+files))
48 50
@@ -76,6 +78,8 @@ Export/import one or more packages from/to the store.\n"))
76 --missing print the files from stdin that are missing")) 78 --missing print the files from stdin that are missing"))
77 (display (G_ " 79 (display (G_ "
78 -x, --extract=DIR extract the archive on stdin to DIR")) 80 -x, --extract=DIR extract the archive on stdin to DIR"))
81 (display (G_ "
82 -t, --list list the files in the archive on stdin"))
79 (newline) 83 (newline)
80 (display (G_ " 84 (display (G_ "
81 --generate-key[=PARAMETERS] 85 --generate-key[=PARAMETERS]
@@ -137,6 +141,9 @@ Export/import one or more packages from/to the store.\n"))
137 (option '("extract" #\x) #t #f 141 (option '("extract" #\x) #t #f
138 (lambda (opt name arg result) 142 (lambda (opt name arg result)
139 (alist-cons 'extract arg result))) 143 (alist-cons 'extract arg result)))
144 (option '("list" #\t) #f #f
145 (lambda (opt name arg result)
146 (alist-cons 'list #t result)))
140 (option '("generate-key") #f #t 147 (option '("generate-key") #f #t
141 (lambda (opt name arg result) 148 (lambda (opt name arg result)
142 (catch 'gcry-error 149 (catch 'gcry-error
@@ -319,6 +326,40 @@ the input port."
319 (with-atomic-file-output %acl-file 326 (with-atomic-file-output %acl-file
320 (cut write-acl acl <>))))) 327 (cut write-acl acl <>)))))
321 328
329(define (list-contents port)
330 "Read a nar from PORT and print the list of files it contains to the current
331output port."
332 (define (consume-input port size)
333 (let ((bv (make-bytevector 32768)))
334 (let loop ((total size))
335 (unless (zero? total)
336 (let ((n (get-bytevector-n! port bv 0
337 (min total (bytevector-length bv)))))
338 (loop (- total n)))))))
339
340 (fold-archive (lambda (file type content result)
341 (match type
342 ('directory
343 (format #t "D ~a~%" file))
344 ('symlink
345 (format #t "S ~a -> ~a~%" file content))
346 ((or 'regular 'executable)
347 (match content
348 ((input . size)
349 (format #t "~a ~60a ~10h B~%"
350 (if (eq? type 'executable)
351 "x" "r")
352 file size)
353 (consume-input input size))))))
354 #t
355 port
356 ""))
357
358
359;;;
360;;; Entry point.
361;;;
362
322(define (guix-archive . args) 363(define (guix-archive . args)
323 (define (lines port) 364 (define (lines port)
324 ;; Return lines read from PORT. 365 ;; Return lines read from PORT.
@@ -353,6 +394,8 @@ the input port."
353 (missing (remove (cut valid-path? store <>) 394 (missing (remove (cut valid-path? store <>)
354 files))) 395 files)))
355 (format #t "~{~a~%~}" missing))) 396 (format #t "~{~a~%~}" missing)))
397 ((assoc-ref opts 'list)
398 (list-contents (current-input-port)))
356 ((assoc-ref opts 'extract) 399 ((assoc-ref opts 'extract)
357 => 400 =>
358 (lambda (target) 401 (lambda (target)
diff --git a/tests/guix-archive.sh b/tests/guix-archive.sh
index fdaeb98ad2b..4c5eea05cf1 100644
--- a/tests/guix-archive.sh
+++ b/tests/guix-archive.sh
@@ -1,5 +1,5 @@
1# GNU Guix --- Functional package management for GNU 1# GNU Guix --- Functional package management for GNU
2# Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> 2# Copyright © 2013, 2014, 2015, 2019 Ludovic Courtès <ludo@gnu.org>
3# 3#
4# This file is part of GNU Guix. 4# This file is part of GNU Guix.
5# 5#
@@ -74,5 +74,10 @@ guix archive -x "$tmpdir" < "$archive"
74test -x "$tmpdir/bin/guile" 74test -x "$tmpdir/bin/guile"
75test -d "$tmpdir/lib/guile" 75test -d "$tmpdir/lib/guile"
76 76
77# Check '--list'.
78guix archive -t < "$archive" | grep "^D /share/guile"
79guix archive -t < "$archive" | grep "^x /bin/guile"
80guix archive -t < "$archive" | grep "^r /share/guile.*/boot-9\.scm"
81
77if echo foo | guix archive --authorize 82if echo foo | guix archive --authorize
78then false; else true; fi 83then false; else true; fi