X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fenvironment.py;h=20a5c1eb95dc0b4f6a58873ffa657305a57909d0;hb=cf8129d30d2a819ccee42e611c9f80d5e0aad5b8;hp=de7faa5ff713b073ad73344e8f2b2f8a33c7fa8b;hpb=a7ce8d1b8b251500f8fc8ac88c0752bd0a95d3c8;p=tools%2Fsat.git diff --git a/src/environment.py b/src/environment.py index de7faa5..20a5c1e 100644 --- a/src/environment.py +++ b/src/environment.py @@ -25,32 +25,34 @@ import src import src.debug as DBG import pprint as PP + class Environ: - '''Class to manage the environment context - ''' + """\ + Class to manage the environment context + """ def __init__(self, environ=None): - '''Initialization. If the environ argument is passed, the environment + """Initialization. If the environ argument is passed, the environment will be add to it, else it is the external environment. :param environ dict: - ''' + """ if environ is not None: self.environ = environ else: self.environ = os.environ def __repr__(self): - """easy non exhaustive quick resume for debug print - """ + """easy non exhaustive quick resume for debug print""" return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(self.environ)) def _expandvars(self, value): - '''replace some $VARIABLE into its actual value in the environment + """\ + replace some $VARIABLE into its actual value in the environment :param value str: the string to be replaced :return: the replaced variable :rtype: str - ''' + """ if "$" in value: # The string.Template class is a string class # for supporting $-substitutions @@ -63,12 +65,19 @@ class Environ: return value def append_value(self, key, value, sep=os.pathsep): - '''append value to key using sep - + """\ + append value to key using sep, + if value contains ":" or ";" then raise error + :param key str: the environment variable to append :param value str: the value to append to key :param sep str: the separator string - ''' + """ + # check that value so no contain the system separator + separator=os.pathsep + if separator in value: + raise Exception("Environ append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator)) + # check if the key is already in the environment if key in self.environ: value_list = self.environ[key].split(sep) @@ -82,12 +91,13 @@ class Environ: self.set(key, value) def append(self, key, value, sep=os.pathsep): - '''Same as append_value but the value argument can be a list + """\ + Same as append_value but the value argument can be a list :param key str: the environment variable to append :param value str or list: the value(s) to append to key :param sep str: the separator string - ''' + """ if isinstance(value, list): for v in value: self.append_value(key, v, sep) @@ -95,12 +105,20 @@ class Environ: self.append_value(key, value, sep) def prepend_value(self, key, value, sep=os.pathsep): - '''prepend value to key using sep + """\ + prepend value to key using sep, + if value contains ":" or ";" then raise error :param key str: the environment variable to prepend :param value str: the value to prepend to key :param sep str: the separator string - ''' + """ + # check that value so no contain the system separator + separator=os.pathsep + if separator in value: + raise Exception("Environ append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator)) + + # check if the key is already in the environment if key in self.environ: value_list = self.environ[key].split(sep) if not value in value_list: @@ -112,50 +130,64 @@ class Environ: self.set(key, value) def prepend(self, key, value, sep=os.pathsep): - '''Same as prepend_value but the value argument can be a list + """\ + Same as prepend_value but the value argument can be a list :param key str: the environment variable to prepend :param value str or list: the value(s) to prepend to key :param sep str: the separator string - ''' + """ if isinstance(value, list): - for v in value: + for v in reversed(value): # prepend list, first item at last to stay first self.prepend_value(key, v, sep) else: self.prepend_value(key, value, sep) def is_defined(self, key): - '''Check if the key exists in the environment + """\ + Check if the key exists in the environment :param key str: the environment variable to check - ''' + """ return key in self.environ.keys() def set(self, key, value): - '''Set the environment variable "key" to value "value" + """\ + Set the environment variable "key" to value "value" :param key str: the environment variable to set :param value str: the value - ''' + """ self.environ[key] = self._expandvars(value) def get(self, key): - '''Get the value of the environment variable "key" + """\ + Get the value of the environment variable "key" :param key str: the environment variable - ''' + """ if key in self.environ: return self.environ[key] else: return "" + def get_value(self, key): + """\ + Get the value of the environment variable "key" + This method is added for API compatibility with FileEnviron class + + :param key str: the environment variable + """ + return self.get(key) + def command_value(self, key, command): - '''Get the value given by the system command "command" - and put it in the environment variable key + """\ + Get the value given by the system command "command" + and put it in the environment variable key :param key str: the environment variable :param command str: the command to execute - ''' + """ value = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, @@ -164,16 +196,17 @@ class Environ: class SalomeEnviron: - """Class to manage the environment of SALOME. + """\ + Class to manage the environment of SALOME. """ - def __init__(self, cfg, environ, forBuild=False, for_package=None, enable_simple_env_script = True): - '''Initialization. + """\ + Initialization. :param cfg Config: the global config :param environ Environ: the Environ instance where @@ -182,13 +215,14 @@ class SalomeEnviron: else a build one :param for_package str: If not None, produce a relative environment designed for a package. - ''' + """ self.environ = environ self.cfg = cfg self.forBuild = forBuild self.for_package = for_package self.enable_simple_env_script = enable_simple_env_script self.silent = False + self.has_python = False def __repr__(self): """easy almost exhaustive quick resume for debug print""" @@ -200,43 +234,60 @@ class SalomeEnviron: return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(res)) def append(self, key, value, sep=os.pathsep): - '''append value to key using sep + """\ + append value to key using sep :param key str: the environment variable to append :param value str: the value to append to key :param sep str: the separator string - ''' + """ return self.environ.append(key, value, sep) def prepend(self, key, value, sep=os.pathsep): - '''prepend value to key using sep + """\ + prepend value to key using sep :param key str: the environment variable to prepend :param value str: the value to prepend to key :param sep str: the separator string - ''' + """ return self.environ.prepend(key, value, sep) def is_defined(self, key): - '''Check if the key exists in the environment + """\ + Check if the key exists in the environment :param key str: the environment variable to check - ''' + """ return self.environ.is_defined(key) def get(self, key): - '''Get the value of the environment variable "key" + """\ + Get the value of the environment variable "key" :param key str: the environment variable - ''' + """ return self.environ.get(key) + def get_value(self, key): + """\ + Get the real value of the environment variable "key" + This method is added for API compatibility with FileEnviron class + + :param key str: the environment variable + """ + if key in self.environ: + return self.environ[key] + else: + return "" + def set(self, key, value): - '''Set the environment variable "key" to value "value" + """\ + Set the environment variable "key" to value "value" :param key str: the environment variable to set :param value str: the value - ''' + """ # check if value needs to be evaluated if value is not None and value.startswith("`") and value.endswith("`"): res = subprocess.Popen("echo %s" % value, @@ -247,7 +298,8 @@ class SalomeEnviron: return self.environ.set(key, value) def dump(self, out): - """Write the environment to out + """\ + Write the environment to out :param out file: the stream where to write the environment """ @@ -259,7 +311,8 @@ class SalomeEnviron: out.write("%s=%s\n" % (k, value)) def add_line(self, nb_line): - """Add empty lines to the out stream (in case of file generation) + """\ + Add empty lines to the out stream (in case of file generation) :param nb_line int: the number of empty lines to add """ @@ -267,7 +320,8 @@ class SalomeEnviron: self.environ.add_line(nb_line) def add_comment(self, comment): - """Add a commentary to the out stream (in case of file generation) + """\ + Add a commentary to the out stream (in case of file generation) :param comment str: the commentary to add """ @@ -275,7 +329,8 @@ class SalomeEnviron: self.environ.add_comment(comment) def add_warning(self, warning): - """Add a warning to the out stream (in case of file generation) + """\ + Add a warning to the out stream (in case of file generation) :param warning str: the warning to add """ @@ -283,18 +338,19 @@ class SalomeEnviron: self.environ.add_warning(warning) def finish(self, required): - """Add a final instruction in the out file (in case of file generation) + """\ + Add a final instruction in the out file (in case of file generation) :param required bool: Do nothing if required is False """ if 'finish' in dir(self.environ): self.environ.add_line(1) - self.environ.add_comment("clean all the path") + # what for ? + # self.environ.add_comment("clean all the path") self.environ.finish(required) def set_python_libdirs(self): - """Set some generic variables for python library paths - """ + """Set some generic variables for python library paths""" ver = self.get('PYTHON_VERSION') self.set('PYTHON_LIBDIR0', os.path.join('lib', 'python' + ver, @@ -305,12 +361,14 @@ class SalomeEnviron: self.python_lib0 = self.get('PYTHON_LIBDIR0') self.python_lib1 = self.get('PYTHON_LIBDIR1') + self.has_python = True def get_names(self, lProducts): - """Get the products name to add in SALOME_MODULES environment variable - It is the name of the product, except in the case where the is a - component name. And it has to be in SALOME_MODULES variable only - if the product has the property has_salome_hui = "yes" + """\ + Get the products name to add in SALOME_MODULES environment variable + It is the name of the product, except in the case where the is a + component name. And it has to be in SALOME_MODULES variable only + if the product has the property has_salome_hui = "yes" :param lProducts list: List of products to potentially add """ @@ -330,18 +388,25 @@ class SalomeEnviron: return lProdName def set_application_env(self, logger): - """Sets the environment defined in the APPLICATION file. + """\ + Sets the environment defined in the APPLICATION file. :param logger Logger: The logger instance to display messages """ - # add variable PRODUCT_ROOT_DIR as $workdir in APPLICATION.environ section if not present - try: - tmp = self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR - except: - self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR = src.pyconf.Reference(self.cfg, src.pyconf.DOLLAR, "workdir") - DBG.write("set_application_env add default Config.APPLICATION.environ.PRODUCT_ROOT_DIR", self.cfg.APPLICATION.environ) - + if self.for_package: + self.set("PRODUCT_ROOT_DIR", "out_dir_Path") + else: + self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR = src.pyconf.Reference(self.cfg, src.pyconf.DOLLAR, "workdir") + + # these sensitive variables are reset to avoid bad environment interactions + self.add_line(1) + self.add_comment("reset these sensitive variables to avoid bad environment interactions") + self.add_comment("comment these to lines if you wish a different behaviour") + self.set("LD_LIBRARY_PATH", "") + self.set("PYTHONPATH", "") + self.add_line(1) + # Set the variables defined in the "environ" section if 'environ' in self.cfg.APPLICATION: # we write PRODUCT environment it in order to conform to @@ -354,19 +419,11 @@ class SalomeEnviron: self.load_cfg_environment(self.cfg.APPLICATION.environ.launch) self.add_line(1) - # If there is an "environ_script" section, load the scripts - if 'environ_script' in self.cfg.APPLICATION: - for pscript in self.cfg.APPLICATION.environ_script: - self.add_comment("script %s" % pscript) - sname = pscript.replace(" ", "_") - self.run_env_script("APPLICATION_%s" % sname, - self.cfg.APPLICATION.environ_script[pscript], - logger) - self.add_line(1) def set_salome_minimal_product_env(self, product_info, logger): - """Sets the minimal environment for a SALOME product. - xxx_ROOT_DIR and xxx_SRC_DIR + """\ + Sets the minimal environment for a SALOME product. + xxx_ROOT_DIR and xxx_SRC_DIR :param product_info Config: The product description :param logger Logger: The logger instance to display messages @@ -396,7 +453,8 @@ class SalomeEnviron: product_info.name)) def set_salome_generic_product_env(self, pi): - """Sets the generic environment for a SALOME product. + """\ + Sets the generic environment for a SALOME product. :param pi Config: The product description """ @@ -416,16 +474,21 @@ class SalomeEnviron: lib_path = os.path.join(envcompo_root_dir, 'lib', 'salome') l_binpath_libpath.append( (bin_path, lib_path) ) + if src.get_property_in_product_cfg(pi, "fhs"): lib_path = os.path.join(env_root_dir, 'lib') - pylib1_path = os.path.join(env_root_dir, self.python_lib0) - pylib2_path = os.path.join(env_root_dir, self.python_lib1) bin_path = os.path.join(env_root_dir, 'bin') + if self.has_python: + # if the application doesn't include python, we don't need these two lines + pylib1_path = os.path.join(env_root_dir, self.python_lib0) + pylib2_path = os.path.join(env_root_dir, self.python_lib1) else: lib_path = os.path.join(env_root_dir, 'lib', 'salome') - pylib1_path = os.path.join(env_root_dir, self.python_lib0, 'salome') - pylib2_path = os.path.join(env_root_dir, self.python_lib1, 'salome') bin_path = os.path.join(env_root_dir, 'bin', 'salome') + if self.has_python: + # if the application doesn't include python, we don't need these two lines + pylib1_path = os.path.join(env_root_dir, self.python_lib0, 'salome') + pylib2_path = os.path.join(env_root_dir, self.python_lib1, 'salome') # Construct the paths to prepend to PATH and LD_LIBRARY_PATH and # PYTHONPATH @@ -439,11 +502,16 @@ class SalomeEnviron: else : self.prepend('LD_LIBRARY_PATH', lib_path) - l = [ bin_path, lib_path, pylib1_path, pylib2_path ] - self.prepend('PYTHONPATH', l) + l = [ bin_path, lib_path ] + if not src.product.product_is_wheel(pi): + if self.has_python: + l.append(pylib1_path) + l.append(pylib2_path) + self.prepend('PYTHONPATH', l) def set_cpp_env(self, product_info): - """Sets the generic environment for a SALOME cpp product. + """\ + Sets the generic environment for a SALOME cpp product. :param product_info Config: The product description """ @@ -465,14 +533,15 @@ class SalomeEnviron: else : self.prepend('LD_LIBRARY_PATH', lib_path) - l = [ bin_path, lib_path, - os.path.join(env_root_dir, self.python_lib0), - os.path.join(env_root_dir, self.python_lib1) - ] + l = [ bin_path, lib_path ] + if self.has_python: + l.append(os.path.join(env_root_dir, self.python_lib0)) + l.append(os.path.join(env_root_dir, self.python_lib1)) self.prepend('PYTHONPATH', l) def load_cfg_environment(self, cfg_env): - """Loads environment defined in cfg_env + """\ + Loads environment defined in cfg_env :param cfg_env Config: A config containing an environment """ @@ -513,7 +582,8 @@ class SalomeEnviron: self.set(env_def, val) def set_a_product(self, product, logger): - """Sets the environment of a product. + """\ + Sets the environment of a product. :param product str: The product name :param logger Logger: The logger instance to display messages @@ -521,6 +591,11 @@ class SalomeEnviron: # Get the informations corresponding to the product pi = src.product.get_product_config(self.cfg, product) + + # skip compile time products at run time + if not self.forBuild: + if src.product.product_is_compile_time(pi): + return # skip mesa products (if any) at run time, # unless use_mesa property was activated @@ -559,6 +634,12 @@ class SalomeEnviron: self.set_salome_minimal_product_env(pi, logger) self.set_salome_generic_product_env(pi) + # use variable LICENCE_FILE to communicate the licence file name to the environment script + licence_file_name = src.product.product_has_licence(pi, self.cfg.PATHS.LICENCEPATH) + if licence_file_name: + logger.write("licence file found for product %s : %s\n" % (pi.name, licence_file_name), 5) + self.set("LICENCE_FILE", licence_file_name) + if src.product.product_is_cpp(pi): # set a specific environment for cpp modules self.set_salome_minimal_product_env(pi, logger) @@ -572,7 +653,7 @@ class SalomeEnviron: source_dir_save = pi.source_dir name_save = pi.name pi.install_dir = os.path.join(self.cfg.APPLICATION.workdir, - "INSTALL", + config.INTERNAL.config.install_dir, pi.component_name) if self.for_package: pi.install_dir = os.path.join("out_dir_Path", @@ -605,7 +686,8 @@ class SalomeEnviron: def run_env_script(self, product_info, logger=None, native=False): - """Runs an environment script. + """\ + Runs an environment script. :param product_info Config: The product description :param logger Logger: The logger instance to display messages @@ -626,10 +708,22 @@ class SalomeEnviron: pyproduct = imp.load_source(product_info.name + "_env_script", env_script) if not native: - pyproduct.set_env(self, - product_info.install_dir, - product_info.version) + if self.forBuild and "set_env_build" in dir(pyproduct): + pyproduct.set_env_build(self, + product_info.install_dir, + product_info.version) + elif (not self.forBuild) and "set_env_launch" in dir(pyproduct): + pyproduct.set_env_launch(self, + product_info.install_dir, + product_info.version) + else: + # at least this one is mandatory, + # if set_env_build and set_env_build are not defined + pyproduct.set_env(self, + product_info.install_dir, + product_info.version) else: + # not mandatory, if set_nativ_env not defined, we do nothing if "set_nativ_env" in dir(pyproduct): pyproduct.set_nativ_env(self) except: @@ -640,8 +734,9 @@ class SalomeEnviron: traceback.print_exc() def run_simple_env_script(self, script_path, logger=None): - """Runs an environment script. Same as run_env_script, but with a - script path as parameter. + """\ + Runs an environment script. Same as run_env_script, but with a + script path as parameter. :param script_path str: a path to an environment script :param logger Logger: The logger instance to display messages @@ -674,7 +769,8 @@ class SalomeEnviron: traceback.print_exc() def set_products(self, logger, src_root=None): - """Sets the environment for all the products. + """\ + Sets the environment for all the products. :param logger Logger: The logger instance to display messages :param src_root src: the application working directory @@ -695,35 +791,43 @@ class SalomeEnviron: self.finish(False) def set_full_environ(self, logger, env_info): - """Sets the full environment for products - specified in env_info dictionary. + """\ + Sets the full environment for products + specified in env_info dictionary. :param logger Logger: The logger instance to display messages :param env_info list: the list of products """ DBG.write("set_full_environ for", env_info) # DBG.write("set_full_environ config", self.cfg.APPLICATION.environ, True) + # set product environ self.set_application_env(logger) - self.set_python_libdirs() + if "Python" in env_info: + self.set_a_product("Python", logger) + self.set_python_libdirs() # set products for product in env_info: + if product == "Python": + continue self.set_a_product(product, logger) class FileEnvWriter: - """Class to dump the environment to a file. + """\ + Class to dump the environment to a file. """ def __init__(self, config, logger, out_dir, src_root, env_info=None): - '''Initialization. + """\ + Initialization. :param cfg Config: the global config :param logger Logger: The logger instance to display messages :param out_dir str: The directory path where t put the output files :param src_root str: The application working directory :param env_info str: The list of products to add in the files. - ''' + """ self.config = config self.logger = logger self.out_dir = out_dir @@ -732,7 +836,8 @@ class FileEnvWriter: self.env_info = env_info def write_env_file(self, filename, forBuild, shell, for_package = None): - """Create an environment file. + """\ + Create an environment file. :param filename str: the file path :param forBuild bool: if true, the build environment @@ -778,8 +883,9 @@ class FileEnvWriter: additional_env = {}, for_package = None, with_commercial = True): - """Append to current opened aFile a cfgForPy - environment (SALOME python launcher). + """\ + Append to current opened aFile a cfgForPy + environment (SALOME python launcher). :param filename str: the file path :param additional_env dict: a dictionary of additional variables @@ -792,9 +898,9 @@ class FileEnvWriter: src.printcolors.printcLabel(filename.name), 3) # create then env object - tmp = src.fileEnviron.get_file_environ(filename, - "cfgForPy", - {}) + tmp = src.fileEnviron.get_file_environ(filename, "cfgForPy", {}) + # DBG.write("fileEnviron.get_file_environ %s" % filename, tmp, True) + # environment for launch env = SalomeEnviron(self.config, tmp, @@ -803,19 +909,22 @@ class FileEnvWriter: enable_simple_env_script = with_commercial) env.silent = self.silent + DBG.write("write_cfgForPy_file", self.config.APPLICATION.environ) + if self.env_info is not None: env.set_full_environ(self.logger, self.env_info) + DBG.write("set_full_environ", self.env_info) + else: # set env from PRODUCT env.set_application_env(self.logger) # The list of products to launch lProductsName = env.get_names(self.config.APPLICATION.products.keys()) - env.set( "SALOME_MODULES", ','.join(lProductsName)) + env.set("SALOME_MODULES", ','.join(lProductsName)) # set the products - env.set_products(self.logger, - src_root=self.src_root) + env.set_products(self.logger, src_root=self.src_root) # Add the additional environment if it is not empty if len(additional_env) != 0: @@ -826,19 +935,22 @@ class FileEnvWriter: env.finish(True) class Shell: - """Definition of a Shell. + """\ + Definition of a Shell. """ def __init__(self, name, extension): - '''Initialization. + """\ + Initialization. :param name str: the shell name :param extension str: the shell extension - ''' + """ self.name = name self.extension = extension def load_environment(config, build, logger): - """Loads the environment (used to run the tests, for example). + """\ + Loads the environment (used to run the tests, for example). :param config Config: the global config :param build bool: build environement if True