packages: Add `package-field-location'.

* guix/packages.scm (package-field-location): New procedure.
* build-aux/sync-synopses.scm: Use it instead of `package-location'.
* tests/packages.scm ("package-field-location"): New test.
This commit is contained in:
Ludovic Courtès 2013-04-22 23:07:13 +02:00
parent b2a886f6c7
commit d66c70967f
3 changed files with 69 additions and 1 deletions

View File

@ -52,7 +52,7 @@
((package . descriptor) ((package . descriptor)
(let ((upstream (gnu-package-doc-summary descriptor)) (let ((upstream (gnu-package-doc-summary descriptor))
(downstream (package-synopsis package)) (downstream (package-synopsis package))
(loc (package-location package))) (loc (package-field-location package 'synopsis)))
(unless (and upstream (string=? upstream downstream)) (unless (and upstream (string=? upstream downstream))
(format (guix-warning-port) (format (guix-warning-port)
"~a: ~a: proposed synopsis: ~s~%" "~a: ~a: proposed synopsis: ~s~%"

View File

@ -28,6 +28,8 @@
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
#:use-module (srfi srfi-34) #:use-module (srfi srfi-34)
#:use-module (srfi srfi-35) #:use-module (srfi srfi-35)
#:use-module ((ice-9 rdelim) #:select (read-line))
#:use-module (ice-9 regex)
#:re-export (%current-system) #:re-export (%current-system)
#:export (origin #:export (origin
origin? origin?
@ -58,6 +60,7 @@
package-maintainers package-maintainers
package-properties package-properties
package-location package-location
package-field-location
package-transitive-inputs package-transitive-inputs
package-transitive-propagated-inputs package-transitive-propagated-inputs
@ -159,6 +162,50 @@ representation."
package) package)
16))))) 16)))))
(define (package-field-location package field)
"Return an estimate of the source code location of the definition of FIELD
for PACKAGE."
(define field-rx
(make-regexp (string-append "\\("
(regexp-quote (symbol->string field))
"[[:blank:]]*")))
(define (seek-to-line port line)
(let ((line (- line 1)))
(let loop ()
(when (< (port-line port) line)
(unless (eof-object? (read-line port))
(loop))))))
(define (find-line port)
(let loop ((line (read-line port)))
(cond ((eof-object? line)
(values #f #f))
((regexp-exec field-rx line)
=>
(lambda (match)
;; At this point `port-line' points to the next line, so need
;; need to add one.
(values (port-line port)
(match:end match))))
(else
(loop (read-line port))))))
(match (package-location package)
(($ <location> file line column)
(catch 'system
(lambda ()
(call-with-input-file (search-path %load-path file)
(lambda (port)
(seek-to-line port line)
(let-values (((line column)
(find-line port)))
(if (and line column)
(location file line column)
(package-location package))))))
(lambda _
(package-location package))))
(_ #f)))
;; Error conditions. ;; Error conditions.

View File

@ -52,6 +52,27 @@
(home-page #f) (license #f) (home-page #f) (license #f)
extra-fields ...)) extra-fields ...))
(test-assert "package-field-location"
(let ()
(define (goto port line column)
(unless (and (= (port-column port) (- column 1))
(= (port-line port) (- line 1)))
(unless (eof-object? (get-char port))
(goto port line column))))
(define read-at
(match-lambda
(($ <location> file line column)
(call-with-input-file (search-path %load-path file)
(lambda (port)
(goto port line column)
(read port))))))
(and (equal? (read-at (package-field-location %bootstrap-guile 'name))
(package-name %bootstrap-guile))
(equal? (read-at (package-field-location %bootstrap-guile 'version))
(package-version %bootstrap-guile)))))
(test-assert "package-transitive-inputs" (test-assert "package-transitive-inputs"
(let* ((a (dummy-package "a")) (let* ((a (dummy-package "a"))
(b (dummy-package "b" (b (dummy-package "b"