Subject: bug#78462: closed (Re: [bug#78463] [PATCH 2/2] news: Add news entry for new 'guix refresh' partial version syntax.)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 19 May 2025 01:12:03 +0000

Your bug report

#78463: [PATCH 1/2] refresh: Allow specifying a partial version via the version specification.

which was filed against the guix-patches package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
78463: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78463
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: [bug#78463] [PATCH 2/2] news: Add news entry for new 'guix refresh' partial version syntax.
From: Maxim Cournoyer <[email-masked]>
To: "pelzflorian (Florian Pelz)" <[email-masked]>
Cc: Julien Lepiller <[email-masked]>, [email-masked]
Date: Mon, 19 May 2025 10:10:52 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Florian,

"pelzflorian (Florian Pelz)" <[email-masked]> writes:

> A good change (untested).
>
> It is not appropriate to write XXX: in comments on your first
> patch’s unit tests, as I understand the Wiktionary definition of XXX:
>
> 2. (computing) Used as a placeholder in source code to mark that some work
> still has to be done.

That's close to the meaning I use it for: something inelegant or dirty,
that would better be rewritten if someone knows better.  In other words,
it's functional but not ideal/hacky.  To mark some work that would need
doing in the future, I'd use a TODO instead.

I'm not sure if that's the most correct definition, but that's at least
how I've always understood it to be used in the Guix code base, e.g. by
Ludovic.

> Could you add this German translation?

Done, thank you!

> Additionally, I surrounded the info command in @command{} markup in the
> last line of the English news, too.
>
>         (title
>          (en "@samp{guix refresh} can now target partial versions")
>          (de "@samp{guix refresh} kann jetzt unvollständige Versionen als Ziel
> nehmen"))
>         (body
>          (en "While it had been possible for some time to use the
> @option{--target-version} to update to a partially defined version, this can
> now be more conveniently expressed via the package version specification
> directly, by prefixing it with the tilde (@samp{~}) character:
>
> @example
> $ guix refresh bash=~5.2
> gnu/packages/bash.scm:150:15: bash would be upgraded from 5.1.16 to 5.2.37
> @end example
>
> For more information, see @command{info \"(guix) Invoking guix refresh\"}.")

It doesn't seem to be explained in the Texinfo manual, but @command is
really only supposed to be used with a single word/command, not a
command line.  For the later @samp should be used instead.  That's
explained in (info "(texinfo) @command").

In this case though, I meant it to be this way: I've recently discovered
that when visiting a Texinfo node in a manual in Emacs, you can copy the
reference to it with 'C-0 c', then paste it somewhere.  Emacs users can
then jump straight to it by evaluating it with C-x C-e (with the cursor
placed after the closing parens).  I recently found that trick, I think
it's neat!  I seem to recall that Gnus also had a means to linkify such
references directly in email.

Thanks for the review and translation, as well as to Ludovic's.

Pushed with commit 450a3615325.  Closing.

-- 
Thanks,
Maxim

Subject: [PATCH 1/2] refresh: Allow specifying a partial version via the version specification.
From: Maxim Cournoyer <[email-masked]>
To: [email-masked]
Cc: Maxim Cournoyer <[email-masked]>
Date: Sat, 17 May 2025 14:40:19 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

* guix/scripts/refresh.scm (update-specification->update-spec): Flag the
update-spec as partial when it is prefixed with '~'.
* tests/guix-refresh.sh: Test it.
* doc/guix.texi (Invoking guix refresh): Document it.

Change-Id: Iab4482d9367105f6ffcd2d6a49148736c93d53e4
---
 doc/guix.texi            | 11 +++++++++++
 guix/scripts/refresh.scm |  7 +++++--
 tests/guix-refresh.sh    | 20 ++++++++++++++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 8e73685a216..584a42b6a79 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15147,6 +15147,17 @@ Invoking guix refresh
 gnu/packages/qt.scm:452:13: qtbase would be upgraded from 5.15.8 to 5.15.10
 @end example
 
+@cindex partial version specification, guix refresh
+A per-package equivalent to --target-version is made available by
+prefixing the version specification with the @samp{~} (tilde) character.
+For example:
+
+@example
+$ guix refresh bash=~5 guile=~3
+gnu/packages/guile.scm:354:13: guile would be upgraded from 3.0.9 to 3.0.10
+gnu/packages/bash.scm:150:15: bash would be upgraded from 5.1.16 to 5.2.37
+@end example
+
 Sometimes the upstream name differs from the package name used in Guix,
 and @command{guix refresh} needs a little help.  Most updaters honor the
 @code{upstream-name} property in package definitions, which can be used
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index 2d086073284..4a94ec637bb 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -231,8 +231,11 @@ (define (update-specification->update-spec spec fallback-version)
   (match (string-rindex spec #\=)
     (#f  (update-spec (specification->package spec) fallback-version
                       (not (not fallback-version))))
-    (idx (update-spec (specification->package (substring spec 0 idx))
-                      (substring spec (1+ idx))))))
+    (idx (let ((version (substring spec (1+ idx)))
+               (package (specification->package (substring spec 0 idx))))
+           (if (string-prefix? "~" version)
+               (update-spec package (string-drop version 1) #t) ;partial
+               (update-spec package version))))))
 
 (define (options->update-specs opts)
   "Return the list of <update-spec> records requested by OPTS, honoring
diff --git a/tests/guix-refresh.sh b/tests/guix-refresh.sh
index 0f1af8cae7c..e287f37717f 100644
--- a/tests/guix-refresh.sh
+++ b/tests/guix-refresh.sh
@@ -126,6 +126,12 @@ case "$(guix refresh -t test guile --target-version=2.0.0 2>&1)" in
     *) false;;
 esac
 
+guix refresh -t test guile=~2.0.0 # XXX: should return non-zero?
+case "$(guix refresh -t test guile=~2.0.0 2>&1)" in
+    *"failed to find"*"2.0.0"*) true;;
+    *) false;;
+esac
+
 # Partial target version => select the newest release prefixed by it.
 guix refresh -t test guile --target-version=3 # XXX: should return non-zero?
 case "$(guix refresh -t test guile --target-version=3 2>&1)" in
@@ -133,6 +139,20 @@ case "$(guix refresh -t test guile --target-version=3 2>&1)" in
     *) false;;
 esac
 
+# Partial spec version => select the newest release prefixed by it.
+guix refresh -t test guile=~3 # XXX: should return non-zero?
+case "$(guix refresh -t test guile=~3 2>&1)" in
+    *"would be upgraded"*"3.13.3"*) true;;
+    *) false;;
+esac
+
+# Conflicting --target-version and spec: spec wins
+guix refresh -t test guile=~3 --target-version=1 # XXX: should return non-zero?
+case "$(guix refresh -t test guile=~3 2>&1)" in
+    *"would be upgraded"*"3.13.3"*) true;;
+    *) false;;
+esac
+
 for spec in "guile=1.6.4" "guile@3=1.6.4"
 do
     guix refresh -t test "$spec"

base-commit: 3fadea42548389141e84a8481d271ac7280de7bc
-- 
2.49.0