import re import subprocess import sys from functools import cache assert sys.version_info >= (3, 7), 'Python version is too low, please load a python >= 3.7' failed_at_least_once=False def subprocess_cmd(cmd): return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True, shell=True) def failure_handler(module, given_status): if len(module) != 0: print('Module: "' + module + '" should be deployed as ' + given_status) global failed_at_least_once failed_at_least_once = True class PmodulePackage(): def __init__(self, name, status, deps=[]): self.name = name self.given_status = status self.true_status = [status] if len(deps) != 0 and self.given_status != 'deprecated': compiler = deps[0] if len(deps) > 1 and 'mpi' in deps[1]: mpi_provider = deps[1] else: mpi_provider = '' self.deps = [PmodulePackage.Pmoduliser(d, compiler, mpi_provider) for d in deps] self.true_status += self.check_deps_status() def check_deps_status(self): deps_status = [] for d in self.deps: deps_status += d.true_status return deps_status def check_correct_status(self, module=''): if (self.given_status != 'deprecated') and len(self.true_status) > 1: if 'deprecated' in self.true_status: self.given_status = 'deprecated' failure_handler(module, self.given_status) elif self.given_status == 'stable' and 'unstable' in self.true_status: self.given_status = 'unstable' failure_handler(module, self.given_status) self.true_status = [self.given_status] @staticmethod @cache def Pmoduliser(pckg_name='', compiler='', mpi_provider=''): default_module_cmd = 'module search ' + pckg_name + ' -a --all-deps --no-header' # try to precise the module search if compiler and/or mpi_provider are given module_cmd = default_module_cmd if compiler != '' and pckg_name != compiler: module_cmd = module_cmd + ' --with=' + compiler if mpi_provider != '' and pckg_name != mpi_provider: module_cmd = module_cmd + ' --with=' + mpi_provider module_cmd_process = subprocess_cmd(module_cmd) # take the default command if the dependency wasn't compiled with the same compiler and/or mpi_provider if len(module_cmd_process.stderr.splitlines()) == 0: module_cmd = default_module_cmd module_cmd_process = subprocess_cmd(module_cmd) package = module_cmd_process.stderr.splitlines() if len(package) != 0: package = package[0].split() Pmodule_pckg = PmodulePackage(package[0], package[1], package[3:]) Pmodule_pckg.check_correct_status() return Pmodule_pckg else: print('Warning: "' + pckg_name + '" could not be found using "' + module_cmd + '"') return PmodulePackage('', '') def main(): module_cmd = 'module search -a --all-deps --no-header' module_cmd_process = subprocess_cmd(module_cmd) for module in module_cmd_process.stderr.splitlines(): if len(module) != 0: package = module.split() Pmodule_pckg = PmodulePackage(package[0], package[1], package[3:]) Pmodule_pckg.check_correct_status(module) if(failed_at_least_once): sys.exit(1) if __name__=="__main__": main()