from functools import cache import subprocess import sys # Global parameter failed_at_least_once = False def deps_status_check(module_cmd_process): 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) 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 def subprocess_cmd(cmd): return subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True, shell=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("", "")