@@ -188,6 +188,7 @@ def __init__(self, ec, logfile=None):
188188
189189 # list of patch/source files, along with checksums
190190 self .patches = []
191+ self .all_patches_paths = set () # set of paths to all patches (including patches of extensions)
191192 self .src = []
192193 self .data_src = []
193194 self .checksums = []
@@ -311,6 +312,9 @@ def __init__(self, ec, logfile=None):
311312 # initialize logger
312313 self ._init_log ()
313314
315+ # number of iterations
316+ self .iter_cnt = - 1
317+
314318 # try and use the specified group (if any)
315319 group_name = build_option ('group' )
316320 group_spec = self .cfg ['group' ]
@@ -598,6 +602,7 @@ def fetch_patches(self, patch_specs=None, extension=False, checksums=None):
598602 patch_info ['path' ] = path
599603 patch_info ['checksum' ] = self .get_checksum_for (checksums , filename = patch_info ['name' ], index = index )
600604
605+ self .all_patches_paths .add (path )
601606 if extension :
602607 patches .append (patch_info )
603608 else :
@@ -2387,7 +2392,8 @@ def handle_iterate_opts(self):
23872392 self .log .debug ("Iterating opt %s: %s" , opt , self .iter_opts [opt ])
23882393
23892394 if self .iter_opts :
2390- print_msg ("starting iteration #%s ..." % self .iter_idx , log = self .log , silent = self .silent )
2395+ print_msg (f"starting iteration { self .iter_idx + 1 } /{ self .iter_cnt } ..." , log = self .log ,
2396+ silent = self .silent )
23912397 self .log .info ("Current iteration index: %s" , self .iter_idx )
23922398
23932399 # pop first element from all iterative easyconfig parameters as next value to use
@@ -2429,7 +2435,7 @@ def det_iter_cnt(self):
24292435
24302436 # we need to take into account that builddependencies is always a list
24312437 # we're only iterating over it if it's a list of lists
2432- builddeps = self .cfg [ 'builddependencies' ]
2438+ builddeps = self .cfg . get_ref ( 'builddependencies' )
24332439 if all (isinstance (x , list ) for x in builddeps ):
24342440 iter_opt_counts .append (len (builddeps ))
24352441
@@ -4789,7 +4795,8 @@ def run_all_steps(self, run_test_cases):
47894795 if self .cfg ['stop' ] == 'cfg' :
47904796 return True
47914797
4792- steps = self .get_steps (run_test_cases = run_test_cases , iteration_count = self .det_iter_cnt ())
4798+ self .iter_cnt = self .det_iter_cnt ()
4799+ steps = self .get_steps (run_test_cases = run_test_cases , iteration_count = self .iter_cnt )
47934800
47944801 # figure out how many steps will actually be run (not be skipped)
47954802 step_cnt = 0
@@ -4922,7 +4929,7 @@ def copy_build_dirs_logs_failed_install(application_log, silent, app, easyconfig
49224929 msg = f"Build directory of failed installation copied to { build_dirs_path } "
49234930
49244931 def operation (src , dest ):
4925- copy_dir (src , dest , dirs_exist_ok = True )
4932+ copy_dir (src , dest , dirs_exist_ok = True , symlinks = True )
49264933
49274934 operation_args .append ((operation , [app .builddir ], build_dirs_path , msg ))
49284935
@@ -5032,7 +5039,9 @@ def build_and_install_one(ecdict, init_env):
50325039 except EasyBuildError as err :
50335040 _log .warning ("Failed to create build environment dump for easyconfig %s: %s" , reprod_spec , err )
50345041
5035- # also add any extension easyblocks used during the build for reproducibility
5042+ # also add any component/extension easyblocks used during the build for reproducibility
5043+ if hasattr (app , 'comp_instances' ):
5044+ copy_easyblocks_for_reprod ([comp for cfg , comp in app .comp_instances ], reprod_dir )
50365045 if app .ext_instances :
50375046 copy_easyblocks_for_reprod (app .ext_instances , reprod_dir )
50385047 # If not already done remove the granted write permissions if we did so
@@ -5119,15 +5128,13 @@ def ensure_writable_log_dir(log_dir):
51195128 block = det_full_ec_version (app .cfg ) + ".block"
51205129 repo .add_easyconfig (ecdict ['original_spec' ], app .name , block , buildstats , currentbuildstats )
51215130 repo .add_easyconfig (spec , app .name , det_full_ec_version (app .cfg ), buildstats , currentbuildstats )
5122- for patch in app .patches :
5123- repo .add_patch (patch [ 'path' ] , app .name )
5131+ for patch_path in app .all_patches_paths :
5132+ repo .add_patch (patch_path , app .name )
51245133 repo .commit ("Built %s" % app .full_mod_name )
51255134 del repo
51265135 except EasyBuildError as err :
51275136 _log .warning ("Unable to commit easyconfig to repository: %s" , err )
51285137
5129- run_hook (EASYBLOCK , hooks , post_step_hook = True , args = [app ])
5130-
51315138 # cleanup logs
51325139 app .close_log ()
51335140
@@ -5144,10 +5151,10 @@ def ensure_writable_log_dir(log_dir):
51445151 _log .debug ("Copied easyconfig file %s to %s" , spec , newspec )
51455152
51465153 # copy patches
5147- for patch in app .patches :
5148- target = os .path .join (new_log_dir , os .path .basename (patch [ 'path' ] ))
5149- copy_file (patch [ 'path' ] , target )
5150- _log .debug ("Copied patch %s to %s" , patch [ 'path' ] , target )
5154+ for patch_path in app .all_patches_paths :
5155+ target = os .path .join (new_log_dir , os .path .basename (patch_path ))
5156+ copy_file (patch_path , target )
5157+ _log .debug ("Copied patch %s to %s" , patch_path , target )
51515158
51525159 if build_option ('read_only_installdir' ) and not app .cfg ['stop' ]:
51535160 # take away user write permissions (again)
@@ -5201,6 +5208,8 @@ def ensure_writable_log_dir(log_dir):
52015208 if not success :
52025209 copy_build_dirs_logs_failed_install (application_log , silent , app , ecdict ['ec' ])
52035210
5211+ run_hook (EASYBLOCK , hooks , post_step_hook = True , args = [app ])
5212+
52045213 del app
52055214
52065215 return (success , application_log , error_msg , exit_code )
0 commit comments