diff options
| -rw-r--r-- | doc/guix.texi | 12 | ||||
| -rw-r--r-- | guix/scripts/archive.scm | 45 | ||||
| -rw-r--r-- | tests/guix-archive.sh | 7 |
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. | |||
| 4598 | The primary purpose of this operation is to facilitate inspection of | 4598 | The primary purpose of this operation is to facilitate inspection of |
| 4599 | archive contents coming from possibly untrusted substitute servers. | 4599 | archive contents coming from possibly untrusted substitute servers. |
| 4600 | 4600 | ||
| 4601 | @item --list | ||
| 4602 | @itemx -t | ||
| 4603 | Read a single-item archive as served by substitute servers | ||
| 4604 | (@pxref{Substitutes}) and print the list of files it contains, as in | ||
| 4605 | this 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 | ||
| 331 | output 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" | |||
| 74 | test -x "$tmpdir/bin/guile" | 74 | test -x "$tmpdir/bin/guile" |
| 75 | test -d "$tmpdir/lib/guile" | 75 | test -d "$tmpdir/lib/guile" |
| 76 | 76 | ||
| 77 | # Check '--list'. | ||
| 78 | guix archive -t < "$archive" | grep "^D /share/guile" | ||
| 79 | guix archive -t < "$archive" | grep "^x /bin/guile" | ||
| 80 | guix archive -t < "$archive" | grep "^r /share/guile.*/boot-9\.scm" | ||
| 81 | |||
| 77 | if echo foo | guix archive --authorize | 82 | if echo foo | guix archive --authorize |
| 78 | then false; else true; fi | 83 | then false; else true; fi |
