diff options
| -rw-r--r-- | gnu/packages.scm | 45 | ||||
| -rw-r--r-- | guix/scripts/package.scm | 45 | ||||
| -rw-r--r-- | tests/packages.scm | 22 |
3 files changed, 92 insertions, 20 deletions
diff --git a/gnu/packages.scm b/gnu/packages.scm index cf655e74480..a1814205f93 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | %default-package-module-path | 53 | %default-package-module-path |
| 54 | 54 | ||
| 55 | fold-packages | 55 | fold-packages |
| 56 | fold-available-packages | ||
| 56 | 57 | ||
| 57 | find-packages-by-name | 58 | find-packages-by-name |
| 58 | find-package-locations | 59 | find-package-locations |
| @@ -182,6 +183,50 @@ flags." | |||
| 182 | directory)) | 183 | directory)) |
| 183 | %load-path))) | 184 | %load-path))) |
| 184 | 185 | ||
| 186 | (define (fold-available-packages proc init) | ||
| 187 | "Fold PROC over the list of available packages. For each available package, | ||
| 188 | PROC is called along these lines: | ||
| 189 | |||
| 190 | (PROC NAME VERSION RESULT | ||
| 191 | #:outputs OUTPUTS | ||
| 192 | #:location LOCATION | ||
| 193 | …) | ||
| 194 | |||
| 195 | PROC can use #:allow-other-keys to ignore the bits it's not interested in. | ||
| 196 | When a package cache is available, this procedure does not actually load any | ||
| 197 | package module." | ||
| 198 | (define cache | ||
| 199 | (load-package-cache (current-profile))) | ||
| 200 | |||
| 201 | (if (and cache (cache-is-authoritative?)) | ||
| 202 | (vhash-fold (lambda (name vector result) | ||
| 203 | (match vector | ||
| 204 | (#(name version module symbol outputs | ||
| 205 | supported? deprecated? | ||
| 206 | file line column) | ||
| 207 | (proc name version result | ||
| 208 | #:outputs outputs | ||
| 209 | #:location (and file | ||
| 210 | (location file line column)) | ||
| 211 | #:supported? supported? | ||
| 212 | #:deprecated? deprecated?)))) | ||
| 213 | init | ||
| 214 | cache) | ||
| 215 | (fold-packages (lambda (package result) | ||
| 216 | (proc (package-name package) | ||
| 217 | (package-version package) | ||
| 218 | result | ||
| 219 | #:outputs (package-outputs package) | ||
| 220 | #:location (package-location package) | ||
| 221 | #:supported? | ||
| 222 | (->bool | ||
| 223 | (member (%current-system) | ||
| 224 | (package-supported-systems package))) | ||
| 225 | #:deprecated? | ||
| 226 | (->bool | ||
| 227 | (package-superseded package)))) | ||
| 228 | init))) | ||
| 229 | |||
| 185 | (define* (fold-packages proc init | 230 | (define* (fold-packages proc init |
| 186 | #:optional | 231 | #:optional |
| 187 | (modules (all-modules (%package-module-path) | 232 | (modules (all-modules (%package-module-path) |
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index e9bed0be1ed..a633d2ee6d6 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm | |||
| @@ -736,29 +736,34 @@ processed, #f otherwise." | |||
| 736 | 736 | ||
| 737 | (('list-available regexp) | 737 | (('list-available regexp) |
| 738 | (let* ((regexp (and regexp (make-regexp* regexp))) | 738 | (let* ((regexp (and regexp (make-regexp* regexp))) |
| 739 | (available (fold-packages | 739 | (available (fold-available-packages |
| 740 | (lambda (p r) | 740 | (lambda* (name version result |
| 741 | (let ((n (package-name p))) | 741 | #:key outputs location |
| 742 | (if (and (supported-package? p) | 742 | supported? superseded? |
| 743 | (not (package-superseded p))) | 743 | #:allow-other-keys) |
| 744 | (if regexp | 744 | (if (and supported? (not superseded?)) |
| 745 | (if (regexp-exec regexp n) | 745 | (if regexp |
| 746 | (cons p r) | 746 | (if (regexp-exec regexp name) |
| 747 | r) | 747 | (cons `(,name ,version |
| 748 | (cons p r)) | 748 | ,outputs ,location) |
| 749 | r))) | 749 | result) |
| 750 | result) | ||
| 751 | (cons `(,name ,version | ||
| 752 | ,outputs ,location) | ||
| 753 | result)) | ||
| 754 | result)) | ||
| 750 | '()))) | 755 | '()))) |
| 751 | (leave-on-EPIPE | 756 | (leave-on-EPIPE |
| 752 | (for-each (lambda (p) | 757 | (for-each (match-lambda |
| 753 | (format #t "~a\t~a\t~a\t~a~%" | 758 | ((name version outputs location) |
| 754 | (package-name p) | 759 | (format #t "~a\t~a\t~a\t~a~%" |
| 755 | (package-version p) | 760 | name version |
| 756 | (string-join (package-outputs p) ",") | 761 | (string-join outputs ",") |
| 757 | (location->string (package-location p)))) | 762 | (location->string location)))) |
| 758 | (sort available | 763 | (sort available |
| 759 | (lambda (p1 p2) | 764 | (match-lambda* |
| 760 | (string<? (package-name p1) | 765 | (((name1 . _) (name2 . _)) |
| 761 | (package-name p2)))))) | 766 | (string<? name1 name2)))))) |
| 762 | #t)) | 767 | #t)) |
| 763 | 768 | ||
| 764 | (('search _) | 769 | (('search _) |
diff --git a/tests/packages.scm b/tests/packages.scm index 8aa117a2e76..ed635d90116 100644 --- a/tests/packages.scm +++ b/tests/packages.scm | |||
| @@ -995,6 +995,28 @@ | |||
| 995 | ((one) | 995 | ((one) |
| 996 | (eq? one guile-2.0)))) | 996 | (eq? one guile-2.0)))) |
| 997 | 997 | ||
| 998 | (test-assert "fold-available-packages with/without cache" | ||
| 999 | (let () | ||
| 1000 | (define no-cache | ||
| 1001 | (fold-available-packages (lambda* (name version result #:rest rest) | ||
| 1002 | (cons (cons* name version rest) | ||
| 1003 | result)) | ||
| 1004 | '())) | ||
| 1005 | |||
| 1006 | (define from-cache | ||
| 1007 | (call-with-temporary-directory | ||
| 1008 | (lambda (cache) | ||
| 1009 | (generate-package-cache cache) | ||
| 1010 | (mock ((guix describe) current-profile (const cache)) | ||
| 1011 | (mock ((gnu packages) cache-is-authoritative? (const #t)) | ||
| 1012 | (fold-available-packages (lambda* (name version result | ||
| 1013 | #:rest rest) | ||
| 1014 | (cons (cons* name version rest) | ||
| 1015 | result)) | ||
| 1016 | '())))))) | ||
| 1017 | |||
| 1018 | (lset= equal? no-cache from-cache))) | ||
| 1019 | |||
| 998 | (test-assert "find-packages-by-name" | 1020 | (test-assert "find-packages-by-name" |
| 999 | (match (find-packages-by-name "hello") | 1021 | (match (find-packages-by-name "hello") |
| 1000 | (((? (cut eq? hello <>))) #t) | 1022 | (((? (cut eq? hello <>))) #t) |
