Subject: Re: bug#31088: Use '@' as version number separator in guix output

From: Chris Marusich <[email-masked]>
Date: Mon, 09 Apr 2018 23:38:01 -0700

Hi Pierre and Mathieu,

Thank you for the bug report, Pierre!  Mathieu, can you take a look at
the patch I've attached to this email?  It should fix this bug, but
since you made similar changes in the past, I'd value your feedback.

Pierre Neidhardt <[email-masked]> writes:

> Would it be possible to separate the package name from the version
> number with '@' instead?

Pierre's suggestion makes sense to me.  Starting with Mathieu's commit
1b846da8c372bee78851439fd9e72b2499115e5a about one year ago, we use "@"
to separate the package name from the version in commands like "guix
package -i [email-masked]" and also in exported scheme procedures like
specification->package (defined in (gnu packages)).  Before that, we
used "-" instead of "@".  When we made the change, it looks like we did
not also update the "dependencies" output from commands like "guix
package --show".

I've attached a patch that fixes the issue.  It applies cleanly to
df154c05dc65025eac2d14ab45699b34c7a1c7c8 (the tip of the master branch
at the time I drafted this email), and "make check" succeeds.  With the
change, the output now looks like this:

  $ ./pre-inst-env guix package --show=ncdu | recsel -p dependencies
  dependencies: [email-masked]

I was not able to run "make check-system" successfully, but there is no
reason to suspect that the attached patch causes any problem, since the
"check-system" target was already failing in the same way at commit
df154c05dc65025eac2d14ab45699b34c7a1c7c8.  I'll open up a separate bug
report for that separate issue.

Because I changed the package-full-name procedure, this also fixes the
package names in other places, such as graphs produced by "guix graph".
I'm not sure how many package rebuilds (if any?) this will cause, and
I'd like to hear what Mathieu has to say about my patch, so I'll wait to
push it until after I get feedback from him or another interested
person.  We should probably also regenerate the images in
guix/doc/images (so that the delimiter used in the images is "@" instead
of "-", although I'm not sure yet how to regenerate the source dot
files.  Mathieu, please let me know what you think!

In the meantime, Pierre, you can work around the issue by writing a
Guile script that gets the package version using the Guix API like so:

  scheme@(guile-user)> ,use (gnu packages ncdu)
  scheme@(guile-user)> ,use (guix packages)
  scheme@(guile-user)> (package-version ncdu)
  $1 = "1.13"

If you aren't sure how to get started writing Guile scripts, please
refer to the section "Running Guile Scripts" in the Guile manual.

-- 
Chris

From 96160c457c852d88e9a584cb16eb7703b02d8de5 Mon Sep 17 00:00:00 2001
From: Chris Marusich <[email-masked]>
Date: Sun, 8 Apr 2018 16:51:42 -0700
Subject: [PATCH] guix: Separate the package name and version with "@", not
 "-".

* guix/packages.scm (package-full-name): By default, use "@" to separate
  the package name and package version.  Add #:delimiter keyword
  argument so that there is still a way to explicitly use a different
  delimiter.
* gnu/packages/commencement.scm (gcc-boot0) <unpack-gmp&co>: Adjust
  accordingly.
* tests/graph.scm: Adjust accordingly.
* tests/profiles.scm: Adjust accordingly.
* NEWS: Mention the change.

Fixes: <https://bugs.gnu.org/31088>.
Reported by Pierre Neidhardt <[email-masked]>.
---
 NEWS                          |  1 +
 gnu/packages/commencement.scm |  2 +-
 guix/packages.go.134WZR       |  0
 guix/packages.scm             | 13 +++++++++----
 tests/graph.scm               |  4 ++--
 tests/profiles.scm            | 11 ++++++-----
 6 files changed, 19 insertions(+), 12 deletions(-)
 create mode 100644 guix/packages.go.134WZR

diff --git a/NEWS b/NEWS
index 2c898e65f..9769bfc87 100644
--- a/NEWS
+++ b/NEWS
@@ -777,6 +777,7 @@ [email-masked]
 
 ** Programming interfaces
 
+*** package-full-name (guix packages) now uses "@" instead of "-" as its delimiter.
 *** New build systems: ‘font’, ‘meson’, ‘minify’, ‘scons’, ‘texlive’
 *** ‘cmake-build-system’ now supports cross-compilation
 *** Various improvements to ‘asdf-build-system’, ‘emacs-build-system’,
diff --git a/gnu/packages/commencement.scm b/gnu/packages/commencement.scm
index fe9fbebcc..9506fbb2b 100644
--- a/gnu/packages/commencement.scm
+++ b/gnu/packages/commencement.scm
@@ -282,7 +282,7 @@
                             ;; Drop trailing letters, as gmp-6.0.0a unpacks
                             ;; into gmp-6.0.0.
                             `(symlink ,(string-trim-right
-                                        (package-full-name lib)
+                                        (package-full-name lib #:delimiter "-")
                                         char-set:letter)
                                       ,(package-name lib)))
                           (list gmp-6.0 mpfr mpc))))
diff --git a/guix/packages.go.134WZR b/guix/packages.go.134WZR
new file mode 100644
index 000000000..e69de29bb
diff --git a/guix/packages.scm b/guix/packages.scm
index b5c0b6044..38e6344bf 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -388,10 +388,11 @@ object."
 (define-condition-type &package-cross-build-system-error &package-error
   package-cross-build-system-error?)
 
-
-(define (package-full-name package)
-  "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
-  (string-append (package-name package) "-" (package-version package)))
+(define* (package-full-name package #:key (delimiter "@"))
+  "Return the full name of PACKAGE--i.e., `NAME@VERSION'.  By specifying
+DELIMITER (a string), you can customize what will appear between the name and
+the version.  By default, DELIMITER is \"@\"."
+  (string-append (package-name package) delimiter (package-version package)))
 
 (define (%standard-patch-inputs)
   (let* ((canonical (module-ref (resolve-interface '(gnu packages base))
@@ -935,6 +936,10 @@ and return it."
               (($ <package> name version source build-system
                             args inputs propagated-inputs native-inputs
                             self-native-input? outputs)
+               ;; Even though we prefer to use "@" to separate the package
+               ;; name from the package version in various user-facing parts
+               ;; of Guix, checkStoreName (in nix/libstore/store-api.cc)
+               ;; prohibits the use of "@", so use "-" instead.
                (or (make-bag build-system (string-append name "-" version)
                              #:system system
                              #:target target
diff --git a/tests/graph.scm b/tests/graph.scm
index 5faa19298..34bc55d2a 100644
--- a/tests/graph.scm
+++ b/tests/graph.scm
@@ -134,8 +134,8 @@ edges."
                      (map (lambda (destination)
                             (list "p-0.drv"
                                   (string-append
-                                   (package-full-name destination)
-                                   ".drv")))
+                                   (package-name destination) "-"
+                                   (package-version destination) ".drv")))
                           implicit)))))))
 
 (test-assert "bag DAG"                            ;a big town in Iraq
diff --git a/tests/profiles.scm b/tests/profiles.scm
index 92eb08cb9..dd0e19967 100644
--- a/tests/profiles.scm
+++ b/tests/profiles.scm
@@ -242,8 +242,9 @@
                                         #:hooks '()
                                         #:locales? #t
                                         #:target target)))
-    (define (find-input name)
-      (let ((name (string-append name ".drv")))
+    (define (find-input package)
+      (let ((name (string-append (package-name package) "-"
+                                 (package-version package) ".drv")))
         (any (lambda (input)
                (let ((input (derivation-input-path input)))
                  (and (string-suffix? name input) input)))
@@ -252,12 +253,12 @@
     ;; The inputs for grep and sed should be cross-build derivations, but that
     ;; for the glibc-utf8-locales should be a native build.
     (return (and (string=? (derivation-system drv) (%current-system))
-                 (string=? (find-input (package-full-name packages:grep))
+                 (string=? (find-input packages:grep)
                            (derivation-file-name grep))
-                 (string=? (find-input (package-full-name packages:sed))
+                 (string=? (find-input packages:sed)
                            (derivation-file-name sed))
                  (string=? (find-input
-                            (package-full-name packages:glibc-utf8-locales))
+                            packages:glibc-utf8-locales)
                            (derivation-file-name locales))))))
 
 (test-assert "package->manifest-entry defaults to \"out\""
-- 
2.17.0