~ruther/guix-local

2876b9892583bc1245d77fd10286025cd8433ede — Ludovic Courtès 12 years ago cc4ecc2
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.
3 files changed, 50 insertions(+), 7 deletions(-)

M guix/scripts/package.scm
M guix/ui.scm
M tests/ui.scm
M guix/scripts/package.scm => guix/scripts/package.scm +2 -7
@@ 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)))

M guix/ui.scm => guix/ui.scm +31 -0
@@ 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."

M tests/ui.scm => tests/ui.scm +17 -0
@@ 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"))