summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/packages.scm45
-rw-r--r--guix/scripts/package.scm45
-rw-r--r--tests/packages.scm22
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,
188PROC is called along these lines:
189
190 (PROC NAME VERSION RESULT
191 #:outputs OUTPUTS
192 #:location LOCATION
193 …)
194
195PROC can use #:allow-other-keys to ignore the bits it's not interested in.
196When a package cache is available, this procedure does not actually load any
197package 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)