guix package: '--list-available' can use data from the cache.

* gnu/packages.scm (fold-available-packages): New procedure.
* guix/scripts/package.scm (process-query): Use it instead of
'fold-packages'.
* tests/packages.scm ("fold-available-packages with/without cache"):
New test.
This commit is contained in:
Ludovic Courtès 2019-01-13 15:36:49 +01:00
parent ee8099f5b6
commit 0ea939fb79
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
3 changed files with 92 additions and 20 deletions

View File

@ -53,6 +53,7 @@
%default-package-module-path %default-package-module-path
fold-packages fold-packages
fold-available-packages
find-packages-by-name find-packages-by-name
find-package-locations find-package-locations
@ -182,6 +183,50 @@ flags."
directory)) directory))
%load-path))) %load-path)))
(define (fold-available-packages proc init)
"Fold PROC over the list of available packages. For each available package,
PROC is called along these lines:
(PROC NAME VERSION RESULT
#:outputs OUTPUTS
#:location LOCATION
)
PROC can use #:allow-other-keys to ignore the bits it's not interested in.
When a package cache is available, this procedure does not actually load any
package module."
(define cache
(load-package-cache (current-profile)))
(if (and cache (cache-is-authoritative?))
(vhash-fold (lambda (name vector result)
(match vector
(#(name version module symbol outputs
supported? deprecated?
file line column)
(proc name version result
#:outputs outputs
#:location (and file
(location file line column))
#:supported? supported?
#:deprecated? deprecated?))))
init
cache)
(fold-packages (lambda (package result)
(proc (package-name package)
(package-version package)
result
#:outputs (package-outputs package)
#:location (package-location package)
#:supported?
(->bool
(member (%current-system)
(package-supported-systems package)))
#:deprecated?
(->bool
(package-superseded package))))
init)))
(define* (fold-packages proc init (define* (fold-packages proc init
#:optional #:optional
(modules (all-modules (%package-module-path) (modules (all-modules (%package-module-path)

View File

@ -736,29 +736,34 @@ processed, #f otherwise."
(('list-available regexp) (('list-available regexp)
(let* ((regexp (and regexp (make-regexp* regexp))) (let* ((regexp (and regexp (make-regexp* regexp)))
(available (fold-packages (available (fold-available-packages
(lambda (p r) (lambda* (name version result
(let ((n (package-name p))) #:key outputs location
(if (and (supported-package? p) supported? superseded?
(not (package-superseded p))) #:allow-other-keys)
(if regexp (if (and supported? (not superseded?))
(if (regexp-exec regexp n) (if regexp
(cons p r) (if (regexp-exec regexp name)
r) (cons `(,name ,version
(cons p r)) ,outputs ,location)
r))) result)
result)
(cons `(,name ,version
,outputs ,location)
result))
result))
'()))) '())))
(leave-on-EPIPE (leave-on-EPIPE
(for-each (lambda (p) (for-each (match-lambda
(format #t "~a\t~a\t~a\t~a~%" ((name version outputs location)
(package-name p) (format #t "~a\t~a\t~a\t~a~%"
(package-version p) name version
(string-join (package-outputs p) ",") (string-join outputs ",")
(location->string (package-location p)))) (location->string location))))
(sort available (sort available
(lambda (p1 p2) (match-lambda*
(string<? (package-name p1) (((name1 . _) (name2 . _))
(package-name p2)))))) (string<? name1 name2))))))
#t)) #t))
(('search _) (('search _)

View File

@ -995,6 +995,28 @@
((one) ((one)
(eq? one guile-2.0)))) (eq? one guile-2.0))))
(test-assert "fold-available-packages with/without cache"
(let ()
(define no-cache
(fold-available-packages (lambda* (name version result #:rest rest)
(cons (cons* name version rest)
result))
'()))
(define from-cache
(call-with-temporary-directory
(lambda (cache)
(generate-package-cache cache)
(mock ((guix describe) current-profile (const cache))
(mock ((gnu packages) cache-is-authoritative? (const #t))
(fold-available-packages (lambda* (name version result
#:rest rest)
(cons (cons* name version rest)
result))
'()))))))
(lset= equal? no-cache from-cache)))
(test-assert "find-packages-by-name" (test-assert "find-packages-by-name"
(match (find-packages-by-name "hello") (match (find-packages-by-name "hello")
(((? (cut eq? hello <>))) #t) (((? (cut eq? hello <>))) #t)