From: Serge Rehbinder Date: Fri, 22 Apr 2016 12:00:46 +0000 (+0200) Subject: First environ command version X-Git-Tag: sprint-04~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1af4c4f18d40c9a984971cb4ee8e20aec6b6f3ee;p=tools%2Fsat.git First environ command version --- diff --git a/commands/config.py b/commands/config.py index 9d35e54..79169e0 100644 --- a/commands/config.py +++ b/commands/config.py @@ -486,7 +486,8 @@ def get_config_children(config, args): try: a = config.getByPath(head) if dir(a).__contains__('keys'): - vals = map(lambda x: head + '.' + x, [m for m in a.keys() if m.startswith(tail)]) + vals = map(lambda x: head + '.' + x, + [m for m in a.keys() if m.startswith(tail)]) except: pass diff --git a/commands/environ.py b/commands/environ.py new file mode 100644 index 0000000..981e69c --- /dev/null +++ b/commands/environ.py @@ -0,0 +1,571 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +# Copyright (C) 2010-2013 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import sys +import subprocess + +import src + +parser = src.options.Options() +parser.add_option('', 'shell', 'list2', 'shell', + _("Generates the environment files for the given format: bash (default), batch or all."), []) +parser.add_option('p', 'products', 'list2', 'products', + _("Includes only the specified products.")) +parser.add_option('p', 'prefix', 'string', 'prefix', + _("Specifies the prefix for the environment files."), "env") +parser.add_option('t', 'target', 'string', 'out_dir', + _("Specifies the directory path where to put the environment files."), None) + +# list of available shells with extensions +C_SHELLS = { "bash": "sh", "batch": "bat" } +C_ALL_SHELL = [ "bash", "batch" ] + +class SalomeEnviron: + """Class to manage the environment of SALOME. + """ + + def __init__(self, cfg, environ, forBuild=False): + self.environ = environ + self.cfg = cfg + self.forBuild = forBuild + self.silent = False + + def __repr__(self): + """easy non exhaustive quick resume for debug print""" + res={} + res["environ"]=str(self.environ) + res["forBuild"]=self.forBuild + return self.__class__.__name__ + str(res)[0:-1] + " ...etc...}" + + def append(self, key, value, sep=os.pathsep): + return self.environ.append(key, value, sep) + + def prepend(self, key, value, sep=os.pathsep): + return self.environ.prepend(key, value, sep) + + def is_defined(self, key): + return self.environ.is_defined(key) + + def get(self, key): + return self.environ.get(key) + + def set(self, key, 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, shell=True, stdout=subprocess.PIPE).communicate() + value = res[0].strip() + + return self.environ.set(key, value) + + def dump(self, out): + """Write the environment to out""" + for k in self.environ.environ.keys(): + try: + value = self.get(k) + except: + value = "?" + out.write("%s=%s\n" % (k, value)) + + def add_line(self, nb_line): + if 'add_line' in dir(self.environ): + self.environ.add_line(nb_line) + + def add_comment(self, comment): + if 'add_comment' in dir(self.environ): + self.environ.add_comment(comment) + + def add_warning(self, warning): + if 'add_warning' in dir(self.environ): + self.environ.add_warning(warning) + + def finish(self, required): + if 'finish' in dir(self.environ): + self.environ.add_line(1) + self.environ.add_comment("clean all the path") + self.environ.finish(required) + + def list_version_4_prereq(self, prerequisite, logger): + alist = [] + for path in self.cfg.TOOLS.environ.prereq_install_dir: + if not os.path.exists(path): + continue + prereqlist = os.listdir(path) + for prereq in prereqlist: + if prereq.split("-")[0] == prerequisite: + #logger.error(str(prereq) + "\n") + alist.append(str(prereq)) + + if len(alist) > 0: + logger.write(_("Available prerequisites are:") + "\n\t%s\n" % '\n\t'.join(alist), 2) + + def set_python_libdirs(self): + if src.architecture.is_windows(): + # sysconfig.get_python_lib() does not return appropriate path on Windows + # clearly decide here once for windows + ver = self.get('PYTHON_VERSION') + self.set('PYTHON_LIBDIR0', os.path.join('lib', 'python' + ver, 'site-packages')) + self.set('PYTHON_LIBDIR1', os.path.join('lib64', 'python' + ver, 'site-packages')) + + else: + """obsolete: too hazardous for WHEN we have to interpret that throught new python script salomeContext + #less "' is clearer and safer for Popen etc... + cmd = 'python -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(plat_specific=%s, standard_lib=False, prefix=str()))"' + #False==0 ; True==1 + self.environ.command_value('PYTHON_LIBDIR0', cmd % "False") + self.environ.command_value('PYTHON_LIBDIR1', cmd % "True") + """ + #cleary decide here once for linux + ver = self.get('PYTHON_VERSION') + self.set('PYTHON_LIBDIR0', os.path.join('lib', 'python' + ver, 'site-packages')) + self.set('PYTHON_LIBDIR1', os.path.join('lib64', 'python' + ver, 'site-packages')) + + self.python_lib0 = self.get('PYTHON_LIBDIR0') + self.python_lib1 = self.get('PYTHON_LIBDIR1') + + ## + # 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 has_gui = "yes" + def getNames(self, lProducts): + lProdHasGui = [p for p in lProducts if 'has_gui' in src.product.get_product_config(self.cfg, p) and src.product.get_product_config(self.cfg, p).has_gui=='yes'] + lProdName = [] + for ProdName in lProdHasGui: + pi = src.product.get_product_config(self.cfg, ProdName) + if 'component_name' in pi: + lProdName.append(pi.component_name) + else: + lProdName.append(ProdName) + return lProdName + + ## + # Sets the environment defined in the PRODUCT file. + def set_application_env(self, logger): + if 'environ' in self.cfg.APPLICATION: + self.add_comment("APPLICATION environment") + for p in self.cfg.APPLICATION.environ: + self.set(p, self.cfg.APPLICATION.environ[p]) + self.add_line(1) + + 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) + + if 'profile' in self.cfg.APPLICATION: + profile_product = self.cfg.APPLICATION.profile.product + product_info_profile = src.product.get_product_config(self.cfg, profile_product) + profile_share_salome = os.path.join( product_info_profile.install_dir, "share", "salome" ) + self.set( "SUITRoot", profile_share_salome ) + self.set( "SalomeAppConfig", os.path.join( profile_share_salome, "resources", profile_product.lower() ) ) + + # The list of products to launch + lProductsName = self.getNames(self.cfg.APPLICATION.products.keys()) + + self.set( "SALOME_MODULES", ','.join(lProductsName)) + + ## + # Set xxx_ROOT_DIR and xxx_SRC_DIR. + def set_salome_minimal_product_env(self, product_info, logger, single_dir, cfgdic=None): + # set root dir + root_dir = product_info.name + "_ROOT_DIR" + indic = cfgdic is not None and root_dir in cfgdic + if not self.is_defined(root_dir) and not indic: + if single_dir: + self.set(root_dir, os.path.join(self.get('INSTALL_ROOT'), 'SALOME')) + elif 'install_dir' in product_info and product_info.install_dir: + self.set(root_dir, product_info.install_dir) + elif not self.silent: + logger.write(" " + _("No install_dir for product %s\n") % product_info.name, 5) + + # set source dir, unless the product is fixed (no source dir) + if not src.product.product_is_fixed(product_info): + src_dir = product_info.name + "_SRC_DIR" + indic = cfgdic is not None and src_dir in cfgdic + if not self.is_defined(src_dir) and not indic: + self.set(src_dir, product_info.source_dir) + + def set_salome_generic_product_env(self, product): + pi = src.product.get_product_config(self.cfg, product) + env_root_dir = self.get(pi.name + "_ROOT_DIR") + l_binpath_libpath = [] + + # create additional ROOT_DIR for CPP components + if 'component_name' in pi: + compo_name = pi.component_name + if compo_name + "CPP" == product: + compo_root_dir = compo_name + "_ROOT_DIR" + envcompo_root_dir = os.path.join( self.cfg.TOOLS.common.install_root, compo_name ) + self.set(compo_root_dir , envcompo_root_dir) + bin_path = os.path.join(envcompo_root_dir, 'bin', 'salome') + lib_path = os.path.join(envcompo_root_dir, 'lib', 'salome') + l_binpath_libpath.append( (bin_path, lib_path) ) + + appliname = 'salome' + if src.get_cfg_param(pi, 'product_type', 'SALOME').upper() not in [ "SALOME", "SMESH_PLUGIN", "SAMPLE" ]: + appliname = '' + + bin_path = os.path.join(env_root_dir, 'bin', appliname) + lib_path = os.path.join(env_root_dir, 'lib', appliname) + l_binpath_libpath.append( (bin_path, lib_path) ) + + for bin_path, lib_path in l_binpath_libpath: + if not self.forBuild: + self.prepend('PATH', bin_path) + if src.architecture.is_windows(): + self.prepend('PATH', lib_path) + else : + self.prepend('LD_LIBRARY_PATH', lib_path) + + l = [ bin_path, lib_path, + os.path.join(env_root_dir, self.python_lib0, appliname), + os.path.join(env_root_dir, self.python_lib1, appliname) + ] + self.prepend('PYTHONPATH', l) + + ## + # Loads environment define in the configuration. + def load_cfg_environment(self, cfg_env): + for env_def in cfg_env: + val = cfg_env[env_def] + if isinstance(val, src.pyconf.Mapping): + continue + + if isinstance(val, src.pyconf.Sequence): + # transform into list of strings + val = map(lambda l: l, val) + + if env_def.startswith("_"): + # separator exception for PV_PLUGIN_PATH + if env_def[1:] == 'PV_PLUGIN_PATH': + self.prepend(env_def[1:], val, ';') + else: + self.prepend(env_def[1:], val) + elif env_def.endswith("_"): + # separator exception for PV_PLUGIN_PATH + if env_def[:-1] == 'PV_PLUGIN_PATH': + self.prepend(env_def[:-1], val, ';') + else: + self.prepend(env_def[:-1], val) + else: + self.set(env_def, val) + + ## + # Sets the environment of a product. + def set_a_product(self, product, logger, single_dir): + + if not self.silent: + logger.write(_("Setting environment for %s\n") % product, 4) + + self.add_line(1) + self.add_comment('setting environ for ' + product) + + pi = src.product.get_product_config(self.cfg, product) + + # Do not define environment if the product is native or fixed + if src.product.product_is_native(pi): + return + + if "environ" in pi: + # set environment using definition of the product + self.set_salome_minimal_product_env(pi, logger, single_dir, pi.environ) + self.set_salome_generic_product_env(product) + self.load_cfg_environment(pi.environ) + if self.forBuild and "build" in pi.environ: + self.load_cfg_environment(pi.environ.build) + if not self.forBuild and "launch" in pi.environ: + self.load_cfg_environment(pi.environ.launch) + else: + # no environment defined in config + self.set_salome_minimal_product_env(pi, logger, single_dir) + if 'install_dir' in pi : + self.set_salome_generic_product_env(product) + + # if product_info defines a env_scripts load it + if 'env_script' in pi: + self.run_env_script(product, pi.env_script, logger) + + + ## + # Runs an environment script. + def run_env_script(self, product, env_script, logger=None): + if not os.path.exists(env_script): + raise src.SatException(_("Environment script not found: %s") % env_script) + + if not self.silent and logger is not None: + logger.write(" ** load %s\n" % env_script, 4) + + try: + import imp + pyproduct = imp.load_source(product + "_env_script", env_script) + pyproduct.load_env(self) + except: + __, exceptionValue, exceptionTraceback = sys.exc_info() + print(exceptionValue) + import traceback + traceback.print_tb(exceptionTraceback) + traceback.print_exc() + + ## + # Sets the environment for all the products. + def set_products(self, logger, src_root=None, single_dir=False): + self.add_line(1) + self.add_comment('setting environ for all products') + + self.set_python_libdirs() + + if src_root is None: + src_root = self.cfg.APPLICATION.workdir + self.set('SRC_ROOT', src_root) + + appli_name = "APPLI" + if "APPLI" in self.cfg and "application_name" in self.cfg.APPLI: + appli_name = self.cfg.APPLI.application_name + self.set("SALOME_APPLI_ROOT", os.path.join(self.cfg.APPLICATION.workdir, appli_name)) + + if not single_dir: + single_dir = src.get_cfg_param(self.cfg.APPLICATION, "compil_in_single_dir", "no") == 'yes' + + for product in src.get_cfg_param(self.cfg.APPLICATION, "imported_products", []): + self.set_a_product(product, logger, single_dir=single_dir) + self.finish(False) + + for product in self.cfg.APPLICATION.products.keys(): + self.set_a_product(product, logger, single_dir=single_dir) + self.finish(False) + + + ## + # Sets the full environment for prerequisites and products specified in env_info dictionary. + def set_full_environ(self, logger, env_info): + # set product environ + self.set_application_env(logger) + + # set products + self.set('INSTALL_ROOT', self.cfg.TOOLS.common.install_root) + self.set('SRC_ROOT', self.cfg.TOOLS.common.source_root) + self.set_python_libdirs() + + single_dir = src.get_cfg_param(self.cfg.PRODUCT, "compil_in_single_dir", "no") == 'yes' + for product in env_info['products']: + self.set_a_product(product, logger, single_dir=single_dir) + +## +# Class to dump the environment to a file. +class FileEnvWriter: + def __init__(self, config, logger, out_dir, src_root, single_dir, env_info=None): + self.config = config + self.logger = logger + self.out_dir = out_dir + self.src_root= src_root + self.single_dir = single_dir + self.silent = True + self.env_info = env_info + + def write_env_file(self, filename, forBuild, shell): + """Create an environment file.""" + if not self.silent: + self.logger.write(_("Create environment file %s\n") % src.printcolors.printcLabel(filename), 3) + + # create then env object + env_file = open(os.path.join(self.out_dir, filename), "w") + tmp = src.fileEnviron.get_file_environ(env_file, shell, {}, self.config ) + env = SalomeEnviron(self.config, tmp, forBuild) + env.silent = self.silent + + if self.env_info is not None: + env.set_full_environ(self.logger, self.env_info) + else: + # set env from PRODUCT + env.set_application_env(self.logger) + # set the products + env.set_products(self.logger, + src_root=self.src_root, single_dir=self.single_dir) + + # add cleanup and close + env.finish(True) + env_file.close() + + return env_file.name + + def write_product_file(self, filename, shell): + """Create a product file.""" + if not self.silent: + self.logger.write(_("Create product file %s\n") % src.printcolors.printcLabel(filename), 3) + + prod_file = open(os.path.join(self.out_dir, filename), "w") + if shell == "bash": + content = _bash_content % self.out_dir + elif shell == "batch": + content = _batch_content % self.out_dir + else: + raise src.SatException(_("Unknown shell: %s") % shell) + + prod_file.write(content) + prod_file.close() + + return prod_file.name + + def write_cfgForPy_file(self, aFile, additional_env = {}): + """append to current opened aFile a cfgForPy environment (python syntax).""" + if not self.silent: + self.logger.write(_("Create configuration file %s\n") % src.printcolors.printcLabel(aFile.name), 3) + + # create then env object + tmp = src.fileEnviron.get_file_environ(aFile, "cfgForPy", {}, self.config) + forBuild = True + forLaunch = False + env = SalomeEnviron(self.config, tmp, forLaunch) + env.silent = self.silent + + if self.env_info is not None: + env.set_full_environ(self.logger, self.env_info) + else: + # set env from PRODUCT + env.set_application_env(self.logger) + # set the prerequisites + env.set_prerequisites(self.logger) + # set the products + env.set_products(self.logger, + src_root=self.src_root, single_dir=self.single_dir) + + if len(additional_env) != 0: + for variable in additional_env: + env.set(variable, additional_env[variable]) + + # add cleanup and close + env.finish(True) + + +# create bash product file +_bash_content = """PRODUCT_DIR=%s +if [[ "${ENV_FOR_LAUNCH}x" == "x" ]] +then + export ENV_FOR_LAUNCH=1 +fi + +if [[ "${ENV_FOR_LAUNCH}" == "1" ]] +then + source $PRODUCT_DIR/env_launch.sh +else + source $PRODUCT_DIR/env_build.sh +fi +""" + +# create batch product file +_batch_content = """set PRODUCT_DIR=%s +IF NOT DEFINED ENV_FOR_LAUNCH set ENV_FOR_LAUNCH=1 + +if "%%ENV_FOR_LAUNCH%%"=="1" ( + %%PRODUCT_DIR%%\\env_launch.bat +) else ( + %%PRODUCT_DIR%%\\env_build.bat +) +""" + +## +# Definition of a Shell. +class Shell: + def __init__(self, name, extension): + self.name = name + self.extension = extension + +## +# Loads the environment (used to run the tests). +def load_environment(config, build, logger): + environ = SalomeEnviron(config, src.environment.Environ(os.environ), build) + environ.set_application_env(logger) + environ.set_prerequisites(logger) + environ.set_products(logger) + environ.finish(True) + +## +# Writes all the environment files +def write_all_source_files(config, logger, out_dir=None, src_root=None, + single_dir=None, silent=False, shells=["bash"], prefix="env", env_info=None): + if not out_dir: + out_dir = config.APPLICATION.workdir + + if not os.path.exists(out_dir): + raise src.SatException(_("Target directory not found: %s") % out_dir) + + if not silent: + logger.write(_("Creating environment files for %s\n") % src.printcolors.printcLabel(config.APPLICATION.name), 2) + src.printcolors.print_value(logger, _("Target"), src.printcolors.printcInfo(out_dir), 3) + logger.write("\n", 3, False) + + shells_list = [] + all_shells = C_ALL_SHELL + if "all" in shells: + shells = all_shells + else: + shells = filter(lambda l: l in all_shells, shells) + + for shell in shells: + if shell not in C_SHELLS: + logger.write(_("Unknown shell: %s\n") % shell, 2) + else: + shells_list.append(Shell(shell, C_SHELLS[shell])) + + writer = FileEnvWriter(config, logger, out_dir, src_root, single_dir, env_info) + writer.silent = silent + files = [] + for_build = True + for_launch = False + for shell in shells_list: + files.append(writer.write_env_file("%s_launch.%s" % (prefix, shell.extension), for_launch, shell.name)) + files.append(writer.write_env_file("%s_build.%s" % (prefix, shell.extension), for_build, shell.name)) + + return files + +################################################## + +## +# Describes the command +def description(): + return _("""The environ command generates the " + "environment files of your application.""") + +## +# Runs the command. +def run(args, runner, logger): + (options, args) = parser.parse_args(args) + + # check that the command was called with an application + src.check_config_has_application( runner.cfg ) + + if options.products is None: + environ_info = None + else: + environ_info = {} + + # add products specified by user (only products included in the application) + environ_info['products'] = filter(lambda l: l in runner.cfg.APPLICATION.products.keys(), options.products) + + if options.shell == []: + shell = ["bash"] + if src.architecture.is_windows(): + shell = ["batch"] + else: + shell = options.shell + + write_all_source_files(runner.cfg, logger, out_dir=options.out_dir, shells=shell, + prefix=options.prefix, env_info=environ_info) + logger.write("\n", 3, False) diff --git a/src/__init__.py b/src/__init__.py index 8e68a1c..04a0928 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -29,6 +29,8 @@ from . import system from . import ElementTree from . import logger from . import product +from . import environment +from . import fileEnviron OK_STATUS = "OK" KO_STATUS = "KO" @@ -61,7 +63,22 @@ def check_config_has_application( config, details = None ): def config_has_application( config ): return 'APPLICATION' in config - + +def get_cfg_param(config, param_name, default): + '''Search for param_name value in config. + If param_name is not in config, then return default, + else, return the found value + + :param config class 'common.pyconf.Config': The config. + :param param_name str: the name of the parameter to get the value + :param default str: The value to return if param_name is not in config + :return: see initial description of the function + :rtype: str + ''' + if param_name in config: + return config[param_name] + return default + def print_info(logger, info): '''Prints the tuples that are in info variable in a formatted way. diff --git a/src/environment.py b/src/environment.py new file mode 100644 index 0000000..95f7b3c --- /dev/null +++ b/src/environment.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +# Copyright (C) 2010-2013 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import subprocess +import string + +import src + +class Environ: + '''Class to manage the environment context + ''' + def __init__(self, environ=None): + '''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 + """ + res={} + res["environ"]=self.environ + return self.__class__.__name__ + str(res)[0:-1] + " ...etc...}" + + def _expandvars(self, value): + '''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 + zt = string.Template(value) + try: + value = zt.substitute(self.environ) + except KeyError as exc: + raise src.SatException(_("Missing definition " + "in environment: %s") % str(exc)) + return value + + def append_value(self, key, value, sep=os.pathsep): + '''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 + ''' + # check if the key is already in the environment + if key in self.environ: + value_list = self.environ[key].split(sep) + # Check if the value is already in the key value or not + if not value in value_list: + value_list.append(value) + else: + value_list.append(value_list.pop(value_list.index(value))) + self.set(key, sep.join(value_list)) + else: + self.set(key, value) + + def append(self, key, value, sep=os.pathsep): + '''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) + else: + self.append_value(key, value, sep) + + def prepend_value(self, key, value, sep=os.pathsep): + '''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 + ''' + if key in self.environ: + value_list = self.environ[key].split(sep) + if not value in value_list: + value_list.insert(0, value) + else: + value_list.insert(0, value_list.pop(value_list.index(value))) + self.set(key, sep.join(value_list)) + else: + self.set(key, value) + + def prepend(self, key, value, sep=os.pathsep): + '''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: + 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 + + :param key str: the environment variable to check + ''' + return self.environ.has_key(key) + + def set(self, key, 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" + + :param key str: the environment variable + ''' + if key in self.environ: + return self.environ[key] + else: + return "" + + def command_value(self, key, command): + '''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, + env=self.environ).communicate()[0] + self.environ[key] = value diff --git a/src/fileEnviron.py b/src/fileEnviron.py new file mode 100644 index 0000000..389fc3b --- /dev/null +++ b/src/fileEnviron.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +# Copyright (C) 2010-2013 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os + +batch_header="""@echo off + +rem The following variables are used only in case of a sat package +set out_dir_Path=%~dp0 +set PRODUCT_OUT_DIR=%out_dir_Path% +set prereq_install_Path=%out_dir_Path%\PREREQUISITES\INSTALL +set prereq_build_Path=%out_dir_Path%\PREREQUISITES\BUILD +""" + + +bash_header="""#!/bin/bash +########################################################################## +# +#### cleandup ### +# cleanup a path (first parameter) from duplicated entries; +# second parameter is the separator +cleandup() { +out_var=`echo $1 | awk -v sep=$2 '{ \\ + na = split($1,a,sep); \\ + k=0; \\ + for(i=0;i<=na;i++) { \\ + found=0; \\ + for(j=0;j tmp.txt\n' % (command)) + self.output.write('set /p %s =< tmp.txt\n' % (key)) + + def finish(self, required=True): + return + +## +# Base class for cfg environment file. +class FileCfg: + def __init__(self, output, environ=None): + self._do_init(output, environ) + + def _do_init(self, output, environ=None): + self.output = output + self.toclean = [] + if environ is not None: + self.environ = environ + else: + self.environ = os.environ + if not self.environ.has_key("PATH"): + self.environ["PATH"]="" + if not self.environ.has_key("LD_LIBRARY_PATH"): + self.environ["LD_LIBRARY_PATH"]="" + if not self.environ.has_key("PYTHONPATH"): + self.environ["PYTHONPATH"]="" + if not self.environ.has_key("TCLLIBPATH"): + self.environ["TCLLIBPATH"]="" + if not self.environ.has_key("TKLIBPATH"): + self.environ["TKLIBPATH"]="" + + + def add_line(self, number): + self.output.write("\n" * number) + + def add_comment(self, comment): + self.output.write("# %s\n" % comment) + + def add_echo(self, text): + self.output.write('# %s"\n' % text) + + def add_warning(self, warning): + self.output.write('# "WARNING %s"\n' % warning) + + def append_value(self, key, value, sep=":"): + if self.is_defined(key) : + self.add(key, value) + else : + self.set(key, value) + + def append(self, key, value, sep=":"): + if isinstance(value, list): + self.append_value(key, sep.join(value), sep) + else: + self.append_value(key, value, sep) + + def prepend_value(self, key, value, sep=":"): + if self.is_defined(key) : + self.add(key, value) + else : + self.set(key, value) + + def prepend(self, key, value, sep=":"): + if isinstance(value, list): + self.prepend_value(key, sep.join(value), sep) + else: + self.prepend_value(key, value, sep) + + def is_defined(self, key): + return self.environ.has_key(key) + + def set(self, key, value): + raise NotImplementedError("set is not implement for file .cfg!") + + def get(self, key): + return '${%s}' % key + + def command_value(self, key, command): + raise NotImplementedError("command_value is not implement for file .cfg!") + + def finish(self, required=True): + #for (key, sep) in self.toclean: + # if sep != ' ': + # self.output.write('clean %s "%s"\n' % (key, sep)) + #self.output.write("# finish\n") + pass + + +def specialPathSeparator(name): + """TCLLIBPATH, TKLIBPATH, PV_PLUGIN_PATH environments variables needs some exotic path separator""" + specialBlanksKeys=["TCLLIBPATH", "TKLIBPATH"] + specialSemicolonKeys=["PV_PLUGIN_PATH"] + res=os.pathsep + if name in specialBlanksKeys: res=" " + if name in specialSemicolonKeys: res=";" + return res + +## +# +## +# Class for generate a cfg file script (in python syntax) SalomeContext API. +class CfgForPyFileEnviron(FileCfg): + def __init__(self, output, environ=None, config=None): + self.config=config + self._do_init(output, environ) + + self.indent=" " # four whitespaces for first indentation in a python script + self.prefix="context." + self.setVarEnv="setVariable" + + self.begin=self.indent+self.prefix + self.output.write((cfgForPy_header) % config['VARS']['product']) + self.specialKeys={"PATH": "Path", "LD_LIBRARY_PATH": "LdLibraryPath", "PYTHONPATH": "PythonPath"} + + def changeToCfg(self, value): + res=value + return res + + def set(self, key, value): + self.output.write(self.begin+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % (key, self.changeToCfg(value))) + self.environ[key] = value + + def add(self, key, value): + if key in self.specialKeys.keys(): + self.output.write(self.begin+'addTo%s(r"%s")\n' % (self.specialKeys[key], self.changeToCfg(value))) + self.environ[key]+=":"+value + return + sep=specialPathSeparator(key) + self.output.write(self.indent+'#temporary solution!!! have to be defined in API a ?dangerous? addToSpecial(r"%s", r"%s")\n' % (key, value)) + #pathsep not precised because do not know future os launch? + self.output.write(self.begin+'addToSpecial(r"%s", r"%s")\n' % (key, self.changeToCfg(value))) + self.environ[key]+=sep+value #here yes we know os for current execution + + def command_value(self, key, command): + #self.output.write('%s=`%s`\n' % (key, command)) + self.output.write(self.indent+'#`%s`\n' % command) + + import shlex, subprocess + args = shlex.split(command) + res=subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, __ = res.communicate() + self.output.write(self.begin+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % (key, out)) + pass + + def add_comment(self, comment): + if comment=="DISTENE license": + self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENSE_FILE', self.changeToCfg('Use global envvar: DLIM8VAR'))) + self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENCE_FILE_FOR_MGCLEANER', self.changeToCfg(''))) + self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENCE_FILE_FOR_YAMS', self.changeToCfg(''))) + return + if "setting environ for" in comment: + self.output.write(self.indent+"#[%s]\n" % comment.split("setting environ for ")[1]) + return + if "PRODUCT environment" in comment: + self.output.write(self.indent+"#[SALOME Configuration]\n\n") + self.output.write(self.indent+"# PRODUCT environment\n") + tmp="," + for i in self.config['PRODUCT']['modules']: tmp+=i+',' + self.output.write(self.indent+"#only for information:\n") + self.output.write(self.indent+'#'+self.setVarEnv+'("SALOME_MODULES", r"%s", overwrite=True)\n\n' % tmp[1:-1]) + try: + #tmp1=self.config['APPLI']['module_appli'] + #tmp2=self.config.TOOLS.common.module_info[tmp1].install_dir + tmp3=self.config.APPLI.module_appli_install_dir + relpath=os.path.relpath("/",os.getenv("HOME")) + tmp=relpath[0:-1]+tmp3 + self.output.write(self.indent+"#only for information: ${APPLI} is preset and have to be relative to $HOME\n") + self.output.write(self.indent+'#'+self.setVarEnv+'("APPLI", r"%s", overwrite=True)\n\n' % tmp) + except: + self.output.write(self.indent+"#only for information: ${APPLI} is by default\n") + return + self.output.write(self.indent+"# %s\n" % comment) + \ No newline at end of file diff --git a/src/options.py b/src/options.py index a6bca2a..79f059e 100644 --- a/src/options.py +++ b/src/options.py @@ -74,7 +74,7 @@ class Options: "long", "list", "list2"] def add_option(self, shortName, longName, - optionType, destName, helpString=""): + optionType, destName, helpString="", default = None): '''Method to add an option to a command. It gets all attributes of an option and append it in the options field @@ -100,7 +100,7 @@ class Options: option['optionType'] = optionType option['destName'] = destName option['helpString'] = helpString - option['result'] = None + option['result'] = default self.options.append(option) def print_help(self):