summaryrefslogtreecommitdiff
path: root/gnu/packages.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-05-03 23:03:20 +0200
committerLudovic Courtès <ludo@gnu.org>2017-05-03 23:50:15 +0200
commitcd903ef7871170d3c4eced45418459d293ef48a7 (patch)
tree1a3bc718ba57704583a63595732220f31f5c0cf0 /gnu/packages.scm
parent1dc0a66591f4fb37fc0df2aec6d3b0b7e2046c70 (diff)
Add (guix discovery).
* guix/discovery.scm, tests/discovery.scm: New files. * gnu/packages.scm (scheme-files, file-name->module-name) (scheme-modules, all-package-modules): Remove. (fold-packages): Rewrite in terms of 'fold-module-public-variables'. * gnu/tests.scm: Use (guix discovery). * Makefile.am (MODULES): Add guix/discovery.scm. (SCM_TESTS): Add tests/discovery.scm.
Diffstat (limited to 'gnu/packages.scm')
-rw-r--r--gnu/packages.scm93
1 files changed, 8 insertions, 85 deletions
diff --git a/gnu/packages.scm b/gnu/packages.scm
index 08f1340612d..57907155fb4 100644
--- a/gnu/packages.scm
+++ b/gnu/packages.scm
@@ -24,12 +24,11 @@
24 #:use-module (guix packages) 24 #:use-module (guix packages)
25 #:use-module (guix ui) 25 #:use-module (guix ui)
26 #:use-module (guix utils) 26 #:use-module (guix utils)
27 #:use-module (guix discovery)
27 #:use-module (guix memoization) 28 #:use-module (guix memoization)
28 #:use-module (guix combinators)
29 #:use-module ((guix build utils) 29 #:use-module ((guix build utils)
30 #:select ((package-name->name+version 30 #:select ((package-name->name+version
31 . hyphen-separated-name->name+version))) 31 . hyphen-separated-name->name+version)))
32 #:use-module (ice-9 ftw)
33 #:use-module (ice-9 vlist) 32 #:use-module (ice-9 vlist)
34 #:use-module (ice-9 match) 33 #:use-module (ice-9 match)
35 #:use-module (srfi srfi-1) 34 #:use-module (srfi srfi-1)
@@ -48,7 +47,6 @@
48 %package-module-path 47 %package-module-path
49 48
50 fold-packages 49 fold-packages
51 scheme-modules ;XXX: for lack of a better place
52 50
53 find-packages-by-name 51 find-packages-by-name
54 find-best-packages-by-name 52 find-best-packages-by-name
@@ -140,92 +138,17 @@ for system '~a'")
140 directory)) 138 directory))
141 %load-path))) 139 %load-path)))
142 140
143(define* (scheme-files directory)
144 "Return the list of Scheme files found under DIRECTORY, recursively. The
145returned list is sorted in alphabetical order."
146
147 ;; Sort entries so that 'fold-packages' works in a deterministic fashion
148 ;; regardless of details of the underlying file system.
149 (sort (file-system-fold (const #t) ; enter?
150 (lambda (path stat result) ; leaf
151 (if (string-suffix? ".scm" path)
152 (cons path result)
153 result))
154 (lambda (path stat result) ; down
155 result)
156 (lambda (path stat result) ; up
157 result)
158 (const #f) ; skip
159 (lambda (path stat errno result)
160 (warning (G_ "cannot access `~a': ~a~%")
161 path (strerror errno))
162 result)
163 '()
164 directory
165 stat)
166 string<?))
167
168(define file-name->module-name
169 (let ((not-slash (char-set-complement (char-set #\/))))
170 (lambda (file)
171 "Return the module name (a list of symbols) corresponding to FILE."
172 (map string->symbol
173 (string-tokenize (string-drop-right file 4) not-slash)))))
174
175(define* (scheme-modules directory #:optional sub-directory)
176 "Return the list of Scheme modules available under DIRECTORY.
177Optionally, narrow the search to SUB-DIRECTORY."
178 (define prefix-len
179 (string-length directory))
180
181 (filter-map (lambda (file)
182 (let* ((file (substring file prefix-len))
183 (module (file-name->module-name file)))
184 (catch #t
185 (lambda ()
186 (resolve-interface module))
187 (lambda args
188 ;; Report the error, but keep going.
189 (warn-about-load-error module args)
190 #f))))
191 (scheme-files (if sub-directory
192 (string-append directory "/" sub-directory)
193 directory))))
194
195(define* (all-package-modules #:optional (path (%package-module-path)))
196 "Return the list of package modules found in PATH, a list of directories to
197search."
198 (fold-right (lambda (spec result)
199 (match spec
200 ((? string? directory)
201 (append (scheme-modules directory) result))
202 ((directory . sub-directory)
203 (append (scheme-modules directory sub-directory)
204 result))))
205 '()
206 path))
207
208(define (fold-packages proc init) 141(define (fold-packages proc init)
209 "Call (PROC PACKAGE RESULT) for each available package, using INIT as 142 "Call (PROC PACKAGE RESULT) for each available package, using INIT as
210the initial value of RESULT. It is guaranteed to never traverse the 143the initial value of RESULT. It is guaranteed to never traverse the
211same package twice." 144same package twice."
212 (identity ; discard second return value 145 (fold-module-public-variables (lambda (object result)
213 (fold2 (lambda (module result seen) 146 (if (and (package? object)
214 (fold2 (lambda (var result seen) 147 (not (hidden-package? object)))
215 (if (and (package? var) 148 (proc object result)
216 (not (vhash-assq var seen)) 149 result))
217 (not (hidden-package? var))) 150 init
218 (values (proc var result) 151 (all-modules (%package-module-path))))
219 (vhash-consq var #t seen))
220 (values result seen)))
221 result
222 seen
223 (module-map (lambda (sym var)
224 (false-if-exception (variable-ref var)))
225 module)))
226 init
227 vlist-null
228 (all-package-modules))))
229 152
230(define find-packages-by-name 153(define find-packages-by-name
231 (let ((packages (delay 154 (let ((packages (delay