Pmodules_tools/dependency-checker.py
2022-11-24 16:07:23 +00:00

92 lines
3.5 KiB
Python

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()