summary refs log tree commit diff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/packages.scm26
1 files changed, 25 insertions, 1 deletions
diff --git a/gnu/packages.scm b/gnu/packages.scm
index 14ad75561c..26d87c6b16 100644
--- a/gnu/packages.scm
+++ b/gnu/packages.scm
@@ -28,6 +28,7 @@
   #:use-module (ice-9 vlist)
   #:use-module (ice-9 match)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-39)
   #:export (search-patch
@@ -45,7 +46,9 @@
             package-transitive-dependents
             package-covering-dependents
 
-            check-package-freshness))
+            check-package-freshness
+
+            specification->package))
 
 ;;; Commentary:
 ;;;
@@ -326,3 +329,24 @@ but ~a is available upstream~%")
       (case key
         ((getaddrinfo-error ftp-error) #f)
         (else (apply throw key args))))))
+
+(define (specification->package spec)
+  "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)))
+    (match (find-best-packages-by-name name version)
+      ((p)                                      ; one match
+       p)
+      ((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))))))