3535"""
3636import copy
3737import os
38+ from datetime import datetime
3839
3940import easybuild .tools .environment as env
4041from easybuild .framework .easyblock import EasyBlock
4546from easybuild .tools .config import build_option
4647from easybuild .tools .hooks import TEST_STEP
4748from easybuild .tools .modules import get_software_root , get_software_version
48- from easybuild .tools .utilities import nub
49+ from easybuild .tools .utilities import nub , time2str
50+
51+
52+ # Description and step name run during component installation
53+ COMPONENT_INSTALL_STEPS = [
54+ ('patching' , 'patch' ),
55+ ('configuring' , 'configure' ),
56+ ('building' , 'build' ),
57+ ('testing' , 'test' ),
58+ ('installing' , 'install' ),
59+ ]
4960
5061
5162class Bundle (EasyBlock ):
@@ -265,14 +276,39 @@ def build_step(self):
265276 """Do nothing."""
266277 pass
267278
279+ def _install_component (self , comp ):
280+ """Run the installation steps for a single component"""
281+ # run relevant steps
282+ for descr , step_name in COMPONENT_INSTALL_STEPS :
283+ if step_name in comp .cfg ['skipsteps' ]:
284+ comp .log .info ("Skipping '%s' step for component %s v%s" , step_name , comp .name , comp .version )
285+ elif build_option ('skip_test_step' ) and step_name == TEST_STEP :
286+ comp .log .info ("Skipping %s step for component %s v%s, as requested via skip-test-step" , step_name ,
287+ comp .name , comp .version )
288+ else :
289+ msg = f' { descr } component { comp .name } ...'
290+ if self .dry_run :
291+ self .dry_run_msg ("%s [DRY RUN]\n " , msg )
292+ else :
293+ print_msg (msg , log = self .log , silent = self .silent )
294+ start_time = datetime .now ()
295+ try :
296+ comp .run_step (step_name , [lambda x : getattr (x , '%s_step' % step_name )])
297+ finally :
298+ if not self .dry_run :
299+ step_duration = datetime .now () - start_time
300+ if step_duration .total_seconds () >= 1 :
301+ print_msg (" ... (took %s)" , time2str (step_duration ), log = self .log , silent = self .silent )
302+ elif self .logdebug or build_option ('trace' ):
303+ print_msg (" ... (took < 1 sec)" , log = self .log , silent = self .silent )
304+
268305 def install_step (self ):
269306 """Install components, if specified."""
270307 comp_cnt = len (self .cfg ['components' ])
271308 for idx , (cfg , comp ) in enumerate (self .comp_instances ):
272-
273309 print_msg ("installing bundle component %s v%s (%d/%d)..." %
274- (cfg [ ' name' ], cfg [ ' version' ] , idx + 1 , comp_cnt ))
275- self .log .info ("Installing component %s v%s using easyblock %s" , cfg [ ' name' ], cfg [ ' version' ] , cfg .easyblock )
310+ (comp . name , comp . version , idx + 1 , comp_cnt ))
311+ self .log .info ("Installing component %s v%s using easyblock %s" , comp . name , comp . version , cfg .easyblock )
276312
277313 # correct build/install dirs
278314 comp .builddir = self .builddir
@@ -317,18 +353,10 @@ def install_step(self):
317353 comp .src [- 1 ]['finalpath' ] = comp .cfg ['start_dir' ]
318354
319355 # check if sanity checks are enabled for the component
320- if self .cfg ['sanity_check_all_components' ] or comp .cfg [ ' name' ] in self .cfg ['sanity_check_components' ]:
356+ if self .cfg ['sanity_check_all_components' ] or comp .name in self .cfg ['sanity_check_components' ]:
321357 self .comp_cfgs_sanity_check .append (comp )
322358
323- # run relevant steps
324- for step_name in ['patch' , 'configure' , 'build' , 'test' , 'install' ]:
325- if step_name in cfg ['skipsteps' ]:
326- comp .log .info ("Skipping '%s' step for component %s v%s" , step_name , cfg ['name' ], cfg ['version' ])
327- elif build_option ('skip_test_step' ) and step_name == TEST_STEP :
328- comp .log .info ("Skipping %s step for component %s v%s, as requested via skip-test-step" , step_name ,
329- cfg ['name' ], cfg ['version' ])
330- else :
331- comp .run_step (step_name , [lambda x : getattr (x , '%s_step' % step_name )])
359+ self ._install_component (comp )
332360
333361 if comp .make_module_req_guess .__qualname__ != 'EasyBlock.make_module_req_guess' :
334362 depr_msg = f"Easyblock used to install component { comp .name } still uses make_module_req_guess"
@@ -381,13 +409,13 @@ def make_module_step(self, *args, **kwargs):
381409 as this is done in the generic EasyBlock while creating
382410 the module file already.
383411 """
384- for cfg , comp in self .comp_instances :
385- self .log .info ("Gathering module paths for component %s v%s" , cfg [ ' name' ], cfg [ ' version' ] )
412+ for _ , comp in self .comp_instances :
413+ self .log .info ("Gathering module paths for component %s v%s" , comp . name , comp . version )
386414
387415 # take into account that easyblock used for component may not be migrated yet to module_load_environment
388416 if comp .make_module_req_guess .__qualname__ != 'EasyBlock.make_module_req_guess' :
389417
390- depr_msg = f"Easyblock used to install component { cfg [ ' name' ] } still uses make_module_req_guess"
418+ depr_msg = f"Easyblock used to install component { comp . name } still uses make_module_req_guess"
391419 self .log .deprecated (depr_msg , '6.0' )
392420
393421 reqs = comp .make_module_req_guess ()
@@ -403,7 +431,7 @@ def make_module_step(self, *args, **kwargs):
403431 setattr (self .module_load_environment , key , value )
404432 except AttributeError :
405433 raise EasyBuildError ("Cannot process module requirements of bundle component %s v%s" ,
406- cfg [ ' name' ], cfg [ ' version' ] )
434+ comp . name , comp . version )
407435 else :
408436 # Explicit call required as adding step to 'install_step' is not sufficient
409437 # for module-only build. Set fake arg to True, as module components should
@@ -445,8 +473,7 @@ def sanity_check_step(self, *args, **kwargs):
445473 # run sanity checks for specific components
446474 cnt = len (self .comp_cfgs_sanity_check )
447475 for idx , comp in enumerate (self .comp_cfgs_sanity_check ):
448- comp_name , comp_ver = comp .cfg ['name' ], comp .cfg ['version' ]
449- print_msg ("sanity checking bundle component %s v%s (%i/%i)..." , comp_name , comp_ver , idx + 1 , cnt )
450- self .log .info ("Starting sanity check step for component %s v%s" , comp_name , comp_ver )
476+ print_msg ("sanity checking bundle component %s v%s (%i/%i)..." , comp .name , comp .version , idx + 1 , cnt )
477+ self .log .info ("Starting sanity check step for component %s v%s" , comp .name , comp .version )
451478
452479 comp .run_step ('sanity_check' , [lambda x : x .sanity_check_step ])
0 commit comments