diff --git a/NEWS.rst b/NEWS.rst index 5601b8078..ba5e14852 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -251,6 +251,8 @@ Modules 5.7.0 (not yet released) * Doc: add the :ref:`user-guide` document that explains a selection of useful but lesser known features through practical examples and common use cases. +* Accept abbreviated upper bounds in version ranges such as ``@3.20:3`` to + select versions starting at ``3.20`` within major version ``3``. * Init: fix command injection in Bash completion when module names contain shell meta-characters. Completion candidates were passed to ``compgen -W`` which evaluates command substitution syntax. (fix `CVE-2026-85013`_ found diff --git a/doc/source/module.rst b/doc/source/module.rst index b9ab6e5ed..e0f58d3e6 100644 --- a/doc/source/module.rst +++ b/doc/source/module.rst @@ -3235,6 +3235,9 @@ the activation of the extended default mechanism (see to refer to more precise version numbers like ``1.2.3``. Characters ``.`` and ``-`` are considered version number separator to determine abbreviated versions. Range of versions on its side natively handles abbreviated versions. +The upper bound may be less precise than the lower bound. An abbreviated +upper bound includes all versions that extend it, provided they also satisfy +the lower bound. In order to be specified in a range of versions or compared to a range of versions, the version major element should corresponds to a number. For diff --git a/tcl/modspec.tcl b/tcl/modspec.tcl index 97bf7e488..a614a449c 100644 --- a/tcl/modspec.tcl +++ b/tcl/modspec.tcl @@ -1246,7 +1246,9 @@ proc parseModuleVersionSpecifier {modspec} { set cmpspec le set versspec $hivers # between or equal - } elseif {[versioncmp $lovers $hivers] == 1} { + # An abbreviated upper bound includes its more precise versions. + } elseif {[versioncmp $lovers $hivers] == 1 && ![string match\ + $hivers[extendedDefaultCharGlobMatch] $lovers]} { set invalidversrange 1 } else { set cmpspec be diff --git a/testsuite/modules.70-maint/272-adv_version_spec-range.exp b/testsuite/modules.70-maint/272-adv_version_spec-range.exp index 0e4ac79de..16c0c8d12 100644 --- a/testsuite/modules.70-maint/272-adv_version_spec-range.exp +++ b/testsuite/modules.70-maint/272-adv_version_spec-range.exp @@ -84,6 +84,8 @@ testouterr_cmd sh {load mod@1::} ERR "$err_specvers'1::'" testouterr_cmd sh {load mod@1,:,} ERR "$err_specvers'1,:,'" testouterr_cmd sh {load mod@,:} ERR "$err_specvers',:'" testouterr_cmd sh {load mod@1.3:1.2} ERR "$err_rangevers'1.3:1.2'" +testouterr_cmd sh {load mod@4.1:3} ERR "$err_rangevers'4.1:3'" +testouterr_cmd sh {load mod@1.30:1.3} ERR "$err_rangevers'1.30:1.3'" testouterr_cmd sh {load mod@,<} ERR "$err_specvers',<'" testouterr_cmd sh {load mod@:<} ERR "$err_rangevers':<'" testouterr_cmd sh {load mod@1/1:2} ERR "$err_specvers'1/1:2'" @@ -113,6 +115,7 @@ testouterr_cmd sh {load extdfl @1.2:} $ans {} testouterr_cmd sh {load extdfl @:1.3.1} $ans {} testouterr_cmd sh {load extdfl @:1.3.7} $ans {} testouterr_cmd sh {load extdfl @1.2:1.3} $ans {} +testouterr_cmd sh {load extdfl @1.2:1} $ans {} testouterr_cmd sh {load extdfl @1.2.3:1.3.7} $ans {} testouterr_cmd sh {load extdfl @:2.0.1} $ans {} testouterr_cmd sh {load extdfl @:2.0} $ans {} @@ -187,6 +190,18 @@ testouterr_cmd sh {spider -t ext?fl @1.3:} OK "$mp:\nextdfl/1.3.1(default)\nextd testouterr_cmd sh {avail -t e??.* @:1.4} OK "$mp:\ne.t.fl/1.3.1\ne.t.fl/1.3.7\ne.t.fl/1.4.5" # additional version tests +# Abbreviated upper bounds apply independently of extended defaults. +foreach extdfl {0 1} { + setenv_var MODULES_EXTENDED_DEFAULT $extdfl + set ans [list [list text $mp/extdfl/1.3.7] [list text $mp/extdfl/1.4.5]] + testouterr_cmd sh {paths extdfl@1.3.7:1} $ans {} + testouterr_cmd sh {paths -i EXTDFL@1.3.7:1} $ans {} + set ans [list [list text $mp/extdfl/1.3.7]] + testouterr_cmd sh {paths extdfl@1.3.7:1.3} $ans {} + testouterr_cmd sh {paths extdfl@1.3.7:1.3,9:10} $ans {} +} +unsetenv_var MODULES_EXTENDED_DEFAULT + testouterr_cmd sh {avail -t extdfl8 @1.33:} OK "$mp:\nextdfl8/1.33" testouterr_cmd sh {avail -t extdfl8 @:1.3} OK "$mp:\nextdfl8/1.3.1\nextdfl8/1.3.7" testouterr_cmd sh {spider -t extdfl8 @:1.3} OK "$mp:\nextdfl8/1.3.1\nextdfl8/1.3.7"