Skip to content
Open
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
9 changes: 6 additions & 3 deletions easybuild/framework/easyconfig/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@
'sanity_check_commands': [[], ("format: [(name, options)] e.g. [('gzip','-h')]. "
"Using a non-tuple is equivalent to (name, '-h')"), BUILD],
'sanity_check_paths': [{}, ("List of files and directories to check "
"(format: {'files':<list>, 'dirs':<list>})"), BUILD],
"(format: {'files':<list>, 'dirs':<list>}). "
"Architecture specific list items are supported."), BUILD],
'skip': [False, "Skip existing software", BUILD],
'skip_mod_files_sanity_check': [False, "Skip the check for .mod files in a GCCcore level install", BUILD],
'skipsteps': [[], "Skip these steps", BUILD],
Expand Down Expand Up @@ -169,8 +170,10 @@

# DEPENDENCIES easyconfig parameters
'allow_system_deps': [[], "Allow listed system dependencies (format: (<name>, <version>))", DEPENDENCIES],
'builddependencies': [[], "List of build dependencies", DEPENDENCIES],
'dependencies': [[], "List of dependencies", DEPENDENCIES],
'builddependencies': [[], ("List of build dependencies Architecture specific versions are supported "
"with 'False' to exclude the dependency"), DEPENDENCIES],
'dependencies': [[], ("List of dependencies. Architecture specific versions are supported "
"with 'False' to exclude the dependency"), DEPENDENCIES],
'hiddendependencies': [[], "List of dependencies available as hidden modules", DEPENDENCIES],
'multi_deps': [{}, "Dict of lists of dependency versions over which to iterate", DEPENDENCIES],
'multi_deps_load_default': [True, "Load module for first version listed in multi_deps by default", DEPENDENCIES],
Expand Down
14 changes: 8 additions & 6 deletions easybuild/framework/easyconfig/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,15 @@ def template_constant_dict(config, ignore=None, toolchain=None):
if isinstance(dep_name, str) and dep_version:
pref = name_to_prefix.get(dep_name.lower())
if pref:
# Resolve version if not already done
dep_version = pick_dep_version(dep_version)
template_values['%sver' % pref] = dep_version
dep_version_parts = dep_version.split('.')
template_values['%smajver' % pref] = dep_version_parts[0]
if len(dep_version_parts) > 1:
template_values['%sminver' % pref] = dep_version_parts[1]
template_values['%sshortver' % pref] = '.'.join(dep_version_parts[:2])
if dep_version:
template_values['%sver' % pref] = dep_version
dep_version_parts = dep_version.split('.')
template_values['%smajver' % pref] = dep_version_parts[0]
if len(dep_version_parts) > 1:
template_values['%sminver' % pref] = dep_version_parts[1]
template_values['%sshortver' % pref] = '.'.join(dep_version_parts[:2])

# step 2.1: CUDA templates in NVHPC
if toolchain is not None and hasattr(toolchain, 'name') and toolchain.name in TEMPLATE_CUDA_VERSION_NVHPC:
Expand Down
73 changes: 33 additions & 40 deletions test/framework/easyconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -3687,18 +3687,22 @@ def test_template_constant_dict(self):
my_arch = st.get_cpu_architecture()

# add Java dep with version specified using a dict value
toy_ec_txt += '\n'.join([
"dependencies += [",
" ('Python', '3.7.2'),"
" ('Java', {",
" 'arch=%s': '1.8.0_221'," % my_arch,
" 'arch=fooarch': '1.8.0-foo',",
" })",
"]",
"builddependencies = [",
" ('CMake', '3.18.4'),",
"]",
])
toy_ec_txt += textwrap.dedent("""
dependencies += [
('Python', '3.7.2'),
('Java', {
'arch=<arch>': '1.8.0_221',
'arch=fooarch': '1.8.0-foo',
}),
('Perl', {
'arch=<arch>': False,
'arch=fooarch': '1.42',
}),
]
builddependencies = [
('CMake', '3.18.4'),
]
""").replace('<arch>', my_arch)

test_ec = os.path.join(self.test_prefix, 'test.eb')
write_file(test_ec, toy_ec_txt)
Expand Down Expand Up @@ -3733,39 +3737,28 @@ def test_template_constant_dict(self):
}

# proper EasyConfig instance
ec = EasyConfig(test_ec)

# CMake should *not* be included, since it's a build-only dependency
dep_names = [x['name'] for x in ec['dependencies']]
self.assertFalse('CMake' in dep_names, "CMake should not be included in list of dependencies: %s" % dep_names)
res = template_constant_dict(ec)
dep_names = [x['name'] for x in ec['dependencies']]
self.assertFalse('CMake' in dep_names, "CMake should not be included in list of dependencies: %s" % dep_names)

self.assertIn('arch', res)
arch = res.pop('arch')
self.assertTrue(arch_regex.match(arch), "'%s' matches with pattern '%s'" % (arch, arch_regex.pattern))

self.assertEqual(res, expected)

full_ec = EasyConfig(test_ec)
expected_full = expected
# only perform shallow/quick parse (as is done in list_software function)
ec = EasyConfigParser(filename=test_ec).get_config_dict()

expected['module_name'] = None
shallow_ec = EasyConfigParser(filename=test_ec).get_config_dict()
expected_shallow = expected.copy()
expected_shallow['module_name'] = None
for key in ('bitbucket_account', 'github_account', 'versionprefix'):
del expected[key]
del expected_shallow[key]

dep_names = [x[0] for x in ec['dependencies']]
self.assertFalse('CMake' in dep_names, "CMake should not be included in list of dependencies: %s" % dep_names)
res = template_constant_dict(ec)
dep_names = [x[0] for x in ec['dependencies']]
self.assertFalse('CMake' in dep_names, "CMake should not be included in list of dependencies: %s" % dep_names)
for name, ec, expected in (('Full', full_ec, expected_full), ('Shallow', shallow_ec, expected_shallow)):
with self.subTest(f'{name} easyconfig'):
# CMake should *not* be included, since it's a build-only dependency
dep_names = [x['name'] if isinstance(x, dict) else x[0] for x in ec['dependencies']]
self.assertNotIn('CMake', dep_names)

self.assertIn('arch', res)
arch = res.pop('arch')
self.assertTrue(arch_regex.match(arch), "'%s' matches with pattern '%s'" % (arch, arch_regex.pattern))
res = template_constant_dict(ec)
self.assertIn('arch', res)
arch = res.pop('arch')
self.assertRegex(arch, arch_regex)

self.assertEqual(res, expected)
self.assertNotIn('perlver', res, "Perl should be filtered out")
self.assertEqual(res, expected)

# also check result of template_constant_dict when dict representing extension is passed
ext_dict = {
Expand Down
Loading