Skip to content

Commit 17edf1a

Browse files
victorusualalazo
andcommitted
Add setdefault option to tcl module (spack#14686)
This commit introduces the command spack module tcl setdefault <package> similar to the one already available for lmod Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
1 parent 79fd1c5 commit 17edf1a

File tree

5 files changed

+79
-19
lines changed

5 files changed

+79
-19
lines changed

lib/spack/spack/cmd/modules/lmod.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
55

66
import functools
7-
import os
8-
9-
import llnl.util.filesystem
107

118
import spack.cmd.common.arguments
129
import spack.cmd.modules
10+
import spack.config
11+
import spack.modules.lmod
1312

1413

1514
def add_command(parser, command_dict):
@@ -41,12 +40,19 @@ def setdefault(module_type, specs, args):
4140
# https://lmod.readthedocs.io/en/latest/060_locating.html#marking-a-version-as-default
4241
#
4342
spack.cmd.modules.one_spec_or_raise(specs)
44-
writer = spack.modules.module_types['lmod'](
45-
specs[0], args.module_set_name)
46-
47-
module_folder = os.path.dirname(writer.layout.filename)
48-
module_basename = os.path.basename(writer.layout.filename)
49-
with llnl.util.filesystem.working_dir(module_folder):
50-
if os.path.exists('default') and os.path.islink('default'):
51-
os.remove('default')
52-
os.symlink(module_basename, 'default')
43+
spec = specs[0]
44+
data = {
45+
'modules': {
46+
args.module_set_name: {
47+
'lmod': {
48+
'defaults': [str(spec)]
49+
}
50+
}
51+
}
52+
}
53+
# Need to clear the cache if a SpackCommand is called during scripting
54+
spack.modules.lmod.configuration_registry = {}
55+
scope = spack.config.InternalConfigScope('lmod-setdefault', data)
56+
with spack.config.override(scope):
57+
writer = spack.modules.module_types['lmod'](spec, args.module_set_name)
58+
writer.update_module_defaults()

lib/spack/spack/cmd/modules/tcl.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,52 @@
22
# Spack Project Developers. See the top-level COPYRIGHT file for details.
33
#
44
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
5-
65
import functools
76

7+
import spack.cmd.common.arguments
88
import spack.cmd.modules
9+
import spack.config
10+
import spack.modules.tcl
911

1012

1113
def add_command(parser, command_dict):
1214
tcl_parser = parser.add_parser(
1315
'tcl', help='manipulate non-hierarchical module files'
1416
)
15-
spack.cmd.modules.setup_parser(tcl_parser)
17+
sp = spack.cmd.modules.setup_parser(tcl_parser)
18+
19+
# Set default module file for a package
20+
setdefault_parser = sp.add_parser(
21+
'setdefault', help='set the default module file for a package'
22+
)
23+
spack.cmd.common.arguments.add_common_arguments(
24+
setdefault_parser, ['constraint']
25+
)
26+
27+
callbacks = dict(spack.cmd.modules.callbacks.items())
28+
callbacks['setdefault'] = setdefault
1629

1730
command_dict['tcl'] = functools.partial(
18-
spack.cmd.modules.modules_cmd, module_type='tcl'
31+
spack.cmd.modules.modules_cmd, module_type='tcl', callbacks=callbacks
1932
)
33+
34+
35+
def setdefault(module_type, specs, args):
36+
"""Set the default module file, when multiple are present"""
37+
# Currently, accepts only a single matching spec
38+
spack.cmd.modules.one_spec_or_raise(specs)
39+
spec = specs[0]
40+
data = {
41+
'modules': {
42+
args.module_set_name: {
43+
'tcl': {
44+
'defaults': [str(spec)]
45+
}
46+
}
47+
}
48+
}
49+
spack.modules.tcl.configuration_registry = {}
50+
scope = spack.config.InternalConfigScope('tcl-setdefault', data)
51+
with spack.config.override(scope):
52+
writer = spack.modules.module_types['tcl'](spec, args.module_set_name)
53+
writer.update_module_defaults()

lib/spack/spack/modules/common.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,9 @@ def write(self, overwrite=False):
906906
fp.set_permissions_by_spec(self.layout.filename, self.spec)
907907

908908
# Symlink defaults if needed
909+
self.update_module_defaults()
910+
911+
def update_module_defaults(self):
909912
if any(self.spec.satisfies(default) for default in self.conf.defaults):
910913
# This spec matches a default, it needs to be symlinked to default
911914
# Symlink to a tmp location first and move, so that existing

lib/spack/spack/test/cmd/module.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,18 @@ def test_loads_recursive_blacklisted(database, module_configuration):
178178

179179
@pytest.mark.db
180180
def test_setdefault_command(
181-
mutable_database, module_configuration
181+
mutable_database, mutable_config
182182
):
183-
module_configuration('autoload_direct')
184-
183+
data = {
184+
'default': {
185+
'enable': ['lmod'],
186+
'lmod': {
187+
'core_compilers': ['clang@3.3'],
188+
'hierarchy': ['mpi']
189+
}
190+
}
191+
}
192+
spack.config.set('modules', data)
185193
# Install two different versions of a package
186194
other_spec, preferred = 'a@1.0', 'a@2.0'
187195

share/spack/spack-completion.bash

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,7 @@ _spack_module_tcl() {
13821382
then
13831383
SPACK_COMPREPLY="-h --help -n --name"
13841384
else
1385-
SPACK_COMPREPLY="refresh find rm loads"
1385+
SPACK_COMPREPLY="refresh find rm loads setdefault"
13861386
fi
13871387
}
13881388

@@ -1422,6 +1422,15 @@ _spack_module_tcl_loads() {
14221422
fi
14231423
}
14241424

1425+
_spack_module_tcl_setdefault() {
1426+
if $list_options
1427+
then
1428+
SPACK_COMPREPLY="-h --help"
1429+
else
1430+
_installed_packages
1431+
fi
1432+
}
1433+
14251434
_spack_monitor() {
14261435
SPACK_COMPREPLY="-h --help --monitor --monitor-save-local --monitor-no-auth --monitor-tags --monitor-keep-going --monitor-host --monitor-prefix"
14271436
}

0 commit comments

Comments
 (0)