Subject: Re: bug#19219: Package names with digits following dashes

From: [email-masked] (Ludovic Courtès)
Date: Sun, 07 Dec 2014 00:38:10 +0100

tag 19219 patch
thanks

Andreas Enge <[email-masked]> skribis:

> I think we need a more sophisticated mechanism for separating package names
> and versions, such as this:
> - Try the compete string as a package name.
> - If it does not exist, treat the part after the last dash as a version and
>   the part before the last dash as the name.

Attached is the beginning of a patch to do that.

However, there are users of ‘package-specification->name+version+output’
that still need to be adjusted, such as Emacs (in guix-main.scm.)  Also,
the responsibility of trying NAME-VERSION is on each caller, which is
not really satisfying.

I’ll ponder it some more.  Suggestions welcome.

Thanks,
Ludo’.

diff --git a/gnu/packages.scm b/gnu/packages.scm
index c9efd0d..25f1221 100644
--- a/gnu/packages.scm
+++ b/gnu/packages.scm
@@ -370,19 +370,24 @@ but ~a is available upstream~%")
   "Return a package matching SPEC.  SPEC may be a package name, or a package
 name followed by a hyphen and a version number.  If the version number is not
 present, return the preferred newest version."
-  (let-values (((name version)
-                (package-name->name+version spec)))
+  (define (lookup name version)
     (match (find-best-packages-by-name name version)
-      ((p)                                      ; one match
+      ((p)                                        ;one match
        p)
-      ((p x ...)                                ; several matches
+      ((p x ...)                                  ;several matches
        (warning (_ "ambiguous package specification `~a'~%") spec)
        (warning (_ "choosing ~a from ~a~%")
                 (package-full-name p)
                 (location->string (package-location p)))
        p)
-      (_                                        ; no matches
-       (if version
-           (leave (_ "~A: package not found for version ~a~%")
-                  name version)
-           (leave (_ "~A: unknown package~%") name))))))
+      (_                                          ;no matches
+       #f)))
+
+  (let-values (((name version)
+                (package-name->name+version spec)))
+    (or (lookup name version)
+        (if version
+            (or (lookup spec #f)
+                (leave (_ "~A: package not found for version ~a~%")
+                       name version))
+            (leave (_ "~A: unknown package~%") name)))))
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index 21dc66c..ae11ee2 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -296,8 +296,7 @@ version; if SPEC does not specify an output, return OUTPUT."
                (package-full-name p)
                sub-drv)))
 
-  (let-values (((name version sub-drv)
-                (package-specification->name+version+output spec output)))
+  (define (lookup name version sub-drv)
     (match (find-best-packages-by-name name version)
       ((p)
        (values p (ensure-output p sub-drv)))
@@ -309,7 +308,26 @@ version; if SPEC does not specify an output, return OUTPUT."
                 (location->string (package-location p)))
        (values p (ensure-output p sub-drv)))
       (()
-       (leave (_ "~a: package not found~%") spec)))))
+       (values #f #f))))
+
+  (define (fail)
+    (leave (_ "~a: package not found~%") spec))
+
+  (let-values (((name version sub-drv)
+                (package-specification->name+version+output spec output)))
+    (let-values (((package output) (lookup name version sub-drv)))
+      (cond
+       ((package? package)
+        (values package output))
+       (version
+        (let-values (((package output)
+                      (lookup (string-append name "-" version) #f
+                              sub-drv)))
+          (if package
+              (values package output)
+              (fail))))
+       (else
+        (fail))))))
 
 (define (upgradeable? name current-version current-path)
   "Return #t if there's a version of package NAME newer than CURRENT-VERSION,