X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=salomeTools.py;h=dd6a88376e677b8e00de8dc940feebbeac4a7424;hb=430be6100860b041ae7e92ac7a59eec9b043bc0d;hp=1f28c7a55f1c713cafbdfad029a76d78a830b675;hpb=14b16c85ddf883c9a8e0837d785d97b931312ce0;p=tools%2Fsat.git diff --git a/salomeTools.py b/salomeTools.py index 1f28c7a..dd6a883 100755 --- a/salomeTools.py +++ b/salomeTools.py @@ -15,16 +15,17 @@ # 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 tempfile import imp import types import gettext +import traceback # salomeTools imports import src @@ -81,6 +82,8 @@ 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 in .")) class Sat(object): '''The main class that stores all the commands of salomeTools @@ -137,11 +140,28 @@ class Sat(object): ''' # 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='', batch = False, verbose = -1, logger_add_link = None): + 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 @@ -151,23 +171,39 @@ class Sat(object): gettext.install('salomeTools', os.path.join(satdir, 'src', 'i18n')) # Get the arguments in a list and remove the empty elements - argv = args.split(" ") - if argv != ['']: - while "" in argv: argv.remove("") - + argv_0 = args.split(" ") + 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 != [''] 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 @@ -185,21 +221,73 @@ class Sat(object): self.cfg.USER.output_verbose_level = 0 silent = (self.cfg.USER.output_verbose_level == 0) - # create log file, unless the command is called - # with a logger as parameter + # 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) + silent_sysstd=silent, + all_in_terminal=self.options.all_in_terminal, + micro_command=micro_command) - if logger_add_link is not None: - logger_add_link.xmlFile.append_node_attrib("Links", attrib={__nameCmd__ : logger_command.logFilePath}) + # 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 @@ -211,18 +299,43 @@ class Sat(object): if verbose > -1: self.options.__setattr__("output_verbose_level", verbose_save) - - finally: # 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__, args]) - logger_command.end_write({"launchedCommand" : launchedCommand}) + 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 + # 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, logger_command.logFilePath + return res # Make sure that run_command will be redefined # at each iteration of the loop @@ -298,7 +411,7 @@ class Sat(object): return # get command name command = opt[0] - # read the configuration from all the pyconf files + # read the configuration from all the pyconf files cfgManager = config.ConfigManager() self.cfg = cfgManager.get_config(datadir=self.datadir) @@ -334,7 +447,22 @@ class Sat(object): (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) ''' @@ -402,13 +530,9 @@ if __name__ == "__main__": code = fun_command(' '.join(args[1:])) else: # catch exception in order to show less verbose but elegant message - try: - code = fun_command(' '.join(args[1:])) - except Exception as exc: - code = 1 - write_exception(exc) + code = fun_command(' '.join(args[1:])) # exit salomeTools with the right code (0 if no errors, else 1) if code is None: code = 0 - sys.exit(code[0]) + sys.exit(code) \ No newline at end of file