From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mathieu Lirzin Subject: Re: [PATCH 04/13] utils: Use '@' for separating package names and version numbers. Date: Mon, 29 Feb 2016 01:28:23 +0100 Message-ID: <87wppo1hso.fsf@gnu.org> References: <1453666771-16869-1-git-send-email-mthl@gnu.org> <1453666771-16869-5-git-send-email-mthl@gnu.org> <87h9i1evp5.fsf@gmail.com> <8737tl4bve.fsf@gnu.org> <877fiwpayr.fsf@gnu.org> <87k2m0cto5.fsf@gnu.org> <87vb5flm0q.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:39740) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aaBhU-0007e8-19 for guix-devel@gnu.org; Sun, 28 Feb 2016 19:28:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aaBhR-0003mM-K0 for guix-devel@gnu.org; Sun, 28 Feb 2016 19:28:35 -0500 In-Reply-To: <87vb5flm0q.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Tue, 23 Feb 2016 12:11:01 +0100") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: Ludovic =?utf-8?Q?Court=C3=A8s?= Cc: guix-devel@gnu.org, Alex Kost --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, ludo@gnu.org (Ludovic Court=C3=A8s) writes: > What about this: > > 1. Put the new =E2=80=98package-name->name+version=E2=80=99 in (guix ut= ils) and keep > it dumb (i.e., it insists on having an =E2=80=98@=E2=80=99, as is th= e case with the > patch you posted.) > > 2. Add the fallback case in =E2=80=98specification->package=E2=80=99 and > =E2=80=98specification->package+output=E2=80=99 in (gnu packages). > > How does that sound? Thanks for finding a solution. It seems to work (at least according to =E2= =80=98make check=E2=80=99). However, I am not pleased by the current state of the =E2=80=98specification/package-name->...=E2=80=99 procedures. They don't c= ompose well, and are obfuscated by being fragmented across a bunch of modules. I don't know if there is much room for improvement but my feeling is that the brain involvement required for implementing the '@' thing was far too high compared to the actual task. I have left the emacs interface untouched. --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-packages-Factorize-package-specification-search.patch Content-Transfer-Encoding: quoted-printable >From a39b458002e2c4c36c9adb2718f166b4e5ff7965 Mon Sep 17 00:00:00 2001 From: Mathieu Lirzin Date: Sun, 28 Feb 2016 17:50:58 +0100 Subject: [PATCH 1/2] packages: Factorize package specification search. * gnu/packages.scm (%find-package): New procedure. (specification->package, specification->package+output): Use it. --- gnu/packages.scm | 64 +++++++++++++++++++++++++---------------------------= ---- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/gnu/packages.scm b/gnu/packages.scm index 64a695d..baec897 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -3,6 +3,7 @@ ;;; Copyright =C2=A9 2013 Mark H Weaver ;;; Copyright =C2=A9 2014 Eric Bavier ;;; Copyright =C2=A9 2016 Alex Kost +;;; Copyright =C2=A9 2016 Mathieu Lirzin ;;; ;;; This file is part of GNU Guix. ;;; @@ -276,26 +277,31 @@ return its return value." (lambda (k signum) (handler signum)))) =20 + +;;; +;;; Package specification. +;;; + +(define (%find-package spec name version) + (match (find-best-packages-by-name name version) + ((pkg . pkg*) + (unless (null? pkg*) + (warning (_ "ambiguous package specification `~a'~%") spec) + (warning (_ "choosing ~a from ~a~%") + (package-full-name pkg) + (location->string (package-location pkg)))) + pkg) + (_ + (if version + (leave (_ "~A: package not found for version ~a~%") name version) + (leave (_ "~A: unknown package~%") name))))) + (define (specification->package spec) "Return a package matching SPEC. SPEC may be a package name, or a packa= ge 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)))))) + (let-values (((name version) (package-name->name+version spec))) + (%find-package spec name version))) =20 (define* (specification->package+output spec #:optional (output "out")) "Return the package and output specified by SPEC, or #f and #f; SPEC may @@ -308,24 +314,12 @@ optionally contain a version number and an output nam= e, as in these examples: =20 If SPEC does not specify a version number, return the preferred newest version; if SPEC does not specify an output, return OUTPUT." - (define (ensure-output p sub-drv) - (if (member sub-drv (package-outputs p)) - sub-drv - (leave (_ "package `~a' lacks output `~a'~%") - (package-full-name p) - sub-drv))) - (let-values (((name version sub-drv) (package-specification->name+version+output spec output))) - (match (find-best-packages-by-name name version) - ((p) - (values p (ensure-output p sub-drv))) - ((p p* ...) - (warning (_ "ambiguous package specification `~a'~%") - spec) - (warning (_ "choosing ~a from ~a~%") - (package-full-name p) - (location->string (package-location p))) - (values p (ensure-output p sub-drv))) - (() - (leave (_ "~a: package not found~%") spec))))) + (and=3D> (%find-package spec name version) + (lambda (pkg) + (if (member sub-drv (package-outputs pkg)) + (values pkg sub-drv) + (leave (_ "package `~a' lacks output `~a'~%") + (package-full-name pkg) + sub-drv)))))) --=20 2.7.0 --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0002-utils-Use-for-separating-package-names-and-version-n.patch Content-Transfer-Encoding: quoted-printable >From a5d3eb26c06965647d0e1749b848f8501ae61d62 Mon Sep 17 00:00:00 2001 From: Mathieu Lirzin Date: Sun, 28 Feb 2016 23:11:36 +0100 Subject: [PATCH 2/2] * utils: Use '@' for separating package names and vers= ion numbers. This provides the ability to use numbers in package names. Fixes . * 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. --- NEWS | 13 +++++++++++++ doc/guix.texi | 12 ++++++------ gnu/packages.scm | 18 +++++++++++++----- guix/scripts/import/hackage.scm | 2 +- guix/ui.scm | 4 ++-- guix/utils.scm | 15 ++++++++++++--- tests/guix-build.sh | 4 ++-- tests/guix-lint.sh | 2 +- tests/guix-package.sh | 4 ++-- tests/ui.scm | 6 +++--- tests/utils.scm | 5 +++-- 11 files changed, 58 insertions(+), 27 deletions(-) diff --git a/NEWS b/NEWS index 010789e..b2a6250 100644 --- a/NEWS +++ b/NEWS @@ -14,18 +14,26 @@ Please send Guix bug reports to bug-guix@gnu.org. =20 ** Package management =20 +*** New syntax for separating package names and version numbers + +Use =E2=80=98@=E2=80=99 instead of =E2=80=98-=E2=80=99 as a separator. Th= is new separator is a reserved +character which is not allowed both in package names and version numbers. + *** 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". =20 **** Removed + - guix-info-fill-column - guix-info-insert-ENTRY-TYPE-function =20 **** 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 +42,7 @@ ENTRY-TYPE means "package", "output" or "generation". - guix-BUFFER-TYPE-file-path (face) -> guix-BUFFER-TYPE-file-name =20 **** 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 +53,10 @@ ENTRY-TYPE means "package", "output" or "generation". guix-ENTRY-TYPE-list-describe-warning-count - guix-package-info-fill-heading -> guix-info-fill =20 +** Noteworthy bug fixes + +*** Numbers in package names are correctly handled (http://bugs.gnu.org/19= 219) + * Changes in 0.9.0 (since 0.8.3) =20 ** Package management diff --git a/doc/guix.texi b/doc/guix.texi index 4c9a91b..705fce1 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -13,7 +13,7 @@ Copyright @copyright{} 2012, 2013, 2014, 2015, 2016 Ludovic Court=C3=A8s@* 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=C4=B1rl=C4=B1/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. =20 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.) =20 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\" . fal= se))" HTTP @end example =20 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 exampl= e: =20 @example -guix import hackage mtl-2.1.3.1 +guix import hackage mtl@@2.1.3.1 @end example =20 @item elpa diff --git a/gnu/packages.scm b/gnu/packages.scm index baec897..8213886 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -282,7 +282,7 @@ return its return value." ;;; Package specification. ;;; =20 -(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 hyp= hen + ;; 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)))))) =20 (define (specification->package spec) "Return a package matching SPEC. SPEC may be a package name, or a packa= ge -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 i= s 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 exampl= es: =20 guile - guile-2.0.9 + guile@2.0.9 guile:debug - guile-2.0.9:debug + guile@2.0.9:debug =20 If SPEC does not specify a version number, return the preferred newest version; if SPEC does not specify an output, return OUTPUT." diff --git a/guix/scripts/import/hackage.scm b/guix/scripts/import/hackage.= scm index 4e84278..f2c2002 100644 --- a/guix/scripts/import/hackage.scm +++ b/guix/scripts/import/hackage.scm @@ -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 t= he package will be generated. If no version suffix is pecified, then the generated package definition will correspond to the latest available diff --git a/guix/ui.scm b/guix/ui.scm index 7310773..a3ec683 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -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 exampl= es: =20 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 #\:) diff --git a/guix/utils.scm b/guix/utils.scm index c61f105..de54179 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -3,6 +3,7 @@ ;;; Copyright =C2=A9 2013, 2014, 2015 Mark H Weaver ;;; Copyright =C2=A9 2014 Eric Bavier ;;; Copyright =C2=A9 2014 Ian Denhardt +;;; Copyright =C2=A9 2016 Mathieu Lirzin ;;; Copyright =C2=A9 2015 David Thompson ;;; ;;; 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 =20 @@ -66,6 +65,7 @@ gnu-triplet->nix-system %current-system %current-target-system + package-name->name+version version-compare version>? version>=3D? @@ -544,6 +544,15 @@ returned by `config.guess'." ;; cross-building to. (make-parameter #f)) =20 +(define (package-name->name+version spec) + "Given SPEC, a package name like \"foo@0.9.1b\", return two values: \"fo= o\" +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)) diff --git a/tests/guix-build.sh b/tests/guix-build.sh index 347cdfa..6175bf8 100644 --- a/tests/guix-build.sh +++ b/tests/guix-build.sh @@ -161,8 +161,8 @@ then false; else true; fi =20 # 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 diff --git a/tests/guix-lint.sh b/tests/guix-lint.sh index 5015b5c..c105521 100644 --- a/tests/guix-lint.sh +++ b/tests/guix-lint.sh @@ -75,4 +75,4 @@ if guix lint -c synopsis,invalid-checker dummy 2>&1 | \ then true; else false; fi =20 # 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 diff --git a/tests/guix-package.sh b/tests/guix-package.sh index cf1a185..273a011 100644 --- a/tests/guix-package.sh +++ b/tests/guix-package.sh @@ -207,13 +207,13 @@ cat > "$module_dir/foo.scm"< "$module_dir/emacs.patch"<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"))) =20 (test-equal "integer" '(1) diff --git a/tests/utils.scm b/tests/utils.scm index a05faab..67b3724 100644 --- a/tests/utils.scm +++ b/tests/utils.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2012, 2013, 2014, 2015, 2016 Ludovic Court=C3=A8s ;;; Copyright =C2=A9 2014 Eric Bavier +;;; Copyright =C2=A9 2016 Mathieu Lirzin ;;; ;;; 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") --=20 2.7.0 --=-=-= Content-Type: text/plain -- Mathieu Lirzin --=-=-=--