@@ -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