utils: Use '@' for separating package names and version numbers.

This provides the ability to use numbers in package names.

Fixes <http://bugs.gnu.org/19219>.

* guix/utils.scm (package-name->name+version): New procedure.
* gnu/packages.scm (%find-package): Add a FALLBACK? keyword argument.
Use the previous method when no package is found.
(specification->package+output, specification->package): Adapt
documentation to new syntax.
* doc/guix.texi (Invoking guix package, Invoking guix import): Likewise.
* guix/ui.scm (package-specification->name+version+output): Likewise.
* guix/scripts/import/hackage.scm (show-help): Likewise.
* tests/guix-build.sh: Adapt to new syntax.
* tests/guix-lint.sh: Likewise.
* tests/guix-package.sh: Likewise.
* tests/ui.scm ("package-specification->name+version+output"): Likewise.
* tests/utils.scm ("package-name->name+version"): Likewise.
* NEWS: Mention new syntax.
This commit is contained in:
Mathieu Lirzin 2016-02-28 23:11:36 +01:00
parent fad155d47e
commit 1b846da8c3
11 changed files with 62 additions and 27 deletions

17
NEWS
View File

@ -14,18 +14,30 @@ Please send Guix bug reports to bug-guix@gnu.org.
** Package management ** Package management
*** New syntax for separating package names and version numbers
Use @ instead of - as a separator, as in gnupg@2.0. This new separator
is a reserved character which is not allowed both in package names and version
numbers.
The old syntax to specify a packages version—e.g., as “gnupg-2.0”—is obsolete
and support for it will be removed in the future.
*** Emacs interface for licenses *** Emacs interface for licenses
*** Emacs interface for system generations *** Emacs interface for system generations
*** Emacs interface for hydra.gnu.org *** Emacs interface for hydra.gnu.org
*** Changes in Emacs interface variables and faces *** Changes in Emacs interface variables and faces
In the following names, BUFFER-TYPE means "info" or "list"; In the following names, BUFFER-TYPE means "info" or "list";
ENTRY-TYPE means "package", "output" or "generation". ENTRY-TYPE means "package", "output" or "generation".
**** Removed **** Removed
- guix-info-fill-column - guix-info-fill-column
- guix-info-insert-ENTRY-TYPE-function - guix-info-insert-ENTRY-TYPE-function
**** Renamed **** Renamed
- guix-info-ignore-empty-vals -> guix-info-ignore-empty-values - guix-info-ignore-empty-vals -> guix-info-ignore-empty-values
- guix-output-name-width -> guix-generation-output-name-width - guix-output-name-width -> guix-generation-output-name-width
- guix-buffer-name-function -> guix-ui-buffer-name-function - guix-buffer-name-function -> guix-ui-buffer-name-function
@ -34,6 +46,7 @@ ENTRY-TYPE means "package", "output" or "generation".
- guix-BUFFER-TYPE-file-path (face) -> guix-BUFFER-TYPE-file-name - guix-BUFFER-TYPE-file-path (face) -> guix-BUFFER-TYPE-file-name
**** Replaced **** Replaced
- guix-list-column-format, guix-list-column-value-methods -> - guix-list-column-format, guix-list-column-value-methods ->
guix-ENTRY-TYPE-list-format guix-ENTRY-TYPE-list-format
- guix-info-displayed-params, guix-info-insert-methods, - guix-info-displayed-params, guix-info-insert-methods,
@ -44,6 +57,10 @@ ENTRY-TYPE means "package", "output" or "generation".
guix-ENTRY-TYPE-list-describe-warning-count guix-ENTRY-TYPE-list-describe-warning-count
- guix-package-info-fill-heading -> guix-info-fill - guix-package-info-fill-heading -> guix-info-fill
** Noteworthy bug fixes
*** Numbers in package names are correctly handled (http://bugs.gnu.org/19219)
* Changes in 0.9.0 (since 0.8.3) * Changes in 0.9.0 (since 0.8.3)
** Package management ** Package management

View File

@ -13,7 +13,7 @@
Copyright @copyright{} 2012, 2013, 2014, 2015, 2016 Ludovic Courtès@* Copyright @copyright{} 2012, 2013, 2014, 2015, 2016 Ludovic Courtès@*
Copyright @copyright{} 2013, 2014, 2016 Andreas Enge@* Copyright @copyright{} 2013, 2014, 2016 Andreas Enge@*
Copyright @copyright{} 2013 Nikita Karetnikov@* Copyright @copyright{} 2013 Nikita Karetnikov@*
Copyright @copyright{} 2015 Mathieu Lirzin@* Copyright @copyright{} 2015, 2016 Mathieu Lirzin@*
Copyright @copyright{} 2014 Pierre-Antoine Rault@* Copyright @copyright{} 2014 Pierre-Antoine Rault@*
Copyright @copyright{} 2015 Taylan Ulrich Bayırlı/Kammer@* Copyright @copyright{} 2015 Taylan Ulrich Bayırlı/Kammer@*
Copyright @copyright{} 2015, 2016 Leo Famulari Copyright @copyright{} 2015, 2016 Leo Famulari
@ -1285,14 +1285,14 @@ The @var{options} can be among the following:
Install the specified @var{package}s. Install the specified @var{package}s.
Each @var{package} may specify either a simple package name, such as Each @var{package} may specify either a simple package name, such as
@code{guile}, or a package name followed by a hyphen and version number, @code{guile}, or a package name followed by an at-sign and version number,
such as @code{guile-1.8.8} or simply @code{guile-1.8} (in the latter such as @code{guile@@1.8.8} or simply @code{guile@@1.8} (in the latter
case, the newest version prefixed by @code{1.8} is selected.) case, the newest version prefixed by @code{1.8} is selected.)
If no version number is specified, the If no version number is specified, the
newest available version will be selected. In addition, @var{package} newest available version will be selected. In addition, @var{package}
may contain a colon, followed by the name of one of the outputs of the may contain a colon, followed by the name of one of the outputs of the
package, as in @code{gcc:doc} or @code{binutils-2.22:lib} package, as in @code{gcc:doc} or @code{binutils@@2.22:lib}
(@pxref{Packages with Multiple Outputs}). Packages with a corresponding (@pxref{Packages with Multiple Outputs}). Packages with a corresponding
name (and optionally version) are searched for among the GNU name (and optionally version) are searched for among the GNU
distribution modules (@pxref{Package Modules}). distribution modules (@pxref{Package Modules}).
@ -4522,10 +4522,10 @@ guix import hackage -t -e "'((\"network-uri\" . false))" HTTP
@end example @end example
A specific package version may optionally be specified by following the A specific package version may optionally be specified by following the
package name by a hyphen and a version number as in the following example: package name by an at-sign and a version number as in the following example:
@example @example
guix import hackage mtl-2.1.3.1 guix import hackage mtl@@2.1.3.1
@end example @end example
@item elpa @item elpa

View File

@ -282,7 +282,7 @@ return its return value."
;;; Package specification. ;;; Package specification.
;;; ;;;
(define (%find-package spec name version) (define* (%find-package spec name version #:key fallback?)
(match (find-best-packages-by-name name version) (match (find-best-packages-by-name name version)
((pkg . pkg*) ((pkg . pkg*)
(unless (null? pkg*) (unless (null? pkg*)
@ -290,15 +290,23 @@ return its return value."
(warning (_ "choosing ~a from ~a~%") (warning (_ "choosing ~a from ~a~%")
(package-full-name pkg) (package-full-name pkg)
(location->string (package-location pkg)))) (location->string (package-location pkg))))
(when fallback?
(warning (_ "deprecated NAME-VERSION syntax.~%")))
pkg) pkg)
(_ (_
(if version (if version
(leave (_ "~A: package not found for version ~a~%") name version) (leave (_ "~A: package not found for version ~a~%") name version)
(leave (_ "~A: unknown package~%") name))))) (or fallback?
;; XXX: Fallback to the older specification style with an hyphen
;; between NAME and VERSION, for backward compatibility.
(let ((proc (@ (guix build utils) package-name->name+version)))
(call-with-values (proc name)
(cut %find-package spec <> <> #:fallback? #t)))
(leave (_ "~A: unknown package~%") name))))))
(define (specification->package spec) (define (specification->package spec)
"Return a package matching SPEC. SPEC may be a package name, or a package "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 name followed by an at-sign and a version number. If the version number is not
present, return the preferred newest version." present, return the preferred newest version."
(let-values (((name version) (package-name->name+version spec))) (let-values (((name version) (package-name->name+version spec)))
(%find-package spec name version))) (%find-package spec name version)))
@ -308,9 +316,9 @@ present, return the preferred newest version."
optionally contain a version number and an output name, as in these examples: optionally contain a version number and an output name, as in these examples:
guile guile
guile-2.0.9 guile@2.0.9
guile:debug guile:debug
guile-2.0.9:debug guile@2.0.9:debug
If SPEC does not specify a version number, return the preferred newest If SPEC does not specify a version number, return the preferred newest
version; if SPEC does not specify an output, return OUTPUT." version; if SPEC does not specify an output, return OUTPUT."

View File

@ -46,7 +46,7 @@
(define (show-help) (define (show-help)
(display (_ "Usage: guix import hackage PACKAGE-NAME (display (_ "Usage: guix import hackage PACKAGE-NAME
Import and convert the Hackage package for PACKAGE-NAME. If PACKAGE-NAME Import and convert the Hackage package for PACKAGE-NAME. If PACKAGE-NAME
includes a suffix constituted by a dash followed by a numerical version (as includes a suffix constituted by a at-sign followed by a numerical version (as
used with Guix packages), then a definition for the specified version of the used with Guix packages), then a definition for the specified version of the
package will be generated. If no version suffix is pecified, then the package will be generated. If no version suffix is pecified, then the
generated package definition will correspond to the latest available generated package definition will correspond to the latest available

View File

@ -1081,9 +1081,9 @@ 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: optionally contain a version number and an output name, as in these examples:
guile guile
guile-2.0.9 guile@2.0.9
guile:debug guile:debug
guile-2.0.9:debug guile@2.0.9:debug
" "
(let*-values (((name sub-drv) (let*-values (((name sub-drv)
(match (string-rindex spec #\:) (match (string-rindex spec #\:)

View File

@ -3,6 +3,7 @@
;;; Copyright © 2013, 2014, 2015 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2013, 2014, 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net> ;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
;;; Copyright © 2015 David Thompson <davet@gnu.org> ;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -31,8 +32,7 @@
#:use-module (rnrs bytevectors) #:use-module (rnrs bytevectors)
#:use-module (rnrs io ports) #:use-module (rnrs io ports)
#:use-module ((rnrs bytevectors) #:select (bytevector-u8-set!)) #:use-module ((rnrs bytevectors) #:select (bytevector-u8-set!))
#:use-module ((guix build utils) #:use-module ((guix build utils) #:select (dump-port))
#:select (dump-port package-name->name+version))
#:use-module ((guix build syscalls) #:select (errno mkdtemp!)) #:use-module ((guix build syscalls) #:select (errno mkdtemp!))
#:use-module (ice-9 vlist) #:use-module (ice-9 vlist)
#:use-module (ice-9 format) #:use-module (ice-9 format)
@ -42,7 +42,6 @@
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (ice-9 format) #:use-module (ice-9 format)
#:use-module (system foreign) #:use-module (system foreign)
#:re-export (package-name->name+version)
#:export (bytevector->base16-string #:export (bytevector->base16-string
base16-string->bytevector base16-string->bytevector
@ -66,6 +65,7 @@
gnu-triplet->nix-system gnu-triplet->nix-system
%current-system %current-system
%current-target-system %current-target-system
package-name->name+version
version-compare version-compare
version>? version>?
version>=? version>=?
@ -544,6 +544,15 @@ returned by `config.guess'."
;; cross-building to. ;; cross-building to.
(make-parameter #f)) (make-parameter #f))
(define (package-name->name+version spec)
"Given SPEC, a package name like \"foo@0.9.1b\", return two values: \"foo\"
and \"0.9.1b\". When the version part is unavailable, SPEC and #f are
returned. Both parts must not contain any '@'."
(match (string-rindex spec #\@)
(#f (values spec #f))
(idx (values (substring spec 0 idx)
(substring spec (1+ idx))))))
(define version-compare (define version-compare
(let ((strverscmp (let ((strverscmp
(let ((sym (or (dynamic-func "strverscmp" (dynamic-link)) (let ((sym (or (dynamic-func "strverscmp" (dynamic-link))

View File

@ -161,8 +161,8 @@ then false; else true; fi
# Parsing package names and versions. # Parsing package names and versions.
guix build -n time # PASS guix build -n time # PASS
guix build -n time-1.7 # PASS, version found guix build -n time@1.7 # PASS, version found
if guix build -n time-3.2; # FAIL, version not found if guix build -n time@3.2; # FAIL, version not found
then false; else true; fi then false; else true; fi
if guix build -n something-that-will-never-exist; # FAIL if guix build -n something-that-will-never-exist; # FAIL
then false; else true; fi then false; else true; fi

View File

@ -75,4 +75,4 @@ if guix lint -c synopsis,invalid-checker dummy 2>&1 | \
then true; else false; fi then true; else false; fi
# Make sure specifying multiple packages works. # Make sure specifying multiple packages works.
guix lint -c inputs-should-be-native dummy dummy-42 dummy guix lint -c inputs-should-be-native dummy dummy@42 dummy

View File

@ -207,13 +207,13 @@ cat > "$module_dir/foo.scm"<<EOF
EOF EOF
guix package -A emacs-foo-bar -L "$module_dir" | grep 42 guix package -A emacs-foo-bar -L "$module_dir" | grep 42
guix package -i emacs-foo-bar-42 -n -L "$module_dir" guix package -i emacs-foo-bar@42 -n -L "$module_dir"
# Same thing using the 'GUIX_PACKAGE_PATH' environment variable. # Same thing using the 'GUIX_PACKAGE_PATH' environment variable.
GUIX_PACKAGE_PATH="$module_dir" GUIX_PACKAGE_PATH="$module_dir"
export GUIX_PACKAGE_PATH export GUIX_PACKAGE_PATH
guix package -A emacs-foo-bar | grep 42 guix package -A emacs-foo-bar | grep 42
guix package -i emacs-foo-bar-42 -n guix package -i emacs-foo-bar@42 -n
# Make sure patches that live under $GUIX_PACKAGE_PATH are found. # Make sure patches that live under $GUIX_PACKAGE_PATH are found.
cat > "$module_dir/emacs.patch"<<EOF cat > "$module_dir/emacs.patch"<<EOF

View File

@ -108,10 +108,10 @@ Second line" 24))
(package-specification->name+version+output spec)) (package-specification->name+version+output spec))
list)) list))
'("guile" '("guile"
"guile-2.0.9" "guile@2.0.9"
"guile:debug" "guile:debug"
"guile-2.0.9:debug" "guile@2.0.9:debug"
"guile-cairo-1.4.1"))) "guile-cairo@1.4.1")))
(test-equal "integer" (test-equal "integer"
'(1) '(1)

View File

@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -59,14 +60,14 @@
((name version) ((name version)
(let*-values (((full-name) (let*-values (((full-name)
(if version (if version
(string-append name "-" version) (string-append name "@" version)
name)) name))
((name* version*) ((name* version*)
(package-name->name+version full-name))) (package-name->name+version full-name)))
(and (equal? name* name) (and (equal? name* name)
(equal? version* version))))) (equal? version* version)))))
'(("foo" "0.9.1b") '(("foo" "0.9.1b")
("foo-bar" "1.0") ("foo-14-bar" "320")
("foo-bar2" #f) ("foo-bar2" #f)
("guile" "2.0.6.65-134c9") ; as produced by `git-version-gen' ("guile" "2.0.6.65-134c9") ; as produced by `git-version-gen'
("nixpkgs" "1.0pre22125_a28fe19") ("nixpkgs" "1.0pre22125_a28fe19")