]> SALOME platform Git repositories - tools/sat.git/commitdiff
Salome HOME
fix AllTestLauncherSat.py and test_*: many errors yet
authorChristian Van Wambeke <christian.van-wambeke@cea.fr>
Fri, 19 Jan 2018 14:03:35 +0000 (15:03 +0100)
committerChristian Van Wambeke <christian.van-wambeke@cea.fr>
Fri, 19 Jan 2018 14:03:35 +0000 (15:03 +0100)
37 files changed:
AllTestLauncherSat.py
commands/__init__.py [new file with mode: 0644]
commands/config.py
commands/job.py
commands/jobs.py
commands/patch.py
commands/source.py
salomeTools.py [deleted file]
sat [changed from symlink to file mode: 0755]
src/__init__.py
src/debug.py
src/i18n/fr/LC_MESSAGES/salomeTools.mo
src/i18n/fr/LC_MESSAGES/salomeTools.po
src/i18n/fr/LC_MESSAGES/salomeTools.po_old [new file with mode: 0644]
src/i18n/test_i18n.py
src/options.py
src/product.py
src/salomeTools.py [new file with mode: 0755]
test/compilation/test_compilation.py
test/compilation/test_make.py
test/compilation/test_makeinstall.py
test/config/test_create_user_pyconf.py
test/config/test_option_copy.py
test/config/test_option_edit.py
test/config/test_option_value.py
test/config/test_option_value_2.py
test/environ/test_environ.py
test/job/test_job.py
test/jobs/test_jobs.py
test/log/test_launch_browser.py
test/log/test_launch_browser2.py
test/prepare/test_clean.py
test/prepare/test_patch.py
test/prepare/test_prepare.py
test/prepare/test_source.py
test/shell/test_shell.py
test/test/test_command.py

index d04f4270dcc18c31dfb32a4551f9e2af7c1e6e42..1a2be076ff9856e33e8144d2c5f4d4de190caa36 100755 (executable)
@@ -65,6 +65,9 @@ import pprint as PP #pretty print
 debug = False
 verboseImport = True
 
+# get path to salomeTools sources
+satdir  = os.path.dirname(os.path.realpath(__file__))
+
 def errPrint(aStr):
   """to avoid write in html or xml file log message"""
   sys.stderr.write(aStr + '\n')
@@ -173,11 +176,12 @@ def runOnArgs(args):
         del sys.path[0]
         done = False
         filesForTest[aFile] = (aImport, aModule)
-    except:
+    except Exception as e:
       if done: 
         del sys.path[0] #attention of sys.path appends
         done = False
-      errPrint("ERROR: AllTestLauncher: import '%s'" % aFile)
+      errPrint("ERROR: AllTestLauncher: import '%s':" % aFile)
+      errPrint("       %s\n" % e)
       continue
 
   listfilesForTest = sorted(filesForTest.keys())
@@ -270,7 +274,7 @@ def getParser():
 dir name with absolute or relative path stand for root directory
 of recursive searching unittest python files
 ''',
-    default='.',
+   default=satdir,
    metavar='dirPath'
   )
   parser.add_argument(
@@ -302,11 +306,15 @@ If name = 'stdout' then all-in-one xml output at 'sys.stdout'. For pipe redirect
 
 ###################################################################
 if __name__ == '__main__':
+  # Make the src & command package accessible from all code
+  sys.path.insert(0, satdir)
+
   args = getParser().parse_args(sys.argv[1:])
   debug = args.debug
   directory = os.path.realpath(args.rootPath)
   if debug: print("INFO: args:\n  %s" % PP.pformat(args))
   sys.path.insert(0, directory) #supposed to be root of a package
+  
   runOnArgs(args)
   del sys.path[0]
 
diff --git a/commands/__init__.py b/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
index 2cab5c59ed7310713a85e5408b7573e9bc982a66..f1ec2b8045b9ce13ba7ae2a1d0ba933dd2436fe1 100644 (file)
@@ -20,15 +20,10 @@ import os
 import platform
 import datetime
 import shutil
-import gettext
 import sys
 
 import src
 
-# internationalization
-satdir  = os.path.dirname(os.path.realpath(__file__))
-gettext.install('salomeTools', os.path.join(satdir, 'src', 'i18n'))
-
 # Define all possible option for config command :  sat config <options>
 parser = src.options.Options()
 parser.add_option('v', 'value', 'string', 'value',
index bb5c88ddeb5406fd48e4409864bba3704c0d2a44..4f6b8919bca05bb043ea23a31d98e23ccc745e73 100644 (file)
@@ -19,7 +19,7 @@
 import os
 
 import src
-import salomeTools
+import src.salomeTools
 
 # Define all possible option for the make command :  sat make <options>
 parser = src.options.Options()
index 7c53d122221e19b2c3d871e7ea03f565f90c55c7..0516243b2da6d2d1dc123ef3ca28afffbe92dba7 100644 (file)
@@ -1852,7 +1852,7 @@ Use the --list option to get the possible files.""") % config_file
         traceback.print_tb(exc_traceback, file=fp)
         fp.seek(0)
         stack = fp.read()
-        logger.write("\nTRACEBACK: %s\n" % stack.replace('"',"'"), 1)
+        logger.write("\nTRACEBACK:\n%s\n" % stack.replace('"',"'"), 1)
         
     finally:
         res = 0
index 3f18442fbaeba836f1634e13c7e10f0971f4bde3..280961fc0ac51d14ca86fd34c09918238d8cb409 100644 (file)
@@ -20,7 +20,7 @@ import os
 import subprocess
 
 import src
-import prepare
+import commands.prepare
 
 # Define all possible option for patch command :  sat patch <options>
 parser = src.options.Options()
index 448774d2851e6daba0c046e99963397df05a1a7a..973cfd1864aa245b3a4be6220209ea7990bc2577 100644 (file)
@@ -20,7 +20,7 @@ import os
 import shutil
 
 import src
-import prepare
+import commands.prepare
 
 # Define all possible option for patch command :  sat patch <options>
 parser = src.options.Options()
@@ -503,7 +503,7 @@ def run(args, runner, logger):
     logger.write("\n", 2, False)
        
     # Get the products list with products informations regarding the options
-    products_infos = prepare.get_products_list(options, runner.cfg, logger)
+    products_infos = commands.prepare.get_products_list(options, runner.cfg, logger)
     
     # Call to the function that gets all the sources
     good_result, results = get_all_product_sources(runner.cfg, 
diff --git a/salomeTools.py b/salomeTools.py
deleted file mode 100755 (executable)
index 219cc5c..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-#!/usr/bin/env python
-#-*- coding:utf-8 -*-
-#  Copyright (C) 2010-2012  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
-'''This file is the main entry file to salomeTools
-'''
-
-# python imports
-import os
-import sys
-import re
-import tempfile
-import imp
-import types
-import gettext
-import traceback
-
-# salomeTools imports
-import src
-
-# get path to salomeTools sources
-satdir  = os.path.dirname(os.path.realpath(__file__))
-cmdsdir = os.path.join(satdir, 'commands')
-
-# Make the src package accessible from all code
-sys.path.append(satdir)
-sys.path.append(cmdsdir)
-
-import config
-import src.debug as DBG
-
-# load resources for internationalization
-#es = gettext.translation('salomeTools', os.path.join(satdir, 'src', 'i18n'))
-#es.install()
-gettext.install('salomeTools', os.path.join(satdir, 'src', 'i18n'))
-
-# The possible hooks : 
-# pre is for hooks to be executed before commands
-# post is for hooks to be executed after commands
-C_PRE_HOOK = "pre"
-C_POST_HOOK = "post"
-
-def find_command_list(dirPath):
-    ''' Parse files in dirPath that end with .py : it gives commands list
-    
-    :param dirPath str: The directory path where to search the commands
-    :return: cmd_list : the list containing the commands name 
-    :rtype: list
-    '''
-    cmd_list = []
-    for item in os.listdir(dirPath):
-        if item.endswith('.py'):
-            cmd_list.append(item[:-len('.py')])
-    return cmd_list
-
-# The list of valid salomeTools commands
-#lCommand = ['config', 'compile', 'prepare']
-lCommand = find_command_list(cmdsdir)
-
-# Define all possible option for salomeTools command :  sat <option> <args>
-parser = src.options.Options()
-parser.add_option('h', 'help', 'boolean', 'help', 
-                  _("shows global help or help on a specific command."))
-parser.add_option('o', 'overwrite', 'list', "overwrite", 
-                  _("overwrites a configuration parameters."))
-parser.add_option('g', 'debug', 'boolean', 'debug_mode', 
-                  _("run salomeTools in debug mode."))
-parser.add_option('v', 'verbose', 'int', "output_verbose_level", 
-                  _("change output verbose level (default is 3)."))
-parser.add_option('b', 'batch', 'boolean', "batch", 
-                  _("batch mode (no question)."))
-parser.add_option('t', 'all_in_terminal', 'boolean', "all_in_terminal", 
-                  _("all traces in the terminal (for example compilation logs)."))
-parser.add_option('l', 'logs_paths_in_file', 'string', "logs_paths_in_file", 
-                  _("put the command result and paths to log files."))
-
-class Sat(object):
-    '''The main class that stores all the commands of salomeTools
-    '''
-    def __init__(self, opt='', datadir=None):
-        '''Initialization
-        
-        :param opt str: The sat options 
-        :param: datadir str : the directory that contain all the external 
-                              data (like software pyconf and software scripts)
-        '''
-        # Read the salomeTools options (the list of possible options is 
-        # at the beginning of this file)
-        try:
-            (options, argus) = parser.parse_args(opt)
-        except Exception as exc:
-            write_exception(exc)
-            sys.exit(-1)
-
-        # initialization of class attributes       
-        self.__dict__ = dict()
-        self.cfg = None # the config that will be read using pyconf module
-        self.arguments = opt
-        self.options = options # the options passed to salomeTools
-        self.datadir = datadir # default value will be <salomeTools root>/data
-        # set the commands by calling the dedicated function
-        self._setCommands(cmdsdir)
-        
-        # if the help option has been called, print help and exit
-        if options.help:
-            try:
-                self.print_help(argus)
-                sys.exit(0)
-            except Exception as exc:
-                write_exception(exc)
-                sys.exit(1)
-
-    def __getattr__(self, name):
-        ''' overwrite of __getattr__ function in order to display 
-            a customized message in case of a wrong call
-        
-        :param name str: The name of the attribute 
-        '''
-        if name in self.__dict__:
-            return self.__dict__[name]
-        else:
-            raise AttributeError(name + _(" is not a valid command"))
-    
-    def _setCommands(self, dirPath):
-        '''set class attributes corresponding to all commands that are 
-           in the dirPath directory
-        
-        :param dirPath str: The directory path containing the commands 
-        '''
-        # loop on the commands name
-        for nameCmd in lCommand:
-            
-            # Exception for the jobs command that requires the paramiko module
-            if nameCmd == "jobs":
-                try:
-                    saveout = sys.stderr
-                    ff = tempfile.TemporaryFile()
-                    sys.stderr = ff
-                    import paramiko
-                    sys.stderr = saveout
-                except:
-                    sys.stderr = saveout
-                    continue
-
-            # load the module that has name nameCmd in dirPath
-            (file_, pathname, description) = imp.find_module(nameCmd, [dirPath])
-            module = imp.load_module(nameCmd, file_, pathname, description)
-            
-            def run_command(args='',
-                            options=None,
-                            batch = False,
-                            verbose = -1,
-                            logger_add_link = None):
-                '''The function that will load the configuration (all pyconf)
-                and return the function run of the command corresponding to module
-                
-                :param args str: The arguments of the command 
-                '''
-                # Make sure the internationalization is available
-                gettext.install('salomeTools', os.path.join(satdir, 'src', 'i18n'))
-                
-                # Get the arguments in a list and remove the empty elements
-                if type(args) == type(''):
-                    # split by spaces without considering spaces in quotes
-                    argv_0 = re.findall(r'(?:"[^"]*"|[^\s"])+', args)
-                else:
-                    argv_0 = args
-                
-                if argv_0 != ['']:
-                    while "" in argv_0: argv_0.remove("")
-                
-                # Format the argv list in order to prevent strings 
-                # that contain a blank to be separated
-                argv = []
-                elem_old = ""
-                for elem in argv_0:
-                    if argv == [] or elem_old.startswith("-") or elem.startswith("-"):
-                        argv.append(elem)
-                    else:
-                        argv[-1] += " " + elem
-                    elem_old = elem
-                           
-                # if it is provided by the command line, get the application
-                appliToLoad = None
-                if argv not in [[''], []] and argv[0][0] != "-":
-                    appliToLoad = argv[0].rstrip('*')
-                    argv = argv[1:]
-                
-                # Check if the global options of salomeTools have to be changed
-                if options:
-                    options_save = self.options
-                    self.options = options  
-
-                # read the configuration from all the pyconf files    
-                cfgManager = config.ConfigManager()
-                self.cfg = cfgManager.get_config(datadir=self.datadir, 
-                                                 application=appliToLoad, 
-                                                 options=self.options, 
-                                                 command=__nameCmd__)
-                               
-                # Set the verbose mode if called
-                if verbose > -1:
-                    verbose_save = self.options.output_verbose_level
-                    self.options.__setattr__("output_verbose_level", verbose)    
-
-                # Set batch mode if called
-                if batch:
-                    batch_save = self.options.batch
-                    self.options.__setattr__("batch", True)
-
-                # set output level
-                if self.options.output_verbose_level is not None:
-                    self.cfg.USER.output_verbose_level = self.options.output_verbose_level
-                if self.cfg.USER.output_verbose_level < 1:
-                    self.cfg.USER.output_verbose_level = 0
-                silent = (self.cfg.USER.output_verbose_level == 0)
-
-                # create log file
-                micro_command = False
-                if logger_add_link:
-                    micro_command = True
-                logger_command = src.logger.Logger(self.cfg, 
-                                   silent_sysstd=silent,
-                                   all_in_terminal=self.options.all_in_terminal,
-                                   micro_command=micro_command)
-                
-                # Check that the path given by the logs_paths_in_file option
-                # is a file path that can be written
-                if self.options.logs_paths_in_file and not micro_command:
-                    try:
-                        self.options.logs_paths_in_file = os.path.abspath(
-                                                self.options.logs_paths_in_file)
-                        dir_file = os.path.dirname(self.options.logs_paths_in_file)
-                        if not os.path.exists(dir_file):
-                            os.makedirs(dir_file)
-                        if os.path.exists(self.options.logs_paths_in_file):
-                            os.remove(self.options.logs_paths_in_file)
-                        file_test = open(self.options.logs_paths_in_file, "w")
-                        file_test.close()
-                    except Exception as e:
-                        msg = _("WARNING: the logs_paths_in_file option will "
-                                "not be taken into account.\nHere is the error:")
-                        logger_command.write("%s\n%s\n\n" % (
-                                             src.printcolors.printcWarning(msg),
-                                             str(e)))
-                        self.options.logs_paths_in_file = None
-                
-                options_launched = ""
-                res = None
-                try:
-                    # Execute the hooks (if there is any) 
-                    # and run method of the command
-                    self.run_hook(__nameCmd__, C_PRE_HOOK, logger_command)
-                    res = __module__.run(argv, self, logger_command)
-                    self.run_hook(__nameCmd__, C_POST_HOOK, logger_command)
-                    if res is None:
-                        res = 0
-                        
-                except Exception as e:
-                    # Get error
-                    logger_command.write("\n***** ", 1)
-                    logger_command.write(src.printcolors.printcError(
-                                                       "salomeTools ERROR:"), 1)
-                    logger_command.write("\n" + str(e) + "\n\n", 1)
-                    # get stack
-                    __, __, exc_traceback = sys.exc_info()
-                    fp = tempfile.TemporaryFile()
-                    traceback.print_tb(exc_traceback, file=fp)
-                    fp.seek(0)
-                    stack = fp.read()
-                    verbosity = 5
-                    if self.options.debug_mode:
-                        verbosity = 1
-                    logger_command.write("TRACEBACK: %s" % stack.replace('"',"'"),
-                                         verbosity)
-                finally:
-                    # set res if it is not set in the command
-                    if res is None:
-                        res = 1
-                                            
-                    # come back to the original global options
-                    if options:
-                        options_launched = get_text_from_options(self.options)
-                        self.options = options_save
-                    
-                    # come back in the original batch mode if 
-                    # batch argument was called
-                    if batch:
-                        self.options.__setattr__("batch", batch_save)
-
-                    # come back in the original verbose mode if 
-                    # verbose argument was called                        
-                    if verbose > -1:
-                        self.options.__setattr__("output_verbose_level", 
-                                                 verbose_save)
-                    # put final attributes in xml log file 
-                    # (end time, total time, ...) and write it
-                    launchedCommand = ' '.join([self.cfg.VARS.salometoolsway +
-                                                os.path.sep +
-                                                'sat',
-                                                options_launched,
-                                                __nameCmd__, 
-                                                ' '.join(argv_0)])
-                    launchedCommand = launchedCommand.replace('"', "'")
-                    
-                    # Add a link to the parent command      
-                    if logger_add_link is not None:
-                        logger_add_link.add_link(logger_command.logFileName,
-                                                 __nameCmd__,
-                                                 res,
-                                                 launchedCommand)
-                        logger_add_link.l_logFiles += logger_command.l_logFiles
-                                            
-                    # Put the final attributes corresponding to end time and
-                    # Write the file to the hard drive
-                    logger_command.end_write(
-                                        {"launchedCommand" : launchedCommand})
-                    
-                    if res != 0:
-                        res = 1
-                        
-                    # print the log file path if 
-                    # the maximum verbose mode is invoked
-                    if not micro_command:
-                        logger_command.write("\nPath to the xml log file:\n",
-                                             5)
-                        logger_command.write("%s\n\n" % src.printcolors.printcInfo(
-                                                logger_command.logFilePath), 5)
-
-                    # If the logs_paths_in_file was called, write the result
-                    # and log files in the given file path
-                    if self.options.logs_paths_in_file and not micro_command:
-                        file_res = open(self.options.logs_paths_in_file, "w")
-                        file_res.write(str(res) + "\n")
-                        for i, filepath in enumerate(logger_command.l_logFiles):
-                            file_res.write(filepath)
-                            if i < len(logger_command.l_logFiles):
-                                file_res.write("\n")
-                                file_res.flush()
-                
-                return res
-
-            # Make sure that run_command will be redefined 
-            # at each iteration of the loop
-            globals_up = {}
-            globals_up.update(run_command.__globals__)
-            globals_up.update({'__nameCmd__': nameCmd, '__module__' : module})
-            func = types.FunctionType(run_command.__code__,
-                                      globals_up,
-                                      run_command.__name__,
-                                      run_command.__defaults__,
-                                      run_command.__closure__)
-
-            # set the attribute corresponding to the command
-            self.__setattr__(nameCmd, func)
-
-    def run_hook(self, cmd_name, hook_type, logger):
-        '''Execute a hook file for a given command regarding the fact 
-           it is pre or post
-        
-        :param cmd_name str: The the command on which execute the hook
-        :param hook_type str: pre or post
-        :param logger Logger: the logging instance to use for the prints
-        '''
-        # The hooks must be defined in the application pyconf
-        # So, if there is no application, do not do anything
-        if not src.config_has_application(self.cfg):
-            return
-
-        # The hooks must be defined in the application pyconf in the
-        # APPLICATION section, hook : { command : 'script_path.py'}
-        if "hook" not in self.cfg.APPLICATION \
-                    or cmd_name not in self.cfg.APPLICATION.hook:
-            return
-
-        # Get the hook_script path and verify that it exists
-        hook_script_path = self.cfg.APPLICATION.hook[cmd_name]
-        if not os.path.exists(hook_script_path):
-            raise src.SatException(_("Hook script not found: %s") % 
-                                   hook_script_path)
-        
-        # Try to execute the script, catch the exception if it fails
-        try:
-            # import the module (in the sense of python)
-            pymodule = imp.load_source(cmd_name, hook_script_path)
-            
-            # format a message to be printed at hook execution
-            msg = src.printcolors.printcWarning(_("Run hook script"))
-            msg = "%s: %s\n" % (msg, 
-                                src.printcolors.printcInfo(hook_script_path))
-            
-            # run the function run_pre_hook if this function is called 
-            # before the command, run_post_hook if it is called after
-            if hook_type == C_PRE_HOOK and "run_pre_hook" in dir(pymodule):
-                logger.write(msg, 1)
-                pymodule.run_pre_hook(self.cfg, logger)
-            elif hook_type == C_POST_HOOK and "run_post_hook" in dir(pymodule):
-                logger.write(msg, 1)
-                pymodule.run_post_hook(self.cfg, logger)
-
-        except Exception as exc:
-            msg = _("Unable to run hook script: %s") % hook_script_path
-            msg += "\n" + str(exc)
-            raise src.SatException(msg)
-
-    def print_help(self, opt):
-        '''Prints help for a command. Function called when "sat -h <command>"
-        
-        :param argv str: the options passed (to get the command name)
-        '''
-        # if no command as argument (sat -h)
-        if len(opt)==0:
-            print_help()
-            return
-        # get command name
-        command = opt[0]
-        # read the configuration from all the pyconf files
-        cfgManager = config.ConfigManager()
-        self.cfg = cfgManager.get_config(datadir=self.datadir)
-
-        # Check if this command exists
-        if not hasattr(self, command):
-            raise src.SatException(_("Command '%s' does not exist") % command)
-        
-        # Print salomeTools version
-        print_version()
-        
-        # load the module
-        module = self.get_module(command)
-
-        # print the description of the command that is done in the command file
-        if hasattr( module, "description" ) :
-            print(src.printcolors.printcHeader( _("Description:") ))
-            print(module.description() + '\n')
-
-        # print the description of the command options
-        if hasattr( module, "parser" ) :
-            module.parser.print_help()
-
-    def get_module(self, module):
-        '''Loads a command. Function called only by print_help
-        
-        :param module str: the command to load
-        '''
-        # Check if this command exists
-        if not hasattr(self, module):
-            raise src.SatException(_("Command '%s' does not exist") % module)
-
-        # load the module
-        (file_, pathname, description) = imp.find_module(module, [cmdsdir])
-        module = imp.load_module(module, file_, pathname, description)
-        return module
-
-def get_text_from_options(options):
-    text_options = ""
-    for attr in dir(options):
-        if attr.startswith("__"):
-            continue
-        if options.__getattr__(attr) != None:
-            option_contain = options.__getattr__(attr)
-            if type(option_contain)==type([]):
-                option_contain = ",".join(option_contain)
-            if type(option_contain)==type(True):
-                option_contain = ""
-            text_options+= "--%s %s " % (attr, option_contain)
-    return text_options
-                
-
-def print_version():
-    '''prints salomeTools version (in src/internal_config/salomeTools.pyconf)
-    '''
-    # read the config 
-    cfgManager = config.ConfigManager()
-    cfg = cfgManager.get_config()
-    # print the key corresponding to salomeTools version
-    print(src.printcolors.printcHeader( _("Version: ") ) + 
-          cfg.INTERNAL.sat_version + '\n')
-
-
-def print_help():
-    '''prints salomeTools general help
-    
-    :param options str: the options
-    '''
-    print_version()
-    
-    print(src.printcolors.printcHeader( _("Usage: ") ) + 
-          "sat [sat_options] <command> [product] [command_options]\n")
-
-    parser.print_help()
-
-    # display all the available commands.
-    print(src.printcolors.printcHeader(_("Available commands are:\n")))
-    for command in lCommand:
-        print(" - %s" % (command))
-        
-    # Explain how to get the help for a specific command
-    print(src.printcolors.printcHeader(_("\nGetting the help for a specific"
-                                    " command: ")) + "sat --help <command>\n")
-
-def write_exception(exc):
-    '''write exception in case of error in a command
-    
-    :param exc exception: the exception to print
-    '''
-    sys.stderr.write("\n***** ")
-    sys.stderr.write(src.printcolors.printcError("salomeTools ERROR:"))
-    sys.stderr.write("\n" + str(exc) + "\n")
-
-
-# ###############################
-# MAIN : terminal command usage #
-# ###############################
-if __name__ == "__main__":  
-    # Initialize the code that will be returned by the terminal command 
-    code = 0
-    (options, args) = parser.parse_args(sys.argv[1:])
-    DBG.push_debug(True)
-    DBG.write("options", options)    
-    DBG.write("args", args)    
-
-    # no arguments : print general help
-    if len(args) == 0:
-        print_help()
-        sys.exit(0)
-    
-    # instantiate the salomeTools class with correct options
-    sat = Sat(sys.argv[1:])
-    # the command called
-    command = args[0]
-    DBG.write("command", command)
-    # get dynamically the command function to call
-    fun_command = sat.__getattr__(command)
-    DBG.write("fun_command", fun_command)
-    # Run the command using the arguments
-    code = fun_command(args[1:])
-    DBG.write("code", code)
-
-    # exit salomeTools with the right code (0 if no errors, else 1)
-    if code is None: code = 0
-    sys.exit(code)
-        
diff --git a/sat b/sat
deleted file mode 120000 (symlink)
index 19cd1ab237a6dee557b56423fd42d2beb877d616..0000000000000000000000000000000000000000
--- a/sat
+++ /dev/null
@@ -1 +0,0 @@
-salomeTools.py
\ No newline at end of file
diff --git a/sat b/sat
new file mode 100755 (executable)
index 0000000000000000000000000000000000000000..ae3cb05530831dd543cc41d07808980817d9f2b0
--- /dev/null
+++ b/sat
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+#  Copyright (C) 2010-2018  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
+
+'''This file is the main entry file to use salomeTools
+'''
+
+import os
+import sys
+
+# get path to salomeTools sources
+satdir  = os.path.dirname(os.path.realpath(__file__))
+
+# Make the src & commands package accessible from all code
+sys.path.insert(0, satdir)
+
+
+#################################
+# MAIN
+#################################
+if __name__ == "__main__":
+    import src
+    from src.salomeTools import Sat
+    import src.debug as DBG # Easy print stderr (for DEBUG only)
+
+    _debug = False          # Have to be False in production (for DEBUG only)
+    DBG.push_debug(_debug)
+
+    # instantiate the salomeTools class with correct options
+    sat = Sat(sys.argv[1:])
+    exitCode = sat.execute_command()
+    DBG.write("sat exit code", src.okToStr(exitCode))
+
+    sys.exit(exitCode)
+        
index 9d28e100db7cfd75cc638b16ff9edfaf2bc5919f..5fc438b8a49ba9dcf88221dae284fec60cb4a4c6 100644 (file)
@@ -48,6 +48,16 @@ TIMEOUT_STATUS = "TIMEOUT"
 
 CONFIG_FILENAME = "sat-config.pyconf"
 
+OKSYS = 0  # OKSYS and KOSYS seems equal on linux or windows
+KOSYS = 1
+OKMESS = {0: "OK", 1: "KO"} # etc... if useful
+   
+def okToStr(ok): 
+    try:
+        return OKMESS[ok]
+    except:
+        return "UnknownExitCode"
+
 class SatException(Exception):
     '''rename Exception Class
     '''
index 3d2f0ac848145d7ca5780c04c7abc055afddfa62..8ea680c3de4395af6c77218c22764dec9772ec68 100644 (file)
@@ -24,10 +24,11 @@ warning: only for SAT development phase
 import sys
 import pprint as PP
 
-_debug = [True] #support push/pop for temporary active outputs
+_debug = [False] #support push/pop for temporary active outputs
 
-def write(title, var=""):
-    if _debug[-1]: 
+def write(title, var="", force=None):
+    """write sys.stderr a message if _debug[-1]==True or optionaly force=True"""
+    if _debug[-1] or force: 
         sys.stderr.write("\n#### DEBUG: %s:\n%s\n" % (title, PP.pformat(var)))   
     return
 
index f62038e7e82d0e333e0e6343be0798f27f7cbf2f..85710c2d9e75c93deb986af4f5cd6a1354fdf82c 100644 (file)
Binary files a/src/i18n/fr/LC_MESSAGES/salomeTools.mo and b/src/i18n/fr/LC_MESSAGES/salomeTools.mo differ
index 6119d55358af9d1a033a0d9000c290eada73dca5..1101bdfcb62c19aa4db41c968b5ec05102472d1a 100644 (file)
@@ -13,9 +13,18 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#, python-format
-msgid "Georges says '%(1)s' for %(2)s."
-msgstr "pour %(2)s Hervé dit '%(1)s'."
+# for test_i18n.py
+msgid "Harvey writes '%(1)s' for %(2)s."
+msgstr "pour %(2)s Hervé écrit '%(1)s'."
+
+# for test_i18n.py
+msgid "hello"
+msgstr "bonjour"
+
+# for test_i18n.py
+# keep Ooops inexisting in salomeTools.po as not translated
+# msgid "Ooops"
+# msgstr "NOT TRANSLATED"
 
 msgid "shows global help or help on a specific command."
 msgstr "affiche l'aide générale ou pour une commande spécifique."
diff --git a/src/i18n/fr/LC_MESSAGES/salomeTools.po_old b/src/i18n/fr/LC_MESSAGES/salomeTools.po_old
new file mode 100644 (file)
index 0000000..1101bdf
--- /dev/null
@@ -0,0 +1,91 @@
+# stuff to fix removed french accentued characters on msgmerge 
+msgid ""
+msgstr ""
+"Project-Id-Version: sat5\n"
+"Report-Msgid-Bugs-To: andrea@nonymous.net \n"
+"POT-Creation-Date: 2016-01-25 18:51+0100\n"
+"PO-Revision-Date: 2016-01-25 19:53+0100\n"
+"Last-Translator: Andrea Nonymous <andrea@nonymous.net>\n"
+"Language-Team: French\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+# for test_i18n.py
+msgid "Harvey writes '%(1)s' for %(2)s."
+msgstr "pour %(2)s Hervé écrit '%(1)s'."
+
+# for test_i18n.py
+msgid "hello"
+msgstr "bonjour"
+
+# for test_i18n.py
+# keep Ooops inexisting in salomeTools.po as not translated
+# msgid "Ooops"
+# msgstr "NOT TRANSLATED"
+
+msgid "shows global help or help on a specific command."
+msgstr "affiche l'aide générale ou pour une commande spécifique."
+
+msgid "overwrites a configuration parameters."
+msgstr "écrase un parametre de configuration."
+
+msgid "run salomeTools in debug mode."
+msgstr "lance salomeTools en mode debug."
+
+msgid "change output verbose level (default is 3)."
+msgstr "change niveau de verbosité (defaut: 3)."
+
+msgid "batch mode (no question)."
+msgstr "mode batch (pas de question)."
+
+msgid "all traces in the terminal (for example compilation logs)."
+msgstr "toutes traces dans le terminal (par exemple: log de compilation)"
+
+msgid "put the command result and paths to log files."
+msgstr "redirige resultats de commandes vers log files"
+
+msgid " is not a valid command"
+msgstr " n'est pas une commande valide"
+
+msgid ""
+"WARNING: the logs_paths_in_file option will not be taken into account.\n"
+"Here is the error:"
+msgstr ""
+
+msgid "Usage: "
+msgstr "Utilisation : "
+
+msgid "Available commands are:\n"
+msgstr "Les commandes disponibles sont:\n"
+
+msgid ""
+"\n"
+"Getting the help for a specific command: "
+msgstr ""
+"\n"
+"Obtenir l'aide d'une commande spécifique : "
+
+msgid "lsb_release not installed\n"
+msgstr "lsb_release n'est pas installé\n"
+
+msgid "You can define $LSB_PATH to give the path to lsb_release\n"
+msgstr "Vous pouvez définir $LSB_PATH pour donner le chemin vers lsb_release\n"
+
+#, python-format
+msgid "Unknown distribution: '%s'\n"
+msgstr "Distribution inconnue : '%s'\n"
+
+msgid "Please add your distribution to src/internal_config/distrib.pyconf\n"
+msgstr ""
+"SVP ajoutez votre distribution au fichier src/internal_config/distrib."
+"pyconf\n"
+
+msgid " is not a valid option"
+msgstr " n'est pas une option valide"
+
+msgid "Available options are:"
+msgstr "Les options disponibles sont:"
+
index a9af31be084c95d6aad75a450583ecb94b283110..cf467dac8e81bdc3d405a68928546591285b33df 100755 (executable)
@@ -28,13 +28,26 @@ import unittest
 verbose = False
 
 class TestCase(unittest.TestCase):
+  
+  def test_001(self):
+    # first load resources for internationalization
+    gettext.install('salomeTools', os.path.realpath(os.path.dirname(__file__)))
  
   def test_005(self):
-    # load resources for internationalization
-    gettext.install('salomeTools', os.path.realpath(os.path.dirname(__file__))) 
-    res = _("Georges says '%(1)s' for %(2)s.") % {"1": "hello", "2": "test"}
+    res = _("Harvey writes '%(1)s' for %(2)s.") % {"1": "hello", "2": "test_005"}
     if verbose: print(res)
-    self.assertEqual(res, "pour test Hervé dit 'hello'.")
+    self.assertEqual(res, "pour test_005 Hervé écrit 'hello'.")
+
+  def test_010(self):
+    res = _("Harvey writes '%(1)s' for %(2)s.") % {"1": _("hello"), "2": "test_010"}
+    if verbose: print(res)
+    self.assertEqual(res, "pour test_010 Hervé écrit 'bonjour'.")
+
+  def test_020(self):
+    # keep Ooops inexisting in salomeTools.po as no translation
+    res = _("Harvey writes '%(1)s' for %(2)s.") % {"1": _("Ooops"), "2": "test_020"}
+    if verbose: print(res)
+    self.assertEqual(res, "pour test_020 Hervé écrit 'Ooops'.")
 
 if __name__ == '__main__':
   verbose = False
index c152345a954481467d02c81073d73da00004fa67..22c51f93fff74abd27b4599edb546ffb1a37c65b 100644 (file)
@@ -22,7 +22,9 @@ import getopt
 import sys
 import pprint as PP
 
-from . import printcolors
+import src
+import src.debug as DBG # Easy print stderr (for DEBUG only)
+import src.printcolors
 
 class OptResult(object):
     '''An instance of this class will be the object manipulated
@@ -63,10 +65,11 @@ class OptResult(object):
         object.__setattr__(self, name, value)
 
     def __repr__(self):
-        res = "%s(%s)" % (self.__class__.__name__, PP.pformat(self.__dict__))
+        aStr = PP.pformat(self.__dict__)
+        res = "%s(\n %s)" % (self.__class__.__name__, aStr[1:-1])
         return res
 
-class Options:
+class Options(object):
     '''Class to manage all salomeTools options
     '''
     def __init__(self):
@@ -76,9 +79,9 @@ class Options:
         # in a list that contains dicts
         self.options = []
         # The list of available option type
-        self.availableOptions = ["boolean", "string", "int", "float",
-                                  "long", "list", "list2"]
+        self.availableOptions = "boolean string int float long list list2".split()
         self.default = None
+        self.results = {}
 
     def add_option(self, shortName, longName,
                     optionType, destName, helpString="", default = None):
@@ -102,7 +105,7 @@ class Options:
 
         if optionType not in self.availableOptions:
             print("error optionType", optionType, "not available.")
-            sys.exit(-1)
+            sys.exit(src.KOSYS)
 
         option['optionType'] = optionType
         option['destName'] = destName
@@ -122,7 +125,7 @@ class Options:
 
         # for all options, print its values. 
         # "shortname" is an optional field of the options 
-        print(printcolors.printcHeader(_("Available options are:")))
+        print(src.printcolors.printcHeader(_("Available options are:")))
         for option in self.options:
             if 'shortName' in option and len(option['shortName']) > 0:
                 print(" -%(shortName)1s, --%(longName)s"
@@ -144,6 +147,8 @@ class Options:
         if argList is None:
             argList = sys.argv[1:]
         
+        DBG.write("parse_args", argList)
+        DBG.write("options", self.options)
         # format shortNameOption and longNameOption 
         # to make right arguments to getopt.getopt function
         shortNameOption = ""
@@ -161,7 +166,10 @@ class Options:
 
         # call to getopt.getopt function to get the option 
         # passed in the command regarding the available options
-        optlist, args = getopt.getopt(argList, shortNameOption, longNameOption)
+        try:
+          optlist, args = getopt.getopt(argList, shortNameOption, longNameOption)
+        except:
+          DBG.write("ERROR", (shortNameOption, longNameOption), True)
         
         # instantiate and completing the optResult that will be returned
         optResult = OptResult()
@@ -198,5 +206,20 @@ class Options:
             # free the option in order to be able to make 
             # a new free call of options (API case)
             option['result'] = None
+
+        self.results = {"optlist": optlist, "optResult": optResult, "args": args, "argList": argList}
+        DBG.write("options and results", self)
         return optResult, args
 
+    def __repr__(self): 
+        '''repr for only self.options and self.results (if present)
+        '''
+        aDict = {'options': self.options, 'results': self.results}
+        aStr = PP.pformat(aDict)
+        res = "%s(\n %s)" % (self.__class__.__name__, aStr[1:-1])
+        return res
+        
+    def debug_write(self):
+        DBG.write("options and results", self, True)
+
+
index 3e9721b20e295b9a3c32339b750486e51df2edae..ea886a085af14fdd2bba98313edaa5a1051ef56a 100644 (file)
@@ -147,7 +147,10 @@ def get_product_config(config, product_name, with_install_dir=True):
         if not prod_pyconf_path:
             msg = _("""\
 No definition found for the product %(1)s.
-Please create a %(2)s.pyconf file.""") % {"1": product_name, "2": product_name}
+Please create a %(2)s.pyconf file somewhere in:\n%(3)s""") % {
+  "1": product_name, 
+  "2": product_name,
+  "3": config.PATHS.PRODUCTPATH }
         else:
             msg = _("""\
 No definition corresponding to the version %(1)s was found in the file:
diff --git a/src/salomeTools.py b/src/salomeTools.py
new file mode 100755 (executable)
index 0000000..f5ca674
--- /dev/null
@@ -0,0 +1,566 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+#  Copyright (C) 2010-2018  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
+
+'''This file is the main entry file to salomeTools
+'''
+
+import os
+import sys
+import re
+import tempfile
+import imp
+import types
+import gettext
+import traceback
+
+
+#################################
+# NOT MAIN allowed
+#################################
+if __name__ == "__main__":
+    sys.stderr.write("\nERROR: 'salomeTools.py' is not main command entry for sat: use 'sat' instead.\n\n")
+    KOSYS = 1 # avoid import src
+    sys.exit(KOSYS)
+
+
+import src.debug as DBG # Easy print stderr (for DEBUG only)
+
+# get path to src
+rootdir = os.path.realpath( os.path.join(os.path.dirname(__file__), "..") )
+DBG.write("sat rootdir", rootdir)  
+srcdir = os.path.join(rootdir, "src")
+cmdsdir = os.path.join(rootdir, "commands")
+
+# load resources for internationalization
+# DBG.write("TODO", "fix xxsalomeTools to avoid french", True)  
+gettext.install('salomeTools', os.path.join(srcdir, 'i18n'))
+
+# salomeTools imports
+import src
+import commands.config
+
+# The possible hooks : 
+# pre is for hooks to be executed before commands
+# post is for hooks to be executed after commands
+C_PRE_HOOK = "pre"
+C_POST_HOOK = "post"
+
+
+def find_command_list(dirPath):
+    '''Parse files in dirPath that end with .py : it gives commands list
+    
+    :param dirPath str: The directory path where to search the commands
+    :return: cmd_list : the list containing the commands name 
+    :rtype: list
+    '''
+    cmd_list = []
+    for item in os.listdir(dirPath):
+        if item in ["__init__.py"]: #avoid theses files
+            continue
+        if item.endswith('.py'):
+            cmd_list.append(item[:-len('.py')])
+    return cmd_list
+
+# The list of valid salomeTools commands
+#lCommand = ['config', 'compile', 'prepare',...]
+lCommand = find_command_list(cmdsdir)
+
+def getCommandsList():
+    """Gives commands list (as basename of files commands/*.py)
+    """ 
+    return lCommand
+
+# Define all possible option for salomeTools command :  sat <options> <args>
+parser = src.options.Options()
+parser.add_option('h', 'help', 'boolean', 'help', 
+                  _("shows global help or help on a specific command."))
+parser.add_option('o', 'overwrite', 'list', "overwrite", 
+                  _("overwrites a configuration parameters."))
+parser.add_option('g', 'debug', 'boolean', 'debug_mode', 
+                  _("run salomeTools in debug mode."))
+parser.add_option('v', 'verbose', 'int', "output_verbose_level", 
+                  _("change output verbose level (default is 3)."))
+parser.add_option('b', 'batch', 'boolean', "batch", 
+                  _("batch mode (no question)."))
+parser.add_option('t', 'all_in_terminal', 'boolean', "all_in_terminal", 
+                  _("all traces in the terminal (for example compilation logs)."))
+parser.add_option('l', 'logs_paths_in_file', 'string', "logs_paths_in_file", 
+                  _("put the command result and paths to log files."))
+
+class Sat(object):
+    '''The main class that stores all the commands of salomeTools
+    '''
+    def __init__(self, opt='', datadir=None):
+        '''Initialization
+        
+        :param opt str: The sat options 
+        :param: datadir str : the directory that contain all the external 
+                              data (like software pyconf and software scripts)
+        '''
+        # Read the salomeTools prefixes options before the 'commands' tag
+        # sat <options> <args>
+        # (the list of possible options is  at the beginning of this file)
+        try:
+            options, args = parser.parse_args(opt)
+            DBG.write("Sat args", args)
+            DBG.write("Sat options", options)    
+        except Exception as exc:
+            write_exception(exc)
+            sys.exit(src.KOSYS)
+
+        # initialization of class attributes       
+        self.__dict__ = dict()
+        self.cfg = None # the config that will be read using pyconf module
+        self.arguments = args # args are postfixes options: args[0] is the 'commands' command
+        self.options = options # the options passed to salomeTools
+        self.datadir = datadir # default value will be <salomeTools root>/data
+        # set the commands by calling the dedicated function
+        self._setCommands(cmdsdir)
+        
+        # if the help option has been called, print help and exit
+        if options.help:
+            try:
+                self.print_help(args)
+                sys.exit(src.OKSYS)
+            except Exception as exc:
+                write_exception(exc)
+                DBG.write("args", args, True) 
+                sys.exit(src.KOSYS)
+
+    def __getattr__(self, name):
+        '''overwrite of __getattr__ function in order to display 
+           a customized message in case of a wrong call
+        
+        :param name str: The name of the attribute 
+        '''
+        if name in self.__dict__:
+            return self.__dict__[name]
+        else:
+            raise AttributeError(name + _(" is not a valid command"))
+
+    def execute_command(self, opt=None):
+        """select first argument as a command in directory 'commands', and launch on arguments
+        
+        :param opt str, optionnal: The sat options (as sys.argv)
+        """
+        if opt is not None:
+            args = opt
+        else:
+            args = self.arguments 
+
+        if len(args) == 0:
+            print_help()
+            return src.OKSYS
+       
+        # the command called
+        command = args[0]
+        # get dynamically the command function to call
+        fun_command = self.__getattr__(command)
+        # Run the command using the arguments
+        exitCode = fun_command(args[1:])
+        return exitCode 
+    
+    def _setCommands(self, dirPath):
+        '''set class attributes corresponding to all commands that are 
+           in the dirPath directory
+        
+        :param dirPath str: The directory path containing the commands 
+        '''
+        # loop on the commands name
+        for nameCmd in lCommand:
+            
+            # Exception for the jobs command that requires the paramiko module
+            if nameCmd == "jobs":
+                try:
+                    saveout = sys.stderr
+                    ff = tempfile.TemporaryFile()
+                    sys.stderr = ff
+                    import paramiko
+                    sys.stderr = saveout
+                except:
+                    sys.stderr = saveout
+                    continue
+
+            # load the module that has name nameCmd in dirPath
+            (file_, pathname, description) = imp.find_module(nameCmd, [dirPath])
+            module = imp.load_module(nameCmd, file_, pathname, description)
+            
+            def run_command(args='',
+                            options=None,
+                            batch = False,
+                            verbose = -1,
+                            logger_add_link = None):
+                '''The function that will load the configuration (all pyconf)
+                and return the function run of the command corresponding to module
+                
+                :param args str: The arguments of the command 
+                '''
+                # Make sure the internationalization is available
+                # gettext.install('salomeTools', os.path.join(srcdir, 'i18n'))
+
+                # Get the arguments in a list and remove the empty elements
+                if type(args) == type(''):
+                    # split by spaces without considering spaces in quotes
+                    argv_0 = re.findall(r'(?:"[^"]*"|[^\s"])+', args)
+                else:
+                    argv_0 = args
+                
+                if argv_0 != ['']:
+                    while "" in argv_0: argv_0.remove("")
+                
+                # Format the argv list in order to prevent strings 
+                # that contain a blank to be separated
+                argv = []
+                elem_old = ""
+                for elem in argv_0:
+                    if argv == [] or elem_old.startswith("-") or elem.startswith("-"):
+                        argv.append(elem)
+                    else:
+                        argv[-1] += " " + elem
+                    elem_old = elem
+                           
+                # if it is provided by the command line, get the application
+                appliToLoad = None
+                if argv not in [[''], []] and argv[0][0] != "-":
+                    appliToLoad = argv[0].rstrip('*')
+                    argv = argv[1:]
+                
+                # Check if the global options of salomeTools have to be changed
+                if options:
+                    options_save = self.options
+                    self.options = options  
+
+                # read the configuration from all the pyconf files    
+                cfgManager = commands.config.ConfigManager()
+                self.cfg = cfgManager.get_config(datadir=self.datadir, 
+                                                 application=appliToLoad, 
+                                                 options=self.options, 
+                                                 command=__nameCmd__)
+                               
+                # Set the verbose mode if called
+                if verbose > -1:
+                    verbose_save = self.options.output_verbose_level
+                    self.options.__setattr__("output_verbose_level", verbose)    
+
+                # Set batch mode if called
+                if batch:
+                    batch_save = self.options.batch
+                    self.options.__setattr__("batch", True)
+
+                # set output level
+                if self.options.output_verbose_level is not None:
+                    self.cfg.USER.output_verbose_level = self.options.output_verbose_level
+                if self.cfg.USER.output_verbose_level < 1:
+                    self.cfg.USER.output_verbose_level = 0
+                silent = (self.cfg.USER.output_verbose_level == 0)
+
+                # create log file
+                micro_command = False
+                if logger_add_link:
+                    micro_command = True
+                logger_command = src.logger.Logger(self.cfg, 
+                                   silent_sysstd=silent,
+                                   all_in_terminal=self.options.all_in_terminal,
+                                   micro_command=micro_command)
+                
+                # Check that the path given by the logs_paths_in_file option
+                # is a file path that can be written
+                if self.options.logs_paths_in_file and not micro_command:
+                    try:
+                        self.options.logs_paths_in_file = os.path.abspath(
+                                                self.options.logs_paths_in_file)
+                        dir_file = os.path.dirname(self.options.logs_paths_in_file)
+                        if not os.path.exists(dir_file):
+                            os.makedirs(dir_file)
+                        if os.path.exists(self.options.logs_paths_in_file):
+                            os.remove(self.options.logs_paths_in_file)
+                        file_test = open(self.options.logs_paths_in_file, "w")
+                        file_test.close()
+                    except Exception as e:
+                        msg = _("WARNING: the logs_paths_in_file option will "
+                                "not be taken into account.\nHere is the error:")
+                        logger_command.write("%s\n%s\n\n" % (
+                                             src.printcolors.printcWarning(msg),
+                                             str(e)))
+                        self.options.logs_paths_in_file = None
+                
+                options_launched = ""
+                res = None
+                try:
+                    # Execute the hooks (if there is any) 
+                    # and run method of the command
+                    self.run_hook(__nameCmd__, C_PRE_HOOK, logger_command)
+                    res = __module__.run(argv, self, logger_command)
+                    self.run_hook(__nameCmd__, C_POST_HOOK, logger_command)
+                    if res is None:
+                        res = 0
+                        
+                except Exception as e:
+                    # Get error
+                    logger_command.write("\n***** ", 1)
+                    logger_command.write(
+                        src.printcolors.printcError("salomeTools ERROR:"), 1)
+                    logger_command.write("\n" + str(e) + "\n\n", 1)
+                    # get stack
+                    __, __, exc_traceback = sys.exc_info()
+                    fp = tempfile.TemporaryFile()
+                    traceback.print_tb(exc_traceback, file=fp)
+                    fp.seek(0)
+                    stack = fp.read()
+                    verbosity = 5
+                    if self.options.debug_mode:
+                        verbosity = 1
+                    logger_command.write("TRACEBACK:\n%s" % stack.replace('"',"'"),
+                                         verbosity)
+                finally:
+                    # set res if it is not set in the command
+                    if res is None:
+                        res = 1
+                                            
+                    # come back to the original global options
+                    if options:
+                        options_launched = get_text_from_options(self.options)
+                        self.options = options_save
+                    
+                    # come back in the original batch mode if 
+                    # batch argument was called
+                    if batch:
+                        self.options.__setattr__("batch", batch_save)
+
+                    # come back in the original verbose mode if 
+                    # verbose argument was called                        
+                    if verbose > -1:
+                        self.options.__setattr__("output_verbose_level", 
+                                                 verbose_save)
+                    # put final attributes in xml log file 
+                    # (end time, total time, ...) and write it
+                    launchedCommand = ' '.join([self.cfg.VARS.salometoolsway +
+                                                os.path.sep +
+                                                'sat',
+                                                options_launched,
+                                                __nameCmd__, 
+                                                ' '.join(argv_0)])
+                    launchedCommand = launchedCommand.replace('"', "'")
+                    
+                    # Add a link to the parent command      
+                    if logger_add_link is not None:
+                        logger_add_link.add_link(logger_command.logFileName,
+                                                 __nameCmd__,
+                                                 res,
+                                                 launchedCommand)
+                        logger_add_link.l_logFiles += logger_command.l_logFiles
+                                            
+                    # Put the final attributes corresponding to end time and
+                    # Write the file to the hard drive
+                    logger_command.end_write(
+                                        {"launchedCommand" : launchedCommand})
+                    
+                    if res != 0:
+                        res = 1
+                        
+                    # print the log file path if 
+                    # the maximum verbose mode is invoked
+                    if not micro_command:
+                        logger_command.write("\nPath to the xml log file:\n", 5)
+                        logger_command.write("%s\n\n" % \
+                            src.printcolors.printcInfo(logger_command.logFilePath), 5)
+
+                    # If the logs_paths_in_file was called, write the result
+                    # and log files in the given file path
+                    if self.options.logs_paths_in_file and not micro_command:
+                        file_res = open(self.options.logs_paths_in_file, "w")
+                        file_res.write(str(res) + "\n")
+                        for i, filepath in enumerate(logger_command.l_logFiles):
+                            file_res.write(filepath)
+                            if i < len(logger_command.l_logFiles):
+                                file_res.write("\n")
+                                file_res.flush()
+                
+                return res
+
+            # Make sure that run_command will be redefined 
+            # at each iteration of the loop
+            globals_up = {}
+            globals_up.update(run_command.__globals__)
+            globals_up.update({'__nameCmd__': nameCmd, '__module__' : module})
+            func = types.FunctionType(run_command.__code__,
+                                      globals_up,
+                                      run_command.__name__,
+                                      run_command.__defaults__,
+                                      run_command.__closure__)
+
+            # set the attribute corresponding to the command
+            self.__setattr__(nameCmd, func)
+
+    def run_hook(self, cmd_name, hook_type, logger):
+        '''Execute a hook file for a given command regarding the fact 
+           it is pre or post
+        
+        :param cmd_name str: The the command on which execute the hook
+        :param hook_type str: pre or post
+        :param logger Logger: the logging instance to use for the prints
+        '''
+        # The hooks must be defined in the application pyconf
+        # So, if there is no application, do not do anything
+        if not src.config_has_application(self.cfg):
+            return
+
+        # The hooks must be defined in the application pyconf in the
+        # APPLICATION section, hook : { command : 'script_path.py'}
+        if "hook" not in self.cfg.APPLICATION \
+                    or cmd_name not in self.cfg.APPLICATION.hook:
+            return
+
+        # Get the hook_script path and verify that it exists
+        hook_script_path = self.cfg.APPLICATION.hook[cmd_name]
+        if not os.path.exists(hook_script_path):
+            raise src.SatException(_("Hook script not found: %s") % 
+                                   hook_script_path)
+        
+        # Try to execute the script, catch the exception if it fails
+        try:
+            # import the module (in the sense of python)
+            pymodule = imp.load_source(cmd_name, hook_script_path)
+            
+            # format a message to be printed at hook execution
+            msg = src.printcolors.printcWarning(_("Run hook script"))
+            msg = "%s: %s\n" % (msg, 
+                                src.printcolors.printcInfo(hook_script_path))
+            
+            # run the function run_pre_hook if this function is called 
+            # before the command, run_post_hook if it is called after
+            if hook_type == C_PRE_HOOK and "run_pre_hook" in dir(pymodule):
+                logger.write(msg, 1)
+                pymodule.run_pre_hook(self.cfg, logger)
+            elif hook_type == C_POST_HOOK and "run_post_hook" in dir(pymodule):
+                logger.write(msg, 1)
+                pymodule.run_post_hook(self.cfg, logger)
+
+        except Exception as exc:
+            msg = _("Unable to run hook script: %s") % hook_script_path
+            msg += "\n" + str(exc)
+            raise src.SatException(msg)
+
+    def print_help(self, opt):
+        '''Prints help for a command. Function called when "sat -h <command>"
+        
+        :param argv str: the options passed (to get the command name)
+        '''
+        # if no command as argument (sat -h)
+        if len(opt)==0:
+            print_help()
+            return
+        # get command name
+        command = opt[0]
+        # read the configuration from all the pyconf files
+        cfgManager = commands.config.ConfigManager()
+        self.cfg = cfgManager.get_config(datadir=self.datadir)
+
+        # Check if this command exists
+        if not hasattr(self, command):
+            raise src.SatException(_("Command '%s' does not exist") % command)
+        
+        # Print salomeTools version
+        print_version()
+        
+        # load the module
+        module = self.get_module(command)
+
+        # print the description of the command that is done in the command file
+        if hasattr( module, "description" ) :
+            print(src.printcolors.printcHeader( _("Description:") ))
+            print(module.description() + '\n')
+
+        # print the description of the command options
+        if hasattr( module, "parser" ) :
+            module.parser.print_help()
+
+    def get_module(self, module):
+        '''Loads a command. Function called only by print_help
+        
+        :param module str: the command to load
+        '''
+        # Check if this command exists
+        if not hasattr(self, module):
+            raise src.SatException(_("Command '%s' does not exist") % module)
+
+        # load the module
+        (file_, pathname, description) = imp.find_module(module, [cmdsdir])
+        module = imp.load_module(module, file_, pathname, description)
+        return module
+
+def get_text_from_options(options):
+    text_options = ""
+    for attr in dir(options):
+        if attr.startswith("__"):
+            continue
+        if options.__getattr__(attr) != None:
+            option_contain = options.__getattr__(attr)
+            if type(option_contain)==type([]):
+                option_contain = ",".join(option_contain)
+            if type(option_contain)==type(True):
+                option_contain = ""
+            text_options+= "--%s %s " % (attr, option_contain)
+    return text_options
+                
+
+def print_version():
+    '''prints salomeTools version (in src/internal_config/salomeTools.pyconf)
+    '''
+    # read the config 
+    cfgManager = commands.config.ConfigManager()
+    cfg = cfgManager.get_config()
+    # print the key corresponding to salomeTools version
+    print(src.printcolors.printcHeader( _("Version: ") ) + 
+          cfg.INTERNAL.sat_version + '\n')
+
+
+def print_help():
+    '''prints salomeTools general help
+    
+    :param options str: the options
+    '''
+    print_version()
+    
+    print(src.printcolors.printcHeader( _("Usage: ") ) + 
+          "sat [sat_options] <command> [product] [command_options]\n")
+
+    parser.print_help()
+
+    # display all the available commands.
+    print(src.printcolors.printcHeader(_("Available commands are:\n")))
+    for command in lCommand:
+        print(" - %s" % (command))
+        
+    # Explain how to get the help for a specific command
+    print(src.printcolors.printcHeader(_("\nGetting the help for a specific"
+                                    " command: ")) + "sat --help <command>\n")
+
+def write_exception(exc):
+    '''write exception in case of error in a command
+    
+    :param exc exception: the exception to print
+    '''
+    sys.stderr.write("\n***** ")
+    sys.stderr.write(src.printcolors.printcError("salomeTools ERROR:"))
+    sys.stderr.write("\n" + str(exc) + "\n")
+
+
+
+
index 0432f613f78a27d7febaad1e8acdbc90bc406f1d..79192ad0e1e8114029a9d310326b33c1bdee2c19 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import unittest
 
 import src.product
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test of the compile command"""
index 208153f25492302f7566ea6c87389757cf664573..c9569654d2fecea3fde5ac8ee1b0a2a3a753453d 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import unittest
 
 import src.product
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test of the make command"""
index 51e4dd31ac866eb78d2eccbc3f613fcad5ce1d11..62aba791ddcbacfb186e087d020c72867b72529b 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import unittest
 
 import src.product
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestMakeinstall(unittest.TestCase):
     """Test of the makeinstall command"""
index 624db2c456ed0028fb7901ddfe40773dcb05821a..df1c0b0ac2e74a9e0fc8807ce2a3e0824d040457 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import shutil
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test create file .pyconf"""
index c828783647455ba1d34f53b9f49472f8c00d1637..bb7fe0b891475ed5379c383cf720c9de18358f4e 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """sat config --copy"""
index 1f368b8da2d0b392a8e8935d93907e5c22594690..a106791d5c002db01f4f3ed06c7f815faf9ee02f 100755 (executable)
@@ -23,7 +23,7 @@ import threading
 import time
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import check_proc_existence_and_kill_multi
 
 sleep_time = 2
index cde0fd3a2f3d6e6ec9ab829ff86c0aa862a14c1b..73cfd562a6e045219f3a2a389e1dba841ed56b32 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import platform
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import outRedirection
 
 class TestCase(unittest.TestCase):
index d90b3621fb6a7e425ac59f824b3181731664750e..413c462ab09c4190dbd6640a7239bd8b9efd2529 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import platform
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import outRedirection
 
 class TestCase(unittest.TestCase):
index a58f2067935485b5fa6912b772cf86cd112b939d..3a63fd5afd80269b92d26870b440e9a4aa14c277 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestSource(unittest.TestCase):
     """Test of the environ command"""
index af77c495779ecdad6f8f3104c99f381064f7b1f9..fc231913313207f03ef4ddecdd1a3f9b64d56449 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test the job command"""
index fe13190ad623984322aa87bec6a402fd39b08dba..0a673a73b4da7c55d7e25fd39eed114c981c06e8 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import outRedirection
 
 class TestCase(unittest.TestCase):
index 04a35e14cae912125480077fd13ded42be829b8c..03d261fd60682f78dc21fcbf4b25d0b5894230bf 100755 (executable)
@@ -25,7 +25,7 @@ import shutil
 import io
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import check_proc_existence_and_kill_multi
 
 sleep_time = 2
index 833be81d65f71f857c016e8bdea4f48ed1f6d565..deaf65ed21d5087edd3f5e1f8647ce0f96910f19 100755 (executable)
@@ -23,7 +23,7 @@ import threading
 import time
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 from test.unittestpy.tools import check_proc_existence_and_kill_multi
 
 sleep_time = 2
index 48108f3bcc9c7a854d85d667cbd95c7071f5b0a7..c753f8d922fe856bd995e2722c331902b49ec323 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 import src.product
 
 from test.unittestpy.tools import outRedirection
index 1a0fac8f8bc5aa4b6248970f27af842673560b0b..ad7db3109b2a2fe7f6e62420d378105cf8211b32 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 import shutil
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 import src.product
 from test.unittestpy.tools import outRedirection
 
index 88a710ddf2bfe888a30be4fa2b5981fd6f7dbf26..334054772909d6c934b4013c23abcdbc871cb46c 100755 (executable)
@@ -23,7 +23,7 @@ import shutil
 import unittest
 
 import src
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test of the prepare command"""
index ab89c369b680b7d65b31982c49aaec847decbb69..f60badc0d922312d84e9f59d7dd965fac053255e 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 import src.product
 from test.unittestpy.tools import outRedirection
 
index 06b5600d7fb2dd3be6966d35f51a5c5eed2d8301..80f579e2a50a15d0841208b43278ead2d4a07069 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestCase(unittest.TestCase):
     """Test of the shell command"""
index 615ee89500f702eec4b2c098f260a80b77d2b5fc..136df62bf14c3911e891eb4cb371b6918c168495 100755 (executable)
@@ -21,7 +21,7 @@ import os
 import sys
 import unittest
 
-from salomeTools import Sat
+from src.salomeTools import Sat
 
 class TestTest(unittest.TestCase):
     """Test of the test command"""