ui: Factorize package specification parsing.

* guix/ui.scm (package-specification->name+version+output): New
  procedure.
* guix/scripts/package.scm (specification->package+output): Use it.
* tests/ui.scm ("package-specification->name+version+output"): New test.
This commit is contained in:
Ludovic Courtès 2013-11-01 16:57:48 +01:00
parent cc4ecc2d88
commit 2876b98925
3 changed files with 50 additions and 7 deletions

View File

@ -323,13 +323,8 @@ version; if SPEC does not specify an output, return OUTPUT."
(package-full-name p)
sub-drv)))
(let*-values (((name sub-drv)
(match (string-rindex spec #\:)
(#f (values spec output))
(colon (values (substring spec 0 colon)
(substring spec (+ 1 colon))))))
((name version)
(package-name->name+version name)))
(let-values (((name version sub-drv)
(package-specification->name+version+output spec)))
(match (find-best-packages-by-name name version)
((p)
(values p (ensure-output p sub-drv)))

View File

@ -52,6 +52,7 @@
fill-paragraph
string->recutils
package->recutils
package-specification->name+version+output
string->generations
string->duration
args-fold*
@ -358,6 +359,11 @@ converted to a space; sequences of more than one line break are preserved."
((_ _ chars)
(list->string (reverse chars)))))
;;;
;;; Packages.
;;;
(define (string->recutils str)
"Return a version of STR where newlines have been replaced by newlines
followed by \"+ \", which makes for a valid multi-line field value in the
@ -472,6 +478,31 @@ following patterns: \"1d\", \"1w\", \"1m\"."
(hours->duration (* 24 30) match)))
(else #f)))
(define* (package-specification->name+version+output spec
#:optional (output "out"))
"Parse package specification SPEC and return three value: the specified
package name, version number (or #f), and output name (or OUTPUT). SPEC may
optionally contain a version number and an output name, as in these examples:
guile
guile-2.0.9
guile:debug
guile-2.0.9:debug
"
(let*-values (((name sub-drv)
(match (string-rindex spec #\:)
(#f (values spec output))
(colon (values (substring spec 0 colon)
(substring spec (+ 1 colon))))))
((name version)
(package-name->name+version name)))
(values name version sub-drv)))
;;;
;;; Command-line option processing.
;;;
(define (args-fold* options unrecognized-option-proc operand-proc . seeds)
"A wrapper on top of `args-fold' that does proper user-facing error
reporting."

View File

@ -65,6 +65,23 @@ interface, and powerful string processing.")
10)
#\newline))
(test-equal "package-specification->name+version+output"
'(("guile" #f "out")
("guile" "2.0.9" "out")
("guile" #f "debug")
("guile" "2.0.9" "debug")
("guile-cairo" "1.4.1" "out"))
(map (lambda (spec)
(call-with-values
(lambda ()
(package-specification->name+version+output spec))
list))
'("guile"
"guile-2.0.9"
"guile:debug"
"guile-2.0.9:debug"
"guile-cairo-1.4.1")))
(test-equal "integer"
'(1)
(string->generations "1"))