From fc879ca0523423d13974ae488331ad3dda62f14a Mon Sep 17 00:00:00 2001 From: Gilles DAVID Date: Tue, 22 Oct 2024 18:08:14 +0200 Subject: [PATCH] =?utf8?q?[APPLI]=20Corrections=20et=20=C3=A9volutions?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit + Installation des modules importés dans SALOME_INSTALL_PYTHON + L'appli est désormais un venv python + ajout automatique du chemin du KERNEL + Remplacement de optparse par argparse --- bin/appli_gen.py | 101 ++++++++++++++++++++++----------- bin/appliskel/.salome_run | 9 +-- bin/appliskel/salome | 9 ++- bin/appliskel/salome_common.py | 4 +- bin/appliskel/salome_mesa | 9 ++- bin/virtual_salome.py | 56 ++++++++++-------- 6 files changed, 121 insertions(+), 67 deletions(-) diff --git a/bin/appli_gen.py b/bin/appli_gen.py index 1905ba2d1..99f577f5e 100755 --- a/bin/appli_gen.py +++ b/bin/appli_gen.py @@ -25,20 +25,22 @@ # Create a %SALOME application (virtual Salome installation) # +import argparse import json import os +from pathlib import Path import sys import shutil import virtual_salome import xml.sax -import optparse import subprocess +import venv usage = """%(prog)s [options] Typical use is: - python %(prog)s + %(prog)s Typical use with options is: - python %(prog)s --verbose --prefix= --config= + %(prog)s --verbose --prefix= --config= """ # --- names of tags in XML configuration file @@ -188,6 +190,26 @@ class params: # ----------------------------------------------------------------------------- + +def update_shebang(source_path, target_path, home_dir): + # Chemin vers l'interpréteur Python de l'application + python_executable = Path(home_dir, "bin") / Path(sys.executable).name + + # Lire le contenu du fichier source + source_file = Path(source_path) + lines = source_file.read_text().splitlines() + + # Vérifier et mettre à jour le shebang + if lines[0].startswith('#!'): + lines[0] = f'#!{python_executable}' + else: + lines.insert(0, f'#!{python_executable}') + + # Écrire le contenu mis à jour dans le fichier cible + target_file = Path(target_path) + target_file.write_text('\n'.join(lines) + '\n') + + def makedirs(namedir): if os.path.exists(namedir): dirbak = namedir+".bak" @@ -200,6 +222,12 @@ def makedirs(namedir): def install(prefix, config_file, verbose=0): home_dir = os.path.abspath(os.path.expanduser(prefix)) filename = os.path.abspath(os.path.expanduser(config_file)) + + venv.create( + env_dir=home_dir, + with_pip=True, + ) + _config = {} try: parser = xml_parser(filename) @@ -228,15 +256,26 @@ def install(prefix, config_file, verbose=0): except Exception: pass - for module in _config.get("modules", []): + # Add KERNEL if not in config + # We use KERNEL that provides appli_gen script + modules = _config.get("modules", []) + if "KERNEL" not in modules: + # We suppose that appli_gen is installed in KERNEL_ROOT_DIR/bin/salome + kernel_path = Path(__file__).resolve().parents[2].as_posix() + _config["KERNEL"] = kernel_path + modules.insert(0, "KERNEL") + kernel_module_path = None + + for module in modules: if module in _config: - print("--- add module ", module, _config[module]) + module_path = _config[module] + print("--- add module ", module, module_path) options = params() options.verbose = verbose options.clear = 0 options.prefix = home_dir options.module_name = module - options.module_path = _config[module] + options.module_path = module_path virtual_salome.link_module(options) # To fix GEOM_TestXAO issue https://codev-tuleap.cea.fr/plugins/tracker/?aid=16599 if module == "GEOM": @@ -246,6 +285,8 @@ def install(prefix, config_file, verbose=0): xao_link=os.path.join(module_dir,'bin','salome', 'test', "xao") print("link %s --> %s"%(os.path.join(test_dir, "xao"), xao_link)) virtual_salome.symlink(xao_link, os.path.join(test_dir, "xao")) + if module == "KERNEL": + kernel_module_path = module_path pass pass @@ -278,12 +319,8 @@ def install(prefix, config_file, verbose=0): appliskel_dir = os.path.join(prefix, 'bin', 'salome', 'appliskel') for fn in ('envd', - 'getAppliPath.py', - 'kill_remote_containers.py', 'runRemote.sh', 'runRemoteSSL.sh', - '.salome_run', - 'update_catalogs.py', '.bashrc', ): virtual_salome.symlink( os.path.join( appliskel_dir, fn ), os.path.join( home_dir, fn) ) @@ -311,17 +348,17 @@ def install(prefix, config_file, verbose=0): fd.write('module load %s\n' % (' '.join(env_modules))) # Copy salome / salome_mesa scripts: - - for scripts in ('salome', 'salome_mesa', 'salome_common.py'): - salome_script = open(os.path.join(appliskel_dir, scripts)).read() + for scripts in ('getAppliPath.py', + 'kill_remote_containers.py', + '.salome_run', + 'update_catalogs.py', + 'salome', + 'salome_mesa', + ): + salome_script = os.path.join(appliskel_dir, scripts) salome_file = os.path.join(home_dir, scripts) - try: - os.remove(salome_file) - except Exception: - pass - with open(salome_file, 'w') as fd: - fd.write(salome_script.replace('MODULES = []', 'MODULES = {}'.format(env_modules))) - os.chmod(salome_file, 0o755) + update_shebang(salome_script, salome_file, home_dir) + os.chmod(salome_file, 0o755) # Add .salome-completion.sh file shutil.copyfile(os.path.join(appliskel_dir, ".salome-completion.sh"), @@ -390,13 +427,10 @@ def install(prefix, config_file, verbose=0): if "resources_path" in _config and os.path.isfile(_config["resources_path"]): command = 'export USER_CATALOG_RESOURCES_FILE=' + os.path.abspath(_config["resources_path"]) +'\n' f.write(command) - # Note: below, PYTHONPATH should not be extended to bin/salome! Python modules must be installed in lib/pythonX.Y, to be fixed (e.g. Kernel SALOME_Container.py) - command ="""export PATH=${HOME}/${APPLI}/bin/salome:$PATH -export PYTHONPATH=${HOME}/${APPLI}/lib/python%s/site-packages/salome:$PYTHONPATH -export PYTHONPATH=${HOME}/${APPLI}/lib/salome:$PYTHONPATH -export PYTHONPATH=${HOME}/${APPLI}/bin/salome:$PYTHONPATH + command ="""\ +export PATH=${HOME}/${APPLI}/bin/salome:$PATH export LD_LIBRARY_PATH=${HOME}/${APPLI}/lib/salome:$LD_LIBRARY_PATH -""" %versionPython +""" f.write(command) # Create environment variable for the salome test for module in _config.get("modules", []): @@ -545,18 +579,19 @@ MMGT_REENTRANT=1 os.chmod(users_dir, 0o777) def main(): - parser = optparse.OptionParser(usage=usage) + parser = argparse.ArgumentParser(usage=usage) - parser.add_option('--prefix', dest="prefix", default='.', - help="Installation directory (default .)") + parser.add_argument('--prefix', default='.', metavar="", + help="Installation directory (default %(default)s)") - parser.add_option('--config', dest="config", default='config_appli.xml', - help="XML configuration file (default config_appli.xml)") + parser.add_argument('--config', default='config_appli.xml', + metavar="", + help="XML configuration file (default %(default)s)") - parser.add_option('-v', '--verbose', action='count', dest='verbose', + parser.add_argument('-v', '--verbose', action='count', default=0, help="Increase verbosity") - options, args = parser.parse_args() + options = parser.parse_args() if not os.path.exists(options.config): print("ERROR: config file %s does not exist. It is mandatory." % options.config) sys.exit(1) diff --git a/bin/appliskel/.salome_run b/bin/appliskel/.salome_run index 85b6df5fd..c29b94e8c 100755 --- a/bin/appliskel/.salome_run +++ b/bin/appliskel/.salome_run @@ -19,15 +19,16 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import os +from pathlib import Path import sys + def main(args): # Identify application path then locate configuration files - currentPath = os.path.realpath(os.path.dirname(os.path.abspath(__file__))) - launcherFile = os.path.basename(__file__) + currentPath = Path(__file__).parent.resolve() + launcherFile = Path(__file__).name from salome_starter import initialize - initialize(currentPath, launcherFile) + initialize(f"{currentPath}", launcherFile) if len(args) == 1 and args[0] in ['--help', 'help', '-h', '--h']: from salomeContext import usage diff --git a/bin/appliskel/salome b/bin/appliskel/salome index 0332091a4..38f1f97cb 100755 --- a/bin/appliskel/salome +++ b/bin/appliskel/salome @@ -18,8 +18,13 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import salome_common +from pathlib import Path import sys +import salome_common + + if __name__ == "__main__": - salome_common.main(sys.argv[1:]) + appli_path = Path(__file__).parent + args = [f"{appli_path}"] + sys.argv[1:] + salome_common.main(args) diff --git a/bin/appliskel/salome_common.py b/bin/appliskel/salome_common.py index fdcbd6f5d..d1c8654e6 100644 --- a/bin/appliskel/salome_common.py +++ b/bin/appliskel/salome_common.py @@ -29,10 +29,10 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -def main(args): +def main(args: list): ''' Load modules then launch salome ''' - appliPath = Path(__file__).parent.resolve() + appliPath = Path(args.pop(0)) modules_file = appliPath / "env_modules.json" if modules_file.is_file(): env_modules = json.loads(open(modules_file).read()).get('env_modules', []) diff --git a/bin/appliskel/salome_mesa b/bin/appliskel/salome_mesa index f7bc64e32..4b59391cf 100644 --- a/bin/appliskel/salome_mesa +++ b/bin/appliskel/salome_mesa @@ -27,13 +27,18 @@ # discussion of the issue, EDF Redmine issue #22374. # -import salome_common +from pathlib import Path import sys +import salome_common + + if __name__ == "__main__": import os if os.name != "posix": os.environ["XLIB_SKIP_ARGB_VISUALS"]="1" os.environ["MESA_GL_VERSION_OVERRIDE"]="4.5" os.environ["SALOME_USE_MESA"]="1" - salome_common.main(sys.argv[1:]) + appli_path = Path(__file__).parent + args = [f"{appli_path}"] + sys.argv[1:] + salome_common.main(args) diff --git a/bin/virtual_salome.py b/bin/virtual_salome.py index b82ea0a5e..2c7310382 100755 --- a/bin/virtual_salome.py +++ b/bin/virtual_salome.py @@ -31,8 +31,12 @@ Typical use:: install module KERNEL in the current directory """ -import sys, os, optparse, shutil, glob, fnmatch - +import argparse +import glob +import os +from pathlib import Path +import shutil +import sys py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) @@ -90,7 +94,6 @@ __lib__dir__ = None def get_lib_dir(): global __lib__dir__ if __lib__dir__: return __lib__dir__ - import platform __lib__dir__ = "lib" return __lib__dir__ @@ -130,15 +133,17 @@ def link_module(options): #incompatible python versions print("incompatible python versions : application has version %s and module %s has not" % (versio,module_dir)) return + + site_path = os.path.join(get_lib_dir(), pyversio, 'site-packages') module_bin_dir=os.path.join(module_dir,'bin','salome') module_test_dir=os.path.join(module_dir,'bin','salome', 'test', options.module_name.lower()) module_idl_dir=os.path.join(module_dir,'idl','salome') module_lib_dir=os.path.join(module_dir,get_lib_dir(),'salome') module_pvlib_dir=os.path.join(module_dir,get_lib_dir(),'paraview') - module_lib_py_dir=os.path.join(module_dir,get_lib_dir(),pyversio,'site-packages','salome') - module_lib_py_shared_dir=os.path.join(module_dir,get_lib_dir(),pyversio, - 'site-packages','salome') + module_pth_py_file=os.path.join(module_dir,site_path,'salome_pth.py') + module_pth_file=os.path.join(module_dir,site_path,'salome.pth') + module_lib_py_dir=os.path.join(module_dir,site_path,'salome') module_share_dir=os.path.join(module_dir,'share','salome') module_doc_gui_dir=os.path.join(module_dir,'doc','salome','gui') module_doc_tui_dir=os.path.join(module_dir,'doc','salome','tui') @@ -154,9 +159,9 @@ def link_module(options): idl_dir=os.path.join(home_dir,'idl','salome') lib_dir=os.path.join(home_dir,'lib','salome') pvlib_dir=os.path.join(home_dir,'lib','paraview') - lib_py_dir=os.path.join(home_dir,'lib',pyversio,'site-packages','salome') - lib_py_shared_dir=os.path.join(home_dir,'lib',pyversio, - 'site-packages','salome') + pth_py_file=os.path.join(home_dir,site_path,'salome_pth.py') + pth_file=os.path.join(home_dir,site_path,'salome.pth') + lib_py_dir=os.path.join(home_dir,site_path,'salome') share_dir=os.path.join(home_dir,'share','salome') doc_gui_dir=os.path.join(home_dir,'doc','salome','gui') doc_tui_dir=os.path.join(home_dir,'doc','salome','tui') @@ -239,6 +244,16 @@ def link_module(options): print(module_pvlib_dir, " doesn't exist") pass + # files lib/pyversio/site-packages/salome_pth.py and lib/pyversio/site-packages/salome.pth + # Those files allow to have home_dir/lib/pyversio/site-packages/salome directory in PYTHONPATH + if os.path.exists(module_pth_py_file) and os.path.exists(module_pth_file): + Path(pth_py_file).parent.mkdir(parents=True, exist_ok=True) + symlink(module_pth_py_file, pth_py_file) + symlink(module_pth_file, pth_file) + else: + if not Path(pth_py_file).exists() and not Path(pth_file).exists(): + print(f"One or both of these files does not exist: {module_pth_py_file}, {module_pth_file}") + #directory lib/pyversio/site-packages/salome : create it and link content if not os.path.exists(module_lib_py_dir): print("Python directory %s does not exist" % module_lib_py_dir) @@ -247,16 +262,10 @@ def link_module(options): module_lib_pypkg_dir=os.path.join(module_lib_py_dir,"salome") lib_pypkg_dir=os.path.join(lib_py_dir,"salome") mkdir(lib_pypkg_dir) - mkdir(lib_py_shared_dir) for fn in os.listdir(module_lib_py_dir): if fn == "salome": continue symlink(os.path.join(module_lib_py_dir, fn), os.path.join(lib_py_dir, fn)) pass - if os.path.exists(module_lib_py_shared_dir): - for fn in os.listdir(module_lib_py_shared_dir): - symlink(os.path.join(module_lib_py_shared_dir, fn), os.path.join(lib_py_shared_dir, fn)) - pass - pass if os.path.exists(module_lib_pypkg_dir): for fn in os.listdir(module_lib_pypkg_dir): symlink(os.path.join(module_lib_pypkg_dir, fn), os.path.join(lib_pypkg_dir, fn)) @@ -264,7 +273,7 @@ def link_module(options): pass else: if verbose: - print(module_lib_py_shared_dir, " doesn't exist") + print(module_lib_pypkg_dir, " doesn't exist") pass #directory share/doc/salome (KERNEL doc) : create it and link content @@ -395,19 +404,18 @@ def main(): Typical use is: python virtual_salome.py -v --prefix="." --module=/local/chris/SALOME2/RELEASES/Install/KERNEL_V3_1_0b1 """ - parser = optparse.OptionParser(usage=usage) + parser = argparse.ArgumentParser(usage=usage) - parser.add_option('-v', '--verbose', action='count', dest='verbose', - default=0, help="Increase verbosity") + parser.add_argument('-v', '--verbose', action='count', dest='verbose', + default=0, help="Increase verbosity") - parser.add_option('--prefix', dest="prefix", default='.', + parser.add_argument('--prefix', default='.', metavar="", help="The base directory to install to (default .)") - parser.add_option('--module', dest="module", - help="The module directory to install in (mandatory)") + parser.add_argument('--module', help="The module directory to install in (mandatory)") - parser.add_option('--clear', dest='clear', action='store_true', - help="Clear out the install and start from scratch") + parser.add_argument('--clear', action='store_true', + help="Clear out the install and start from scratch") options, args = parser.parse_args() link_module(options) -- 2.39.2