Skip to content

Commit 96ff24b

Browse files
authored
Merge pull request #4500 from Micket/moduledependson
Enable `module-depends-on` by default
2 parents 18d5c0b + 197f459 commit 96ff24b

File tree

9 files changed

+106
-56
lines changed

9 files changed

+106
-56
lines changed

easybuild/framework/easyblock.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,8 @@ def make_devel_module(self, create_in_builddir=False):
12191219
# these should be all the dependencies and we should load them
12201220
recursive_unload = self.cfg['recursive_module_unload']
12211221
depends_on = self.cfg['module_depends_on']
1222+
if depends_on is not None:
1223+
self.log.deprecated("'module_depends_on' easyconfig parameter should not be used anymore", '6.0')
12221224
for key in os.environ:
12231225
# legacy support
12241226
if key.startswith(DEVEL_ENV_VAR_NAME_PREFIX):
@@ -1346,6 +1348,8 @@ def make_module_dep(self, unload_info=None):
13461348
# include load statements for retained dependencies
13471349
recursive_unload = self.cfg['recursive_module_unload']
13481350
depends_on = self.cfg['module_depends_on']
1351+
if depends_on is not None:
1352+
self.log.deprecated("'module_depends_on' easyconfig parameter should not be used anymore", '6.0')
13491353
loads = []
13501354
for dep in deps:
13511355
unload_modules = []

easybuild/framework/easyconfig/default.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@
206206
'moduleclass': [MODULECLASS_BASE, 'Module class to be used for this software', MODULES],
207207
'moduleforceunload': [False, 'Force unload of all modules when loading the extension', MODULES],
208208
'moduleloadnoconflict': [False, "Don't check for conflicts, unload other versions instead ", MODULES],
209-
'module_depends_on': [False, 'Use depends_on (Lmod 7.6.1+) for dependencies in generated module '
210-
'(implies recursive unloading of modules).', MODULES],
209+
'module_depends_on': [None, 'Use depends_on (Lmod 7.6.1+) for dependencies in generated module '
210+
'(implies recursive unloading of modules) [DEPRECATED]', MODULES],
211211
'recursive_module_unload': [None, "Recursive unload of all dependencies when unloading module "
212212
"(True/False to hard enable/disable; None implies honoring "
213213
"the --recursive-module-unload EasyBuild configuration setting",

easybuild/tools/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
422422
'command_line',
423423
'external_modules_metadata',
424424
'extra_ec_paths',
425+
'mod_depends_on', # deprecated
425426
'robot_path',
426427
'valid_module_classes',
427428
'valid_stops',
428429
],
429430
False: [
430431
'dry_run',
431-
'mod_depends_on',
432432
'recursive_mod_unload',
433433
'retain_all_deps',
434434
'silent',

easybuild/tools/module_generator.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -484,13 +484,13 @@ def getenv_cmd(self, envvar, default=None):
484484
"""
485485
raise NotImplementedError
486486

487-
def load_module(self, mod_name, recursive_unload=False, depends_on=False, unload_modules=None, multi_dep_mods=None):
487+
def load_module(self, mod_name, recursive_unload=False, depends_on=None, unload_modules=None, multi_dep_mods=None):
488488
"""
489489
Generate load statement for specified module.
490490
491491
:param mod_name: name of module to generate load statement for
492492
:param recursive_unload: boolean indicating whether the 'load' statement should be reverted on unload
493-
:param depends_on: use depends_on statements rather than (guarded) load statements
493+
:param depends_on: use depends_on statements rather than (guarded) load statements (DEPRECATED)
494494
:param unload_modules: name(s) of module to unload first
495495
:param multi_dep_mods: list of module names in multi_deps context, to use for guarding load statement
496496
"""
@@ -879,14 +879,14 @@ def getenv_cmd(self, envvar, default=None):
879879
cmd = '[if { [info exists %(envvar)s] } { concat $%(envvar)s } else { concat "%(default)s" } ]' % values
880880
return cmd
881881

882-
def load_module(self, mod_name, recursive_unload=None, depends_on=False, unload_modules=None, multi_dep_mods=None):
882+
def load_module(self, mod_name, recursive_unload=None, depends_on=None, unload_modules=None, multi_dep_mods=None):
883883
"""
884884
Generate load statement for specified module.
885885
886886
:param mod_name: name of module to generate load statement for
887887
:param recursive_unload: boolean indicating whether the 'load' statement should be reverted on unload
888888
(if None: enable if recursive_mod_unload build option or depends_on is True)
889-
:param depends_on: use depends_on statements rather than (guarded) load statements
889+
:param depends_on: use depends_on statements rather than (guarded) load statements (DEPRECATED)
890890
:param unload_modules: name(s) of module to unload first
891891
:param multi_dep_mods: list of module names in multi_deps context, to use for guarding load statement
892892
"""
@@ -895,7 +895,10 @@ def load_module(self, mod_name, recursive_unload=None, depends_on=False, unload_
895895
body.extend([self.unload_module(m).strip() for m in unload_modules])
896896
load_template = self.LOAD_TEMPLATE
897897
# Lmod 7.6.1+ supports depends-on which does this most nicely:
898-
if build_option('mod_depends_on') or depends_on:
898+
if (build_option('mod_depends_on') and self.modules_tool.supports_depends_on) or depends_on:
899+
if depends_on is not None:
900+
depr_msg = "'depends_on' argument of module generator method 'load_module' should not be used anymore"
901+
self.log.deprecated(depr_msg, '6.0')
899902
if not self.modules_tool.supports_depends_on:
900903
raise EasyBuildError("depends-on statements in generated module are not supported by modules tool")
901904
load_template = self.LOAD_TEMPLATE_DEPENDS_ON
@@ -1304,14 +1307,14 @@ def getenv_cmd(self, envvar, default=None):
13041307
cmd = 'os.getenv("%s") or "%s"' % (envvar, default)
13051308
return cmd
13061309

1307-
def load_module(self, mod_name, recursive_unload=None, depends_on=False, unload_modules=None, multi_dep_mods=None):
1310+
def load_module(self, mod_name, recursive_unload=None, depends_on=None, unload_modules=None, multi_dep_mods=None):
13081311
"""
13091312
Generate load statement for specified module.
13101313
13111314
:param mod_name: name of module to generate load statement for
13121315
:param recursive_unload: boolean indicating whether the 'load' statement should be reverted on unload
13131316
(if None: enable if recursive_mod_unload build option or depends_on is True)
1314-
:param depends_on: use depends_on statements rather than (guarded) load statements
1317+
:param depends_on: use depends_on statements rather than (guarded) load statements (DEPRECATED)
13151318
:param unload_modules: name(s) of module to unload first
13161319
:param multi_dep_mods: list of module names in multi_deps context, to use for guarding load statement
13171320
"""
@@ -1321,7 +1324,10 @@ def load_module(self, mod_name, recursive_unload=None, depends_on=False, unload_
13211324

13221325
load_template = self.LOAD_TEMPLATE
13231326
# Lmod 7.6+ supports depends_on which does this most nicely:
1324-
if build_option('mod_depends_on') or depends_on:
1327+
if (build_option('mod_depends_on') and self.modules_tool.supports_depends_on) or depends_on:
1328+
if depends_on is not None:
1329+
depr_msg = "'depends_on' argument of module generator method 'load_module' should not be used anymore"
1330+
self.log.deprecated(depr_msg, '6.0')
13251331
if not self.modules_tool.supports_depends_on:
13261332
raise EasyBuildError("depends_on statements in generated module are not supported by modules tool")
13271333
load_template = self.LOAD_TEMPLATE_DEPENDS_ON

easybuild/tools/options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ def config_options(self):
598598
'strtuple', 'store', DEFAULT_LOGFILE_FORMAT[:], {'metavar': 'DIR,FORMAT'}),
599599
'module-depends-on': ("Use depends_on (Lmod 7.6.1+) for dependencies in all generated modules "
600600
"(implies recursive unloading of modules).",
601-
None, 'store_true', False),
601+
None, 'store_true', True),
602602
'module-extensions': ("Include 'extensions' statement in generated module file (Lua syntax only)",
603603
None, 'store_true', True),
604604
'module-naming-scheme': ("Module naming scheme to use", None, 'store', DEFAULT_MNS),

test/framework/easyblock.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -873,10 +873,10 @@ def test_make_module_dep_hmns(self):
873873
with self.mocked_stdout_stderr():
874874
mod_dep_txt = eb.make_module_dep()
875875
for mod in ['GCC/6.4.0-2.28', 'OpenMPI/2.1.2']:
876-
regex = re.compile('load.*%s' % mod)
876+
regex = re.compile('(load|depends[-_]on).*%s' % mod)
877877
self.assertFalse(regex.search(mod_dep_txt), "Pattern '%s' found in: %s" % (regex.pattern, mod_dep_txt))
878878

879-
regex = re.compile('load.*FFTW/3.3.7')
879+
regex = re.compile('(load|depends[-_]on).*FFTW/3.3.7')
880880
self.assertTrue(regex.search(mod_dep_txt), "Pattern '%s' found in: %s" % (regex.pattern, mod_dep_txt))
881881

882882
def test_make_module_dep_of_dep_hmns(self):
@@ -1361,27 +1361,27 @@ def test_make_module_step(self):
13611361

13621362
for (name, ver) in [('GCC', '6.4.0-2.28')]:
13631363
if get_module_syntax() == 'Tcl':
1364-
regex = re.compile(r'^\s*module load %s\s*$' % os.path.join(name, ver), re.M)
1364+
regex = re.compile(r'^\s*(module load|depends-on) %s\s*$' % os.path.join(name, ver), re.M)
13651365
elif get_module_syntax() == 'Lua':
1366-
regex = re.compile(r'^\s*load\("%s"\)$' % os.path.join(name, ver), re.M)
1366+
regex = re.compile(r'^\s*(load|depends_on)\("%s"\)$' % os.path.join(name, ver), re.M)
13671367
else:
13681368
self.fail("Unknown module syntax: %s" % get_module_syntax())
13691369
self.assertTrue(regex.search(txt), "Pattern %s found in %s" % (regex.pattern, txt))
13701370

13711371
for (name, ver) in [('test', '1.2.3')]:
13721372
if get_module_syntax() == 'Tcl':
1373-
regex = re.compile(r'^\s*module load %s/.%s\s*$' % (name, ver), re.M)
1373+
regex = re.compile(r'^\s*(module load|depends-on) %s/.%s\s*$' % (name, ver), re.M)
13741374
elif get_module_syntax() == 'Lua':
1375-
regex = re.compile(r'^\s*load\("%s/.%s"\)$' % (name, ver), re.M)
1375+
regex = re.compile(r'^\s*(load|depends_on)\("%s/.%s"\)$' % (name, ver), re.M)
13761376
else:
13771377
self.fail("Unknown module syntax: %s" % get_module_syntax())
13781378
self.assertTrue(regex.search(txt), "Pattern %s found in %s" % (regex.pattern, txt))
13791379

13801380
for (name, ver) in [('OpenMPI', '2.1.2-GCC-6.4.0-2.28')]:
13811381
if get_module_syntax() == 'Tcl':
1382-
regex = re.compile(r'^\s*module load %s/.?%s\s*$' % (name, ver), re.M)
1382+
regex = re.compile(r'^\s*(module load|depends-on) %s/.?%s\s*$' % (name, ver), re.M)
13831383
elif get_module_syntax() == 'Lua':
1384-
regex = re.compile(r'^\s*load\("%s/.?%s"\)$' % (name, ver), re.M)
1384+
regex = re.compile(r'^\s*(load|depends_on)\("%s/.?%s"\)$' % (name, ver), re.M)
13851385
else:
13861386
self.fail("Unknown module syntax: %s" % get_module_syntax())
13871387
self.assertFalse(regex.search(txt), "Pattern '%s' *not* found in %s" % (regex.pattern, txt))

test/framework/easyconfig.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4785,6 +4785,10 @@ def test_recursive_module_unload(self):
47854785
toy_ec = os.path.join(test_ecs_dir, 'f', 'foss', 'foss-2018a.eb')
47864786
test_ec = os.path.join(self.test_prefix, 'test.eb')
47874787
test_ec_txt = read_file(toy_ec)
4788+
4789+
# this test only makes sense if depends_on is not used
4790+
self.allow_deprecated_behaviour()
4791+
test_ec_txt += '\nmodule_depends_on = False'
47884792
write_file(test_ec, test_ec_txt)
47894793

47904794
test_module = os.path.join(self.test_installpath, 'modules', 'all', 'foss', '2018a')
@@ -4827,6 +4831,8 @@ def test_recursive_module_unload(self):
48274831
# recursive_module_unload easyconfig parameter is honored
48284832
test_ec_bis = os.path.join(self.test_prefix, 'test_bis.eb')
48294833
test_ec_bis_txt = read_file(toy_ec) + '\nrecursive_module_unload = True'
4834+
# this test only makes sense if depends_on is not used
4835+
test_ec_bis_txt += '\nmodule_depends_on = False'
48304836
write_file(test_ec_bis, test_ec_bis_txt)
48314837

48324838
ec_bis = EasyConfig(test_ec_bis)
@@ -4871,6 +4877,8 @@ def test_recursive_module_unload(self):
48714877
self.assertTrue(build_option('recursive_mod_unload'))
48724878
test_ec_bis = os.path.join(self.test_prefix, 'test_bis.eb')
48734879
test_ec_bis_txt = read_file(toy_ec) + '\nrecursive_module_unload = False'
4880+
# this test only makes sense if depends_on is not used
4881+
test_ec_bis_txt += '\nmodule_depends_on = False'
48744882
write_file(test_ec_bis, test_ec_bis_txt)
48754883
ec_bis = EasyConfig(test_ec_bis)
48764884
self.assertEqual(ec_bis['recursive_module_unload'], False)

test/framework/module_generator.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -298,20 +298,25 @@ def test_load(self):
298298
self.assertEqual(expected, self.modgen.load_module("mod_name"))
299299

300300
# Lmod 7.6+ depends-on
301+
302+
self.allow_deprecated_behaviour()
303+
301304
if self.modtool.supports_depends_on:
302305
expected = '\n'.join([
303306
'',
304307
"depends-on mod_name",
305308
'',
306309
])
307-
self.assertEqual(expected, self.modgen.load_module("mod_name", depends_on=True))
310+
with self.mocked_stdout_stderr():
311+
txt = self.modgen.load_module("mod_name", depends_on=True)
312+
self.assertEqual(expected, txt)
308313
init_config(build_options={'mod_depends_on': 'True'})
309314
self.assertEqual(expected, self.modgen.load_module("mod_name"))
310315
else:
311316
expected = "depends-on statements in generated module are not supported by modules tool"
312-
self.assertErrorRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name", depends_on=True)
313-
init_config(build_options={'mod_depends_on': 'True'})
314-
self.assertErrorRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name")
317+
with self.mocked_stdout_stderr():
318+
self.assertErrorRegex(EasyBuildError, expected,
319+
self.modgen.load_module, "mod_name", depends_on=True)
315320
else:
316321
# default: guarded module load (which implies no recursive unloading)
317322
expected = '\n'.join([
@@ -338,20 +343,26 @@ def test_load(self):
338343
self.assertEqual(expected, self.modgen.load_module("mod_name"))
339344

340345
# Lmod 7.6+ depends_on
346+
347+
self.allow_deprecated_behaviour()
348+
341349
if self.modtool.supports_depends_on:
342350
expected = '\n'.join([
343351
'',
344352
'depends_on("mod_name")',
345353
'',
346354
])
347-
self.assertEqual(expected, self.modgen.load_module("mod_name", depends_on=True))
355+
with self.mocked_stdout_stderr():
356+
txt = self.modgen.load_module("mod_name", depends_on=True)
357+
358+
self.assertEqual(expected, txt)
348359
init_config(build_options={'mod_depends_on': 'True'})
349360
self.assertEqual(expected, self.modgen.load_module("mod_name"))
350361
else:
351362
expected = "depends_on statements in generated module are not supported by modules tool"
352-
self.assertErrorRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name", depends_on=True)
353-
init_config(build_options={'mod_depends_on': 'True'})
354-
self.assertErrorRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name")
363+
with self.mocked_stdout_stderr():
364+
self.assertErrorRegex(EasyBuildError, expected,
365+
self.modgen.load_module, "mod_name", depends_on=True)
355366

356367
def test_load_multi_deps(self):
357368
"""Test generated load statement when multi_deps is involved."""
@@ -390,8 +401,12 @@ def test_load_multi_deps(self):
390401
self.assertEqual(expected, res)
391402

392403
if self.modtool.supports_depends_on:
404+
405+
self.allow_deprecated_behaviour()
406+
393407
# two versions with depends_on
394-
res = self.modgen.load_module('Python/3.7.4', multi_dep_mods=multi_dep_mods, depends_on=True)
408+
with self.mocked_stdout_stderr():
409+
res = self.modgen.load_module('Python/3.7.4', multi_dep_mods=multi_dep_mods, depends_on=True)
395410

396411
if self.MODULE_GENERATOR_CLASS == ModuleGeneratorTcl:
397412
expected = '\n'.join([
@@ -415,6 +430,8 @@ def test_load_multi_deps(self):
415430
])
416431
self.assertEqual(expected, res)
417432

433+
self.disallow_deprecated_behaviour()
434+
418435
# now test with more than two versions...
419436
multi_dep_mods = ['foo/1.2.3', 'foo/2.3.4', 'foo/3.4.5', 'foo/4.5.6']
420437
res = self.modgen.load_module('foo/1.2.3', multi_dep_mods=multi_dep_mods)
@@ -452,8 +469,12 @@ def test_load_multi_deps(self):
452469
self.assertEqual(expected, res)
453470

454471
if self.modtool.supports_depends_on:
472+
473+
self.allow_deprecated_behaviour()
474+
455475
# more than two versions, with depends_on
456-
res = self.modgen.load_module('foo/1.2.3', multi_dep_mods=multi_dep_mods, depends_on=True)
476+
with self.mocked_stdout_stderr():
477+
res = self.modgen.load_module('foo/1.2.3', multi_dep_mods=multi_dep_mods, depends_on=True)
457478

458479
if self.MODULE_GENERATOR_CLASS == ModuleGeneratorTcl:
459480
expected = '\n'.join([
@@ -479,6 +500,8 @@ def test_load_multi_deps(self):
479500
])
480501
self.assertEqual(expected, res)
481502

503+
self.disallow_deprecated_behaviour()
504+
482505
# what if we only list a single version?
483506
# see https://github.com/easybuilders/easybuild-framework/issues/3080
484507
res = self.modgen.load_module('one/1.0', multi_dep_mods=['one/1.0'])
@@ -505,7 +528,11 @@ def test_load_multi_deps(self):
505528
self.assertEqual(expected, res)
506529

507530
if self.modtool.supports_depends_on:
508-
res = self.modgen.load_module('one/1.0', multi_dep_mods=['one/1.0'], depends_on=True)
531+
532+
self.allow_deprecated_behaviour()
533+
534+
with self.mocked_stdout_stderr():
535+
res = self.modgen.load_module('one/1.0', multi_dep_mods=['one/1.0'], depends_on=True)
509536

510537
if self.MODULE_GENERATOR_CLASS == ModuleGeneratorTcl:
511538
expected = '\ndepends-on one/1.0\n'

0 commit comments

Comments
 (0)