Skip to content

Commit 6a26673

Browse files
committed
Disable templating for more code
- `default_component_specs` must not be resolved - `self.cfg.update` resolves the current value before doing the update. Just put the whole code inside the context manager to use the old behavior
1 parent 09e60d7 commit 6a26673

File tree

1 file changed

+86
-85
lines changed

1 file changed

+86
-85
lines changed

easybuild/easyblocks/generic/bundle.py

Lines changed: 86 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def __init__(self, *args, **kwargs):
9191
self.cfg = self.cfg.copy()
9292

9393
# disable templating to avoid premature resolving of template values
94+
# Note that self.cfg.update also resolves templates!
9495
with self.cfg.disable_templating():
9596
# list of checksums for patches (must be included after checksums for sources)
9697
checksums_patches = []
@@ -111,102 +112,102 @@ def __init__(self, *args, **kwargs):
111112
self.cfg['sanity_check_commands'] = {}
112113
components = self.cfg['components']
113114

114-
for comp in components:
115-
comp_name, comp_version, comp_specs = comp[0], comp[1], {}
116-
if len(comp) == 3:
117-
comp_specs = comp[2]
115+
for comp in components:
116+
comp_name, comp_version, comp_specs = comp[0], comp[1], {}
117+
if len(comp) == 3:
118+
comp_specs = comp[2]
118119

119-
comp_cfg = self.cfg.copy()
120+
comp_cfg = self.cfg.copy()
120121

121-
comp_cfg['name'] = comp_name
122-
comp_cfg['version'] = comp_version
123-
124-
# determine easyblock to use for this component
125-
# - if an easyblock is specified explicitely, that will be used
126-
# - if not, a software-specific easyblock will be considered by get_easyblock_class
127-
# - if no easyblock was found, default_easyblock is considered
128-
comp_easyblock = comp_specs.get('easyblock')
129-
easyblock_class = get_easyblock_class(comp_easyblock, name=comp_name, error_on_missing_easyblock=False)
130-
if easyblock_class is None:
131-
if self.cfg['default_easyblock']:
132-
easyblock = self.cfg['default_easyblock']
133-
easyblock_class = get_easyblock_class(easyblock)
122+
comp_cfg['name'] = comp_name
123+
comp_cfg['version'] = comp_version
134124

125+
# determine easyblock to use for this component
126+
# - if an easyblock is specified explicitely, that will be used
127+
# - if not, a software-specific easyblock will be considered by get_easyblock_class
128+
# - if no easyblock was found, default_easyblock is considered
129+
comp_easyblock = comp_specs.get('easyblock')
130+
easyblock_class = get_easyblock_class(comp_easyblock, name=comp_name, error_on_missing_easyblock=False)
135131
if easyblock_class is None:
136-
raise EasyBuildError("No easyblock found for component %s v%s", comp_name, comp_version)
137-
else:
132+
if self.cfg['default_easyblock']:
133+
easyblock = self.cfg['default_easyblock']
134+
easyblock_class = get_easyblock_class(easyblock)
135+
136+
if easyblock_class is None:
137+
raise EasyBuildError("No easyblock found for component %s v%s", comp_name, comp_version)
138138
self.log.info("Using default easyblock %s for component %s", easyblock, comp_name)
139-
else:
140-
easyblock = easyblock_class.__name__
141-
self.log.info("Using easyblock %s for component %s", easyblock, comp_name)
142-
143-
if easyblock == 'Bundle':
144-
raise EasyBuildError("The Bundle easyblock can not be used to install components in a bundle")
145-
146-
comp_cfg.easyblock = easyblock_class
147-
148-
# make sure that extra easyconfig parameters are known, so they can be set
149-
extra_opts = comp_cfg.easyblock.extra_options()
150-
comp_cfg.extend_params(copy.deepcopy(extra_opts))
151-
152-
comp_cfg.generate_template_values()
153-
154-
# do not inherit easyblock to use from parent (since that would result in an infinite loop in install_step)
155-
comp_cfg['easyblock'] = None
156-
157-
# reset list of sources/source_urls/checksums
158-
comp_cfg['sources'] = comp_cfg['source_urls'] = comp_cfg['checksums'] = comp_cfg['patches'] = []
159-
160-
for key in self.cfg['default_component_specs']:
161-
comp_cfg[key] = self.cfg['default_component_specs'][key]
162-
163-
for key in comp_specs:
164-
comp_cfg[key] = comp_specs[key]
165-
166-
# Don't require that all template values can be resolved at this point but still resolve them.
167-
# This is important to ensure that template values like %(name)s and %(version)s
168-
# are correctly resolved with the component name/version before values are copied over to self.cfg
169-
with comp_cfg.allow_unresolved_templates():
170-
comp_sources = comp_cfg['sources']
171-
comp_source_urls = comp_cfg['source_urls']
172-
if not comp_sources:
173-
raise EasyBuildError("No sources specification for component %s v%s", comp_name, comp_version)
174-
# If per-component source URLs are provided, attach them directly to the relevant sources
175-
if comp_source_urls:
176-
for source in comp_sources:
177-
if isinstance(source, str):
178-
self.cfg.update('sources', [{'filename': source, 'source_urls': comp_source_urls[:]}])
179-
elif isinstance(source, dict):
180-
# Update source_urls in the 'source' dict to use the one for the components
181-
# (if it doesn't already exist)
182-
if 'source_urls' not in source:
183-
source['source_urls'] = comp_source_urls[:]
184-
self.cfg.update('sources', [source])
185-
else:
186-
raise EasyBuildError("Source %s for component %s is neither a string nor a dict, cannot "
187-
"process it.", source, comp_cfg['name'])
188-
else:
189-
# add component sources to list of sources
190-
self.cfg.update('sources', comp_sources)
139+
else:
140+
easyblock = easyblock_class.__name__
141+
self.log.info("Using easyblock %s for component %s", easyblock, comp_name)
142+
143+
if easyblock == 'Bundle':
144+
raise EasyBuildError("The Bundle easyblock can not be used to install components in a bundle")
145+
146+
comp_cfg.easyblock = easyblock_class
147+
148+
# make sure that extra easyconfig parameters are known, so they can be set
149+
extra_opts = comp_cfg.easyblock.extra_options()
150+
comp_cfg.extend_params(copy.deepcopy(extra_opts))
151+
152+
comp_cfg.generate_template_values()
153+
154+
# do not inherit easyblock to use from parent
155+
# (since that would result in an infinite loop in install_step)
156+
comp_cfg['easyblock'] = None
157+
158+
# reset list of sources/source_urls/checksums
159+
comp_cfg['sources'] = comp_cfg['source_urls'] = comp_cfg['checksums'] = comp_cfg['patches'] = []
160+
161+
for key in self.cfg['default_component_specs']:
162+
comp_cfg[key] = self.cfg['default_component_specs'][key]
163+
164+
for key in comp_specs:
165+
comp_cfg[key] = comp_specs[key]
166+
167+
# Don't require that all template values can be resolved at this point but still resolve them.
168+
# This is important to ensure that template values like %(name)s and %(version)s
169+
# are correctly resolved with the component name/version before values are copied over to self.cfg
170+
with comp_cfg.allow_unresolved_templates():
171+
comp_sources = comp_cfg['sources']
172+
comp_source_urls = comp_cfg['source_urls']
173+
if not comp_sources:
174+
raise EasyBuildError("No sources specification for component %s v%s", comp_name, comp_version)
175+
# If per-component source URLs are provided, attach them directly to the relevant sources
176+
if comp_source_urls:
177+
for source in comp_sources:
178+
if isinstance(source, str):
179+
self.cfg.update('sources', [{'filename': source, 'source_urls': comp_source_urls[:]}])
180+
elif isinstance(source, dict):
181+
# Update source_urls in the 'source' dict to use the one for the components
182+
# (if it doesn't already exist)
183+
if 'source_urls' not in source:
184+
source['source_urls'] = comp_source_urls[:]
185+
self.cfg.update('sources', [source])
186+
else:
187+
raise EasyBuildError("Source %s for component %s is neither a string nor a dict, cannot "
188+
"process it.", source, comp_cfg['name'])
189+
else:
190+
# add component sources to list of sources
191+
self.cfg.update('sources', comp_sources)
191192

192-
comp_checksums = comp_cfg['checksums']
193-
if comp_checksums:
194-
src_cnt = len(comp_sources)
193+
comp_checksums = comp_cfg['checksums']
194+
if comp_checksums:
195+
src_cnt = len(comp_sources)
195196

196-
# add per-component checksums for sources to list of checksums
197-
self.cfg.update('checksums', comp_checksums[:src_cnt])
197+
# add per-component checksums for sources to list of checksums
198+
self.cfg.update('checksums', comp_checksums[:src_cnt])
198199

199-
# add per-component checksums for patches to list of checksums for patches
200-
checksums_patches.extend(comp_checksums[src_cnt:])
200+
# add per-component checksums for patches to list of checksums for patches
201+
checksums_patches.extend(comp_checksums[src_cnt:])
201202

202-
with comp_cfg.allow_unresolved_templates():
203-
comp_patches = comp_cfg['patches']
204-
if comp_patches:
205-
self.cfg.update('patches', comp_patches)
203+
with comp_cfg.allow_unresolved_templates():
204+
comp_patches = comp_cfg['patches']
205+
if comp_patches:
206+
self.cfg.update('patches', comp_patches)
206207

207-
self.comp_instances.append((comp_cfg, comp_cfg.easyblock(comp_cfg, logfile=self.logfile)))
208+
self.comp_instances.append((comp_cfg, comp_cfg.easyblock(comp_cfg, logfile=self.logfile)))
208209

209-
self.cfg.update('checksums', checksums_patches)
210+
self.cfg.update('checksums', checksums_patches)
210211

211212
# restore general sanity checks if using component-specific sanity checks
212213
if self.cfg['sanity_check_components'] or self.cfg['sanity_check_all_components']:

0 commit comments

Comments
 (0)