~ruther/guix-local

1b846da8c372bee78851439fd9e72b2499115e5a — Mathieu Lirzin 10 years ago fad155d
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.
M NEWS => NEWS +17 -0
@@ 14,18 14,30 @@ Please send Guix bug reports to bug-guix@gnu.org.

** 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 package’s 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 system generations
*** Emacs interface for hydra.gnu.org
*** Changes in Emacs interface variables and faces

In the following names, BUFFER-TYPE means "info" or "list";
ENTRY-TYPE means "package", "output" or "generation".

**** Removed

- guix-info-fill-column
- guix-info-insert-ENTRY-TYPE-function

**** Renamed

- guix-info-ignore-empty-vals -> guix-info-ignore-empty-values
- guix-output-name-width -> guix-generation-output-name-width
- 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

**** Replaced

- guix-list-column-format, guix-list-column-value-methods ->
  guix-ENTRY-TYPE-list-format
- 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-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)

** Package management

M doc/guix.texi => doc/guix.texi +6 -6
@@ 13,7 13,7 @@
Copyright @copyright{} 2012, 2013, 2014, 2015, 2016 Ludovic Courtès@*
Copyright @copyright{} 2013, 2014, 2016 Andreas Enge@*
Copyright @copyright{} 2013 Nikita Karetnikov@*
Copyright @copyright{} 2015 Mathieu Lirzin@*
Copyright @copyright{} 2015, 2016 Mathieu Lirzin@*
Copyright @copyright{} 2014 Pierre-Antoine Rault@*
Copyright @copyright{} 2015 Taylan Ulrich Bayırlı/Kammer@*
Copyright @copyright{} 2015, 2016 Leo Famulari


@@ 1285,14 1285,14 @@ The @var{options} can be among the following:
Install the specified @var{package}s.

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,
such as @code{guile-1.8.8} or simply @code{guile-1.8} (in the latter
@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
case, the newest version prefixed by @code{1.8} is selected.)

If no version number is specified, the
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
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
name (and optionally version) are searched for among the GNU
distribution modules (@pxref{Package Modules}).


@@ 4522,10 4522,10 @@ guix import hackage -t -e "'((\"network-uri\" . false))" HTTP
@end example

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
guix import hackage mtl-2.1.3.1
guix import hackage mtl@@2.1.3.1
@end example

@item elpa

M gnu/packages.scm => gnu/packages.scm +13 -5
@@ 282,7 282,7 @@ return its return value."
;;; Package specification.
;;;

(define (%find-package spec name version)
(define* (%find-package spec name version #:key fallback?)
  (match (find-best-packages-by-name name version)
    ((pkg . pkg*)
     (unless (null? pkg*)


@@ 290,15 290,23 @@ return its return value."
       (warning (_ "choosing ~a from ~a~%")
                (package-full-name pkg)
                (location->string (package-location pkg))))
     (when fallback?
       (warning (_ "deprecated NAME-VERSION syntax.~%")))
     pkg)
    (_
     (if 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)
  "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."
  (let-values (((name version) (package-name->name+version spec)))
    (%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:

  guile
  guile-2.0.9
  guile@2.0.9
  guile:debug
  guile-2.0.9:debug
  guile@2.0.9:debug

If SPEC does not specify a version number, return the preferred newest
version; if SPEC does not specify an output, return OUTPUT."

M guix/scripts/import/hackage.scm => guix/scripts/import/hackage.scm +1 -1
@@ 46,7 46,7 @@
(define (show-help)
  (display (_ "Usage: guix import hackage 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
package will be generated.  If no version suffix is pecified, then the
generated package definition will correspond to the latest available

M guix/ui.scm => guix/ui.scm +2 -2
@@ 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:

  guile
  guile-2.0.9
  guile@2.0.9
  guile:debug
  guile-2.0.9:debug
  guile@2.0.9:debug
"
  (let*-values (((name sub-drv)
                 (match (string-rindex spec #\:)

M guix/utils.scm => guix/utils.scm +12 -3
@@ 3,6 3,7 @@
;;; Copyright © 2013, 2014, 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;;
;;; This file is part of GNU Guix.


@@ 31,8 32,7 @@
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs io ports)
  #:use-module ((rnrs bytevectors) #:select (bytevector-u8-set!))
  #:use-module ((guix build utils)
                #:select (dump-port package-name->name+version))
  #:use-module ((guix build utils) #:select (dump-port))
  #:use-module ((guix build syscalls) #:select (errno mkdtemp!))
  #:use-module (ice-9 vlist)
  #:use-module (ice-9 format)


@@ 42,7 42,6 @@
  #:use-module (ice-9 match)
  #:use-module (ice-9 format)
  #:use-module (system foreign)
  #:re-export (package-name->name+version)
  #:export (bytevector->base16-string
            base16-string->bytevector



@@ 66,6 65,7 @@
            gnu-triplet->nix-system
            %current-system
            %current-target-system
            package-name->name+version
            version-compare
            version>?
            version>=?


@@ 544,6 544,15 @@ returned by `config.guess'."
  ;; cross-building to.
  (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
  (let ((strverscmp
         (let ((sym (or (dynamic-func "strverscmp" (dynamic-link))

M tests/guix-build.sh => tests/guix-build.sh +2 -2
@@ 161,8 161,8 @@ then false; else true; fi

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

M tests/guix-lint.sh => tests/guix-lint.sh +1 -1
@@ 75,4 75,4 @@ if guix lint -c synopsis,invalid-checker dummy 2>&1 | \
then true; else false; fi

# 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

M tests/guix-package.sh => tests/guix-package.sh +2 -2
@@ 207,13 207,13 @@ cat > "$module_dir/foo.scm"<<EOF
EOF

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.
GUIX_PACKAGE_PATH="$module_dir"
export GUIX_PACKAGE_PATH
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.
cat > "$module_dir/emacs.patch"<<EOF

M tests/ui.scm => tests/ui.scm +3 -3
@@ 108,10 108,10 @@ Second line" 24))
               (package-specification->name+version+output spec))
           list))
       '("guile"
         "guile-2.0.9"
         "guile@2.0.9"
         "guile:debug"
         "guile-2.0.9:debug"
         "guile-cairo-1.4.1")))
         "guile@2.0.9:debug"
         "guile-cairo@1.4.1")))

(test-equal "integer"
  '(1)

M tests/utils.scm => tests/utils.scm +3 -2
@@ 1,6 1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 59,14 60,14 @@
          ((name version)
           (let*-values (((full-name)
                          (if version
                              (string-append name "-" version)
                              (string-append name "@" version)
                              name))
                         ((name* version*)
                          (package-name->name+version full-name)))
             (and (equal? name* name)
                  (equal? version* version)))))
         '(("foo" "0.9.1b")
           ("foo-bar" "1.0")
           ("foo-14-bar" "320")
           ("foo-bar2" #f)
           ("guile" "2.0.6.65-134c9") ; as produced by `git-version-gen'
           ("nixpkgs" "1.0pre22125_a28fe19")