from traceback import format_exc
from .extension_utilities import logger, \
- DFILE_EXT, ARCFILE_EXT, EXTDEPENDSON_KEY, \
- isvalid_filename, isvalid_dirname
+ DFILE_EXT, ARCFILE_EXT, EXTDEPENDSON_KEY, EXTCOMPONENT_KEY, \
+ isvalid_filename, isvalid_dirname, ext_info_bykey, set_selext_env, get_app_root
+
def unpack_salomex(salome_root, salomex):
"""
salomex - a given salomex file to unpack.
Returns:
- None.
+ True if an ext was successfully unpacked.
"""
logger.debug('Starting unpack a salome extension file')
# Check if provided filenames are valid
if not isvalid_dirname(salome_root) or \
not isvalid_filename(salomex, ARCFILE_EXT):
- return
+ return False
try:
with tarfile.open(salomex) as ext:
if not os.path.isfile(depends_filename):
logger.error('Cannot find %s for a module that extension depends on!',
depends_filename)
- return
+ return False
# Unpack archive in the salome_root
logger.debug('Extract all the files into %s...', salome_root)
except (OSError, KeyError):
logger.error(format_exc())
+ return False
+
+ return True
+
+
+def install_salomex(salomex):
+ """
+ Install a given salome extension into SALOME_APPLICATION_DIR.
+
+ Args:
+ salomex - a given salomex file to unpack.
+
+ Returns:
+ A list of components to be activated later.
+ """
+
+ logger.debug('Starting install a salome extension from %s', salomex)
+
+ # Check if we have the salome root path
+ app_root = os.environ.get('SALOME_APPLICATION_DIR', '')
+ if not app_root:
+ # It should be set on the app start, but leave it here to run as a standalone script
+ logger.warning(
+ 'Env var SALOME_APPLICATION_DIR is not set! Try to set it going up from cur location.')
+ app_root = get_app_root()
+
+ # Unpack an archive
+ if not unpack_salomex(app_root, salomex):
+ return []
+
+ # Set up an environment
+ # It's not clear at the moment what to do if it fails
+ ext_name, _ = os.path.splitext(os.path.basename(salomex))
+ set_selext_env(app_root, ext_name)
+
+ # Get components to activate later
+ components = ext_info_bykey(app_root, ext_name, EXTCOMPONENT_KEY)
+
+ return components if components else []
if __name__ == '__main__':
if len(sys.argv) == 3:
arg_1, arg_2 = sys.argv[1:] # pylint: disable=unbalanced-tuple-unpacking
unpack_salomex(arg_1, arg_2)
+ elif len(sys.argv) == 2:
+ install_salomex(sys.argv[1])
else:
logger.error('You must provide all the arguments!')
logger.info(unpack_salomex.__doc__)
"""
import os
+import sys
import logging
import json
from traceback import format_exc
+from pathlib import Path
+import importlib.util
# Usually logging verbosity is set inside bin/runSalomeCommon.py when salome is starting.
# Here we do just the same for a case if we call this package stand alone.
logging.basicConfig(format=FORMAT, level=logging.DEBUG, force=False)
logger = logging.getLogger()
+# SalomeContext sets the logging verbosity level on its own,
+# and we put it here, so it doesn't override the local format above.
+#pylint: disable=wrong-import-position
+import salomeContext
+#pylint: enable=wrong-import-position
+
SALOME_EXTDIR = '__SALOME_EXT__'
ARCFILE_EXT = 'salomex'
BFILE_EXT = 'salomexb'
return {}
+def value_from_salomexd(file_path, key):
+ """
+ Reads a content of a salomexd file and return a value for the given key.
+
+ Args:
+ file_path - the path to the salomexd file.
+ key - the key to search an assigned value.
+
+ Returns:
+ A value assigned to the given key if exist, otherwise None.
+ """
+
+ file_content = read_salomexd(file_path)
+ if key in file_content and file_content[key]:
+ logger.debug('Key: %s, value: %s', key, file_content[key])
+ return file_content[key]
+
+ logger.warning('Cannot get a value for key %s in salomexd file %s', key, file_path)
+ return None
+
+
+def ext_info_bykey(salome_root, salomex_name, key):
+ """
+ Search a salomexd file by ext name and return a value for the given key.
+
+ Args:
+ install_dir - directory where the given extension is installed.
+ salomex_name - the given extension's name.
+ key - the key to search an assigned value.
+
+ Returns:
+ A value for key in the given ext salomexd file.
+ """
+
+ salomexd = find_salomexd(salome_root, salomex_name)
+ if salomexd:
+ return value_from_salomexd(salomexd, key)
+
+ return None
+
+
def create_salomexb(name, included):
"""
Create a salomexb file from a list of included file names.
"""
return find_file(install_dir, salomex_name + ENVPYFILE_SUF)
+
+
+def module_from_filename(filename):
+ """
+ Create and execute a module by filename.
+
+ Args:
+ filename - a given python filename.
+
+ Returns:
+ Module.
+ """
+
+ # Get the module from the filename
+ basename = os.path.basename(filename)
+ module_name, _ = os.path.splitext(basename)
+
+ spec = importlib.util.spec_from_file_location(module_name, filename)
+ if not spec:
+ logger.error('Could not get a spec for %s file!')
+ return None
+
+ module = importlib.util.module_from_spec(spec)
+ if not module:
+ logger.error('Could not get a module for %s file!')
+ return None
+
+ sys.modules[module_name] = module
+
+ logger.debug('Execute %s module', module_name)
+ spec.loader.exec_module(module)
+
+ return module
+
+
+def set_selext_env(install_dir, salomex_name, context=None):
+ """
+ Finds and run _env.py file for the given extension.
+
+ Args:
+ install_dir - path to directory to check.
+ salomex_name - extension's name.
+ context - SalomeContext object.
+
+ Returns:
+ True if an envpy file was found and run its init func.
+ """
+
+ logger.debug('Set an env for salome extension: %s...', salomex_name)
+
+ # Set the root dir as env variable
+ if not context:
+ context = salomeContext.SalomeContext(None)
+ context.setVariable('SALOME_APPLICATION_DIR', install_dir, overwrite=False)
+
+ # Find env file
+ ext_envpy = find_envpy(install_dir, salomex_name)
+ if not ext_envpy:
+ return False
+
+ # Get a module
+ envpy_module = module_from_filename(ext_envpy)
+ if not envpy_module:
+ return False
+
+ # Set env if we have something to set
+ ext_root = os.path.join(install_dir, SALOME_EXTDIR)
+ if hasattr(envpy_module, 'init'):
+ envpy_module.init(context, ext_root)
+ return True
+ else:
+ logger.warning('Env file %s doesnt have init func:!', ext_envpy)
+
+ logger.warning('Setting an env for salome extension %s failed!', salomex_name)
+ return False
+
+
+def get_app_root(levels_up=5):
+ """
+ Finds an app root by going up on the given steps.
+
+ Args:
+ levels_up - steps up in dir hierarchy relative to the current file.
+
+ Returns:
+ Path to the app root.
+ """
+
+ app_root = str(Path(__file__).resolve().parents[levels_up - 1])
+ logger.debug('App root: %s', app_root)
+
+ return app_root
import os
import sys
-import importlib.util
-from pathlib import Path
import salomeContext
from SalomeOnDemandTK.extension_utilities import logger, \
- DFILE_EXT, SALOME_EXTDIR, \
- list_files_ext, find_envpy
-
-
-def module_from_filename(filename):
- """
- Create and execute a module by filename.
-
- Args:
- filename - a given python filename.
-
- Returns:
- Module.
- """
-
- # Get the module from the filename
- basename = os.path.basename(filename)
- module_name, _ = os.path.splitext(basename)
-
- spec = importlib.util.spec_from_file_location(module_name, filename)
- if not spec:
- logger.error('Could not get a spec for %s file!')
- return None
-
- module = importlib.util.module_from_spec(spec)
- if not module:
- logger.error('Could not get a module for %s file!')
- return None
-
- sys.modules[module_name] = module
-
- logger.debug('Execute %s module', module_name)
- spec.loader.exec_module(module)
-
- return module
+ DFILE_EXT, \
+ list_files_ext, set_selext_env, get_app_root
def set_ext_env(app_name='', version=''):
logger.debug('Set an env for app: %s, version: %s...', app_name, version)
# Get the root directory
- levels_up = 4
- app_root = str(Path(__file__).resolve().parents[levels_up - 1])
- logger.debug('App root: %s', app_root)
+ app_root = get_app_root()
# Find and source all _env.py files for installed extensions
installed_ext = list_files_ext(app_root, DFILE_EXT)
context.setVariable('SALOME_APPLICATION_DIR', app_root, overwrite=True)
# Execute env file as a module
- ext_root = os.path.join(app_root, SALOME_EXTDIR)
for salomexd in installed_ext:
salomexd_name = os.path.basename(salomexd)
ext_name, _ = os.path.splitext(salomexd_name)
- # Find env file
- ext_envpy = find_envpy(app_root, ext_name)
- if not ext_envpy:
- continue
-
- # Get a module
- envpy_module = module_from_filename(ext_envpy)
- if not envpy_module:
- continue
-
- # Set env if we have something to set
- if hasattr(envpy_module, 'init'):
- envpy_module.init(context, ext_root)
+ set_selext_env(app_root, ext_name, context)
if __name__ == "__main__":