apteryx pushed a commit to branch master
in repository guix.

commit 271a8fc2499135c3f0198bf69c9f2a60f1961bf1
Author: Maxim Cournoyer <maxim.courno...@gmail.com>
AuthorDate: Sat May 17 14:36:40 2025 +0900

    refresh: Allow specifying a partial version via the version specification.
    
    * 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.  Remove extraneous 'guix refresh'
    invocation.
    * doc/guix.texi (Invoking guix refresh): Document it.
    
    Change-Id: Iab4482d9367105f6ffcd2d6a49148736c93d53e4
    Reviewed-by: Florian Pelz <pelzflor...@pelzflorian.de>
    Reviewed-by: Ludovic Courtès <l...@gnu.org>
---
 doc/guix.texi            | 11 +++++++++++
 guix/scripts/refresh.scm |  7 +++++--
 tests/guix-refresh.sh    | 19 ++++++++++++++++++-
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 4f9cd56aa5..fd86551787 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15148,6 +15148,17 @@ gnu/packages/qt.scm:1472:13: qtdeclarative would be 
upgraded from 5.15.8 to 5.15
 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 2d08607328..4a94ec637b 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -231,8 +231,11 @@ SPEC lacks a version, use 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 0f1af8cae7..93db7bfab4 100644
--- a/tests/guix-refresh.sh
+++ b/tests/guix-refresh.sh
@@ -126,13 +126,30 @@ 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
     *"would be upgraded"*"3.13.3"*) true;;
     *) false;;
 esac
 
+# Partial spec version => select the newest release prefixed by it.
+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
+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"

Reply via email to