Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ Modules 5.7.0 (not yet released)
test suite run is aborted.
* Correctly match loaded modules specified as requirement with a trailing
``/`` character after module name. (fix issue #640)
* Also consider ``-`` in addition to ``.`` as a version number separator
character when selecting a module with the :mconfig:`extended_default`
mechanism. (fix issue #619)


.. _5.6 release notes:
Expand Down
3 changes: 3 additions & 0 deletions doc/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,9 @@ Starting version 5.5, characters ``+`` and ``~`` may be part of module name or
version as long as the string part next to these character is not a valid
variant name.

Starting version 5.7, character ``-`` is considered a version number separator
for :mconfig:`extended_default` mechanism.

Environment
"""""""""""

Expand Down
7 changes: 4 additions & 3 deletions doc/source/design/extended-default.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ Specification
- query soft/1 returns nothing
- query soft/10.1.2 returns highest among soft/10.1.2.4 soft/10.1.2.3

- In situation where soft/1.1(default) soft/1.2 soft/2.1 soft/2.2
- In situation where soft/1.1(default) soft/1.2 soft/2.1 soft/2.2 soft/3.4-ad75bc9a

- query soft/1 returns soft/1.1
- query soft/2 returns soft/2.2
- query soft/3.4 returns soft/3.4-ad75bc9a

- Character considered as version number separator: ``.``
- Characters considered as version number separator: ``.`` and ``-``

- list: ``.`` and ``-``
- ``-`` was also considered initially, but cannot determine in all case the highest version specified after this character (may find a hash name, strings like *rc*, *alpha*, *beta*, etc)
- ``-`` is considered a version number separator character since version 5.7
- not possible with ``+`` as it is used by variant specification

- Does not apply to the root part of module name
Expand Down
12 changes: 8 additions & 4 deletions doc/source/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3146,8 +3146,9 @@ Constraints can be expressed to refine the selection of module version to:
Advanced specification of single version or list of versions may benefit from
the activation of the extended default mechanism (see
:envvar:`MODULES_EXTENDED_DEFAULT`) to use an abbreviated notation like ``@1``
to refer to more precise version numbers like ``1.2.3``. Range of versions on
its side natively handles abbreviated versions.
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.

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
Expand Down Expand Up @@ -5008,9 +5009,9 @@ ENVIRONMENT

If set to ``1``, a specified module version is matched against starting
portion of existing module versions, where portion is a substring separated
from the rest of the version string by a ``.`` character. For example
from the rest of the version string by ``.`` or ``-`` characters. For example
specified modules ``mod/1`` and ``mod/1.2`` will match existing modulefile
``mod/1.2.3``.
``mod/1.2.3`` and ``mod/2.4`` will match ``mod/2.4-91db5cf2``.

In case multiple modulefiles match the specified module version and a single
module has to be selected, the explicitly set default version is returned if
Expand All @@ -5026,6 +5027,9 @@ ENVIRONMENT

.. versionadded:: 4.4

.. versionchanged:: 5.7
Character ``-`` is also considered a version number separator

.. envvar:: MODULES_FAMILY_<NAME>

Module name minus version that provides for the *name* family in currently
Expand Down
11 changes: 8 additions & 3 deletions doc/source/modulefile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1949,8 +1949,8 @@ The equivalent :file:`.modulerc` would look like:
If the extended default mechanism is enabled (see
:envvar:`MODULES_EXTENDED_DEFAULT` in :ref:`module(1)`) the module version
specified is matched against starting portion of existing module versions,
where portion is a substring separated from the rest of version string by a
``.`` character.
where portion is a substring separated from the rest of version string by
``.`` or ``-`` characters.

When the implicit default mechanism and the `Advanced module version
specifiers`_ are both enabled, a ``default`` and ``latest`` symbolic versions
Expand Down Expand Up @@ -2081,7 +2081,9 @@ Advanced specification of single version or list of versions may benefit from
the activation of the extended default mechanism (see
:envvar:`MODULES_EXTENDED_DEFAULT` in :ref:`module(1)`) to use an abbreviated
notation like ``@1`` to refer to more precise version numbers like ``1.2.3``.
Range of versions on its side natively handles abbreviated versions.
Characters ``.`` and ``-`` are considered version number separator to
determine abbreviated versions. Range of versions on its side natively handles
abbreviated versions.

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
Expand Down Expand Up @@ -2109,6 +2111,9 @@ version will be selected.
.. versionchanged:: 4.8
Use of version range is allowed in version list

.. versionchanged:: 5.7
Character ``-`` is also considered a version number separator

Variants
^^^^^^^^

Expand Down
63 changes: 39 additions & 24 deletions tcl/modspec.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ proc defineDoesModMatchAtDepthProc {contains querydepth test} {
}
}

proc extendedDefaultCharGlobMatch {} {
return {[-.]*}
}

# Define procedure to check module version equals pattern. Adapt procedure
# code whether icase and extended_default are enabled or disabled
proc defineModVersCmpProc {icase extdfl} {
Expand Down Expand Up @@ -270,6 +274,7 @@ proc defineModVersCmpProc {icase extdfl} {
# alternative definitions of modVersCmp proc
proc modVersCmpProc {cmpspec versspec modvers test {psuf {}}} {
set ret 0
set echar [extendedDefaultCharGlobMatch]
switch -- $cmpspec {
in {
# check each verspec in list until match
Expand All @@ -295,26 +300,27 @@ proc modVersCmpProc {cmpspec versspec modvers test {psuf {}}} {
# are always extended_default-enabled (as 1.2 includes 1.2.12 for
# instance) and equal, eqstart and match tests are equivalent
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$versspec] != -1 || [string match $versspec.* $modvers])}]
$versspec] != -1 || [string match $versspec$echar $modvers])}]
}
le {
# 'ge' comment also applies here
set ret [expr {[isVersion $modvers] && ([versioncmp $versspec\
$modvers] != -1 || [string match $versspec.* $modvers])}]
$modvers] != -1 || [string match $versspec$echar $modvers])}]
}
be {
# 'ge' comment also applies here
lassign $versspec lovers hivers
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$lovers] != -1 || [string match $lovers.* $modvers]) &&\
$lovers] != -1 || [string match $lovers$echar $modvers]) &&\
([versioncmp $hivers $modvers] != -1 || [string match\
$hivers.* $modvers])}]
$hivers$echar $modvers])}]
}
}
return $ret
}
proc modVersCmpProcIcase {cmpspec versspec modvers test {psuf {}}} {
set ret 0
set echar [extendedDefaultCharGlobMatch]
switch -- $cmpspec {
in {
foreach inspec $versspec {
Expand All @@ -336,24 +342,27 @@ proc modVersCmpProcIcase {cmpspec versspec modvers test {psuf {}}} {
}
ge {
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$versspec] != -1 || [string match -nocase $versspec.* $modvers])}]
$versspec] != -1 || [string match -nocase $versspec$echar\
$modvers])}]
}
le {
set ret [expr {[isVersion $modvers] && ([versioncmp $versspec\
$modvers] != -1 || [string match -nocase $versspec.* $modvers])}]
$modvers] != -1 || [string match -nocase $versspec$echar\
$modvers])}]
}
be {
lassign $versspec lovers hivers
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$lovers] != -1 || [string match $lovers.* $modvers]) &&\
$lovers] != -1 || [string match $lovers$echar $modvers]) &&\
([versioncmp $hivers $modvers] != -1 || [string match -nocase\
$hivers.* $modvers])}]
$hivers$echar $modvers])}]
}
}
return $ret
}
proc modVersCmpProcExtdfl {cmpspec versspec modvers test {psuf {}}} {
set ret 0
set echar [extendedDefaultCharGlobMatch]
switch -- $cmpspec {
in {
foreach inspec $versspec {
Expand All @@ -372,30 +381,31 @@ proc modVersCmpProcExtdfl {cmpspec versspec modvers test {psuf {}}} {
##nagelfar ignore Non static subcommand
set ret [string $test $versspec $modvers]
}
if {!$ret && [string match $versspec.* $modvers]} {
if {!$ret && [string match $versspec$echar $modvers]} {
set ret 1
}
}
ge {
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$versspec] != -1 || [string match $versspec.* $modvers])}]
$versspec] != -1 || [string match $versspec$echar $modvers])}]
}
le {
set ret [expr {[isVersion $modvers] && ([versioncmp $versspec\
$modvers] != -1 || [string match $versspec.* $modvers])}]
$modvers] != -1 || [string match $versspec$echar $modvers])}]
}
be {
lassign $versspec lovers hivers
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$lovers] != -1 || [string match $lovers.* $modvers]) &&\
$lovers] != -1 || [string match $lovers$echar $modvers]) &&\
([versioncmp $hivers $modvers] != -1 || [string match\
$hivers.* $modvers])}]
$hivers$echar $modvers])}]
}
}
return $ret
}
proc modVersCmpProcIcaseExtdfl {cmpspec versspec modvers test {psuf {}}} {
set ret 0
set echar [extendedDefaultCharGlobMatch]
switch -- $cmpspec {
in {
foreach inspec $versspec {
Expand All @@ -414,24 +424,26 @@ proc modVersCmpProcIcaseExtdfl {cmpspec versspec modvers test {psuf {}}} {
##nagelfar ignore Non static subcommand
set ret [string $test -nocase $versspec $modvers]
}
if {!$ret && [string match -nocase $versspec.* $modvers]} {
if {!$ret && [string match -nocase $versspec$echar $modvers]} {
set ret 1
}
}
ge {
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$versspec] != -1 || [string match -nocase $versspec.* $modvers])}]
$versspec] != -1 || [string match -nocase $versspec$echar\
$modvers])}]
}
le {
set ret [expr {[isVersion $modvers] && ([versioncmp $versspec\
$modvers] != -1 || [string match -nocase $versspec.* $modvers])}]
$modvers] != -1 || [string match -nocase $versspec$echar\
$modvers])}]
}
be {
lassign $versspec lovers hivers
set ret [expr {[isVersion $modvers] && ([versioncmp $modvers\
$lovers] != -1 || [string match $lovers.* $modvers]) &&\
$lovers] != -1 || [string match $lovers$echar $modvers]) &&\
([versioncmp $hivers $modvers] != -1 || [string match -nocase\
$hivers.* $modvers])}]
$hivers$echar $modvers])}]
}
}
return $ret
Expand Down Expand Up @@ -536,10 +548,11 @@ proc defineModEqStaticProc {icase extdfl modspec} {
append procbody "
if {!\$ret && \[string first / \$pmod\] != -1} {
if {\$test eq {match}} {
set pmodextdfl \$pmod.*
set pmodextdfl \$pmod
} else {
set pmodextdfl {$pmodescglob.*}
set pmodextdfl {$pmodescglob}
}
append pmodextdfl \[extendedDefaultCharGlobMatch\]
set ret \[string match $nocasearg\$pmodextdfl \$mod\]
}"
}
Expand Down Expand Up @@ -958,10 +971,11 @@ proc modEqProcExtdfl {pattern mod {test equal} {trspec 1} {ismodlo 0} {vrcmp\
# try the extended default match if not root module and not eqspec test
if {![info exists eqspec] && !$ret && [string first / $pmod] != -1} {
if {$test eq {match}} {
set pmodextdfl $pmod.*
set pmodextdfl $pmod
} else {
set pmodextdfl $pmodescglob.*
set pmodextdfl $pmodescglob
}
append pmodextdfl [extendedDefaultCharGlobMatch]
set ret [string match $pmodextdfl $mod]
if {!$ret && [llength $altlist]} {
foreach alt $altlist {
Expand Down Expand Up @@ -1107,10 +1121,11 @@ proc modEqProcIcaseExtdfl {pattern mod {test equal} {trspec 1} {ismodlo 0}\
# try the extended default match if not root module and not eqspec test
if {![info exists eqspec] && !$ret && [string first / $pmod] != -1} {
if {$test eq {match}} {
set pmodextdfl $pmod.*
set pmodextdfl $pmod
} else {
set pmodextdfl $pmodescglob.*
set pmodextdfl $pmodescglob
}
append pmodextdfl [extendedDefaultCharGlobMatch]
set ret [string match -nocase $pmodextdfl $mod]
if {!$ret && [llength $altlist]} {
foreach alt $altlist {
Expand Down
2 changes: 1 addition & 1 deletion testsuite/modules.70-maint/260-extended_default.exp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ setenv_var MODULES_EXTENDED_DEFAULT 1

# test over different kind of module versions
array set exactmatch [list extdfl/1.1.0 1 extdfl/2.0 1]
foreach {query match} [list extdfl/1 extdfl/1.3.1 extdfl/1.0 extdfl/1.0.2 extdfl/1.0.0 ERR extdfl/1.1 extdfl/1.1.0-beta extdfl/1.1.0 extdfl/1.1.0 extdfl/1.2 extdfl/1.2.10 extdfl/1.3 extdfl/1.3.1 extdfl/1.4 extdfl/1.4.5 ext*l/1.4 ERR ext?fl/1.4 ERR extdfl/2 extdfl/2.0.1 extdfl/2.0 extdfl/2.0 extdfl2/3.0 extdfl2/3.0.15 extdfl2/3 extdfl2/3.10.2 extdfl2/3.1 extdfl2/3.1.7 extdfl2/3.9 extdfl2/3.9.2 extdfl2/3.09 extdfl2/3.09.3 extdfl3/1 extdfl3/1.3/4 extdflb ERR extdflb.4 ERR extdflc ERR e.t.fl/1.4 e.t.fl/1.4.5 e??.*/1.4 ERR] {
foreach {query match} [list extdfl/1 extdfl/1.3.1 extdfl/1.0 extdfl/1.0.2 extdfl/1.0.0 extdfl/1.0.0-beta extdfl/1.1 extdfl/1.1.0-beta extdfl/1.1.0 extdfl/1.1.0 extdfl/1.2 extdfl/1.2.10 extdfl/1.3 extdfl/1.3.1 extdfl/1.4 extdfl/1.4.5 ext*l/1.4 ERR ext?fl/1.4 ERR extdfl/2 extdfl/2.0.1 extdfl/2.0 extdfl/2.0 extdfl2/3.0 extdfl2/3.0.15 extdfl2/3 extdfl2/3.10.2 extdfl2/3.1 extdfl2/3.1.7 extdfl2/3.9 extdfl2/3.9.2 extdfl2/3.09 extdfl2/3.09.3 extdfl3/1 extdfl3/1.3/4 extdflb ERR extdflb.4 ERR extdflc ERR e.t.fl/1.4 e.t.fl/1.4.5 e??.*/1.4 ERR] {
if {$match eq {ERR}} {
set ans ERR
set tserr $err_path'$query'
Expand Down
Loading