Salome HOME
Add the job command
authorSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 9 Jun 2016 08:25:28 +0000 (10:25 +0200)
committerSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 9 Jun 2016 08:25:28 +0000 (10:25 +0200)
commands/compile.py
commands/job.py [new file with mode: 0644]
commands/log.py
commands/prepare.py
salomeTools.py
src/compilation.py
src/environment.py
src/logger.py
src/xsl/command.xsl

index 532c88040f0f3272cde69333c760ccb90e721104..5ab1c502b8296dc4aed0dd10e7ba648a2611bf04 100644 (file)
@@ -399,7 +399,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
     # Logging and sat command call for configure step
     len_end_line = len_end
     log_step(logger, header, "CONFIGURE")
-    res_c, __ = sat.configure(config.VARS.application + " --products " + p_name,
+    res_c = sat.configure(config.VARS.application + " --products " + p_name,
                           verbose = 0,
                           logger_add_link = logger)
     log_res_step(logger, res_c)
@@ -424,7 +424,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
         # Get the make_flags option if there is any
         if options.makeflags:
             make_arguments += " --option -j" + options.makeflags
-        res_m, __ = sat.make(make_arguments,
+        res_m = sat.make(make_arguments,
                          verbose = 0,
                          logger_add_link = logger)
         log_res_step(logger, res_m)
@@ -435,7 +435,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
         else: 
             # Logging and sat command call for make install step
             log_step(logger, header, "MAKE INSTALL")
-            res_mi, __ = sat.makeinstall(config.VARS.application + 
+            res_mi = sat.makeinstall(config.VARS.application + 
                                      " --products " + 
                                      p_name,
                                     verbose = 0,
diff --git a/commands/job.py b/commands/job.py
new file mode 100644 (file)
index 0000000..cbaf3ea
--- /dev/null
@@ -0,0 +1,155 @@
+#!/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
+
+import os
+
+import src
+import jobs
+
+# Define all possible option for the make command :  sat make <options>
+parser = src.options.Options()
+parser.add_option('j', 'jobs_config', 'string', 'jobs_cfg', 
+                  _('The name of the config file that contains'
+                  ' the jobs configuration'))
+parser.add_option('', 'job', 'string', 'job',
+    _('The job name from which to execute commands.'), "")
+
+def description():
+    '''method that is called when salomeTools is called with --help option.
+    
+    :return: The text to display for the job command description.
+    :rtype: str
+    '''
+    return _("Executes the commands of the job defined"
+             " in the jobs configuration file")
+  
+def run(args, runner, logger):
+    '''method that is called when salomeTools is called with job parameter.
+    '''
+    
+    # Parse the options
+    (options, args) = parser.parse_args(args)
+      
+    jobs_cfg_files_dir = runner.cfg.SITE.jobs.config_path
+    
+    # Make sure the path to the jobs config files directory exists 
+    if not os.path.exists(jobs_cfg_files_dir):      
+        logger.write(_("Creating directory %s\n") % 
+                     src.printcolors.printcLabel(jobs_cfg_files_dir), 1)
+        os.mkdir(jobs_cfg_files_dir)
+
+    # Make sure the jobs_config option has been called
+    if not options.jobs_cfg:
+        message = _("The option --jobs_config is required\n")      
+        raise src.SatException( message )
+    
+    # Make sure the job option has been called
+    if not options.job:
+        message = _("The option --job is required\n")      
+        raise src.SatException( message )
+    
+    # Make sure the invoked file exists
+    file_jobs_cfg = os.path.join(jobs_cfg_files_dir, options.jobs_cfg)
+    if not file_jobs_cfg.endswith('.pyconf'):
+        file_jobs_cfg += '.pyconf'
+        
+    if not os.path.exists(file_jobs_cfg):
+        message = _("The file %s does not exist.\n") % file_jobs_cfg
+        logger.write(src.printcolors.printcError(message), 1)
+        message = _("The possible files are :\n")
+        logger.write( src.printcolors.printcInfo(message), 1)
+        for f in sorted(os.listdir(jobs_cfg_files_dir)):
+            if not f.endswith('.pyconf'):
+                continue
+            jobscfgname = f[:-7]
+            logger.write("%s\n" % jobscfgname)
+        raise src.SatException( _("No corresponding file") )
+    
+    jobs.print_info(logger, runner.cfg.VARS.dist, file_jobs_cfg)
+    
+    # Read the config that is in the file
+    config_jobs = src.read_config_from_a_file(file_jobs_cfg)
+    
+    # Find the job and its commands
+    found = False
+    for job in config_jobs.jobs:
+        if job.name == options.job:
+            commands = job.commands
+            found = True
+            break
+    if not found:
+        msg = _("Impossible to find the job \"%(job_name)s\" in "
+                "%(jobs_config_file)s" % {"job_name" : options.job,
+                                          "jobs_config_file" : file_jobs_cfg})
+        logger.write(src.printcolors.printcError(msg) + "\n")
+        return 1
+    
+    # Find the maximum length of the commands in order to format the display
+    len_max_command = max([len(cmd) for cmd in commands])
+    
+    # Loop over the commands and execute it
+    res = 0
+    nb_pass = 0
+    for command in commands:
+        # Determine if it is a sat command or a shell command
+        cmd_exe = command.split(" ")[0] # first part
+        if cmd_exe == "sat":
+            sat_command_name = command.split(" ")[1]
+            end_cmd = command.replace(cmd_exe + " " + sat_command_name, "")
+        else:
+            sat_command_name = "shell"
+            end_cmd = "--command " + command
+        
+        # Get dynamically the command function to call 
+        sat_command = runner.__getattr__(sat_command_name)
+        logger.write("Executing " + 
+                     src.printcolors.printcLabel(command) + " ", 3)
+        logger.write("." * (len_max_command - len(command)) + " ", 3)
+        logger.flush()
+        # Execute the command
+        code = sat_command(end_cmd,
+                                     batch = True,
+                                     verbose = 0,
+                                     logger_add_link = logger)
+        # Print the status of the command
+        if code == 0:
+            nb_pass += 1
+            logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
+        else:
+            res = 1
+            logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 3)
+    
+    # Print the final state
+    if res == 0:
+        final_status = "OK"
+    else:
+        final_status = "KO"
+   
+    logger.write(_("\nCommands: %(status)s (%(valid_result)d/%(nb_products)d)\n\n") % \
+        { 'status': src.printcolors.printc(final_status), 
+          'valid_result': nb_pass,
+          'nb_products': len(commands) }, 3)
+    
+    # Print the status and the list of log files
+    logger.write(_("The status and the list of log files "
+                   "used in the command is the following :\n"))
+    logger.write("%i\n" % res, 1)
+    for file_path in logger.l_logFiles:
+        logger.write("%s\n" % file_path, 1)
+    
+    return res
\ No newline at end of file
index c7e46020dcead744c65abd8460d3b66bca8baa2f..ff93fad6fdf71989da29f571e850056f3e7890ad 100644 (file)
@@ -161,7 +161,8 @@ def run(args, runner, logger):
                             'OUT', 
                             os.path.basename(filePath)[:-len('.xml')] + '.txt')
             remove_log_file(txtFilePath, logger)
-            # remove also the corresponding pyconf file in OUT directory
+            # remove also the corresponding pyconf (do not exist 2016-06) 
+            # file in OUT directory
             pyconfFilePath = os.path.join(os.path.dirname(filePath), 
                             'OUT', 
                             os.path.basename(filePath)[:-len('.xml')] + '.pyconf')
index 3dedf61255e406396e5b4529f3527598cdc75590..a09f4a49d2c85bda9fd31332e89698bb9ac3e37b 100644 (file)
@@ -158,7 +158,7 @@ def run(args, runner, logger):
         msg = _("Clean the source directories ...")
         logger.write(msg, 3)
         logger.flush()
-        res_clean, __ = runner.clean(args_clean, batch=True, verbose = 0,
+        res_clean = runner.clean(args_clean, batch=True, verbose = 0,
                                     logger_add_link = logger)
         if res_clean == 0:
             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
@@ -167,7 +167,7 @@ def run(args, runner, logger):
     if do_source:
         msg = _("Get the sources of the products ...")
         logger.write(msg, 5)
-        res_source, __ = runner.source(args_source,
+        res_source = runner.source(args_source,
                                     logger_add_link = logger)
         if res_source == 0:
             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
@@ -176,7 +176,7 @@ def run(args, runner, logger):
     if do_patch:
         msg = _("Patch the product sources (if any) ...")
         logger.write(msg, 5)
-        res_patch, __ = runner.patch(args_patch,
+        res_patch = runner.patch(args_patch,
                                     logger_add_link = logger)
         if res_patch == 0:
             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
index 4049ed2436995460ea1e0d14b2a4694afc56945f..e384fc4d972ec654d894ae630feaad0e8411c602 100755 (executable)
@@ -171,7 +171,7 @@ class Sat(object):
                 if argv != [''] and argv[0][0] != "-":
                     appliToLoad = argv[0].rstrip('*')
                     argv = argv[1:]
-                               
+   
                 # read the configuration from all the pyconf files    
                 cfgManager = config.ConfigManager()
                 self.cfg = cfgManager.get_config(datadir=self.datadir, 
@@ -196,15 +196,11 @@ 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
                 logger_command = src.logger.Logger(self.cfg, 
                                                    silent_sysstd=silent,
                                                    all_in_terminal=self.options.all_in_terminal)
-                
-                if logger_add_link is not None:
-                    logger_add_link.xmlFile.append_node_attrib("Links", attrib={__nameCmd__ : logger_command.logFilePath})
-                
+                               
                 try:
                     # Execute the hooks (if there is any) 
                     # and run method of the command
@@ -226,8 +222,6 @@ 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 +
@@ -235,9 +229,34 @@ class Sat(object):
                                                 'sat',
                                                 __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:
+                        xmlLinks = logger_add_link.xmlFile.xmlroot.find(
+                                                                    "Links")
+                        src.xmlManager.add_simple_node(xmlLinks, 
+                                                       "link", 
+                                            text = logger_command.logFileName,
+                                            attrib = {"command" : __nameCmd__,
+                                                      "passed" : res,
+                                        "launchedCommand" : launchedCommand})
+                        logger_add_link.l_logFiles +=    logger_command.l_logFiles
+
+                finally:
+                    launchedCommand = ' '.join([self.cfg.VARS.salometoolsway +
+                                                os.path.sep +
+                                                'sat',
+                                                __nameCmd__, 
+                                                args])
+                    launchedCommand = launchedCommand.replace('"', "'")
+                    
+                    # Put the final attributes corresponding to end time and
+                    # Write the file to the hard drive
+                    logger_command.end_write(
+                                        {"launchedCommand" : launchedCommand})
                 
-                return res, logger_command.logFilePath
+                return res
 
             # Make sure that run_command will be redefined 
             # at each iteration of the loop
@@ -414,11 +433,11 @@ if __name__ == "__main__":
     if options.debug_mode:
         # call classically the command and if it fails, 
         # show exception and stack (usual python mode)
-        code, __ = fun_command(' '.join(args[1:]))
+        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:]))
+            code = fun_command(' '.join(args[1:]))
         except Exception as exc:
             code = 1
             write_exception(exc)
index 153d74850d505d4ba8033d9e8e2946d2b1c587e4..9368db92e37bf44b53e26ee825b567b82c4f6984 100644 (file)
@@ -44,19 +44,6 @@ class Builder:
         self.header = ""
         self.debug_mode = debug_mode
 
-        if not self.source_dir.exists() and check_src:
-            raise src.SatException(_("No sources found for product %(product)s in %(source_dir)s" % \
-                { "product": self.product_info.name, "source_dir": self.source_dir } ))
-
-        """
-        # check that required modules exist
-        for dep in self.product_info.depend:
-            assert dep in self.config.TOOLS.src.product_info, "UNDEFINED product: %s" % dep
-            dep_info = self.config.TOOLS.src.product_info[dep]
-            if 'install_dir' in dep_info and not os.path.exists(dep_info.install_dir):
-                raise src.SatException(_("Module %s is required") % dep)
-        """
-
     ##
     # Shortcut method to log in log file.
     def log(self, text, level, showInfo=True):
index 7868ed4a300ef55c6d4ec6b17cda16d0a5a7267f..6e2888b960741c93eabb4a1f8bd86bd5c39b468e 100644 (file)
@@ -129,7 +129,7 @@ class Environ:
         
         :param key str: the environment variable to check
         '''
-        return self.environ.has_key(key)
+        return key in self.environ.keys()
 
     def set(self, key, value):
         '''Set the environment variable "key" to value "value"
index 0e662030b28edde86befa4c191c1ae0b79150ac4..40c01367e7c7575e15d21fd601062f5607c66c14 100644 (file)
@@ -54,10 +54,17 @@ class Logger(object):
         src.ensure_path_exists(os.path.dirname(logFilePath))
         src.ensure_path_exists(os.path.dirname(txtFilePath))
         
+        # The path of the log files (one for sat traces, and the other for 
+        # the system commands traces)
         self.logFileName = logFileName
         self.logFilePath = logFilePath
         self.txtFileName = txtFileName
         self.txtFilePath = txtFilePath
+        
+        # The list of all log files corresponding to the current command and
+        # the commands called by the current command
+        self.l_logFiles = [logFilePath, txtFilePath]
+        
         # Initialize xml instance and put first fields 
         # like beginTime, user, command, etc... 
         self.xmlFile = xmlManager.XmlLogFile(logFilePath, "SATcommand", 
@@ -65,6 +72,8 @@ class Logger(object):
         self.put_initial_xml_fields()
         # Initialize the txt file for reading
         self.logTxtFile = open(str(self.txtFilePath), 'w')
+        # If the option all_in_terminal was called, all the system commands
+        # are redirected to the terminal
         if all_in_terminal:
             self.logTxtFile = sys.__stdout__
         
@@ -249,6 +258,7 @@ def show_command_log(logFilePath, cmd, application, notShownCommands):
  
     # Get the application of the log file
     logFileXml = src.xmlManager.ReadXmlFile(logFilePath)
+
     if 'application' in logFileXml.xmlroot.keys():
         appliLog = logFileXml.xmlroot.get('application')
         # if it corresponds, then the log has to be shown
@@ -282,10 +292,12 @@ def list_log_file(dirPath, expression):
             date_hour_cmd = fileName.split('_')
             date_not_formated = date_hour_cmd[0]
             date = "%s/%s/%s" % (date_not_formated[6:8], 
-                                 date_not_formated[4:6], date_not_formated[0:4] )
+                                 date_not_formated[4:6], 
+                                 date_not_formated[0:4])
             hour_not_formated = date_hour_cmd[1]
             hour = "%s:%s:%s" % (hour_not_formated[0:2], 
-                                 hour_not_formated[2:4], hour_not_formated[4:6])
+                                 hour_not_formated[2:4], 
+                                 hour_not_formated[4:6])
             cmd = date_hour_cmd[2][:-len('.xml')]
             lRes.append((os.path.join(dirPath, fileName), 
                          date_not_formated, date, hour_not_formated, hour, cmd))
index 97c3dd6984d722d1073437a8d3ac4b89f5e10089..6ab03004cea0496478bc35e199aa2e8da4d04820 100644 (file)
@@ -24,6 +24,8 @@
                       overflow: auto;
                       max-height: 250px;
                     }
+        .OK2        { color:#00AA00; }
+       .KO2        { color:#FF0000; }
     </style>
        
 </head>
                
                <h1>Links</h1>
                <table border="1">
-                       <tr>
-                               <xsl:for-each select="SATcommand/Links/@*">
+                       <xsl:for-each select="SATcommand/Links/link">
+                               <tr>
                                        <td bgcolor="LightBlue">
-                                               <a title="log">
-                                                       <xsl:attribute name="href"><xsl:value-of select="."/></xsl:attribute>
-                                                       <xsl:value-of select="name(.)"/>
-                                               </a>
+                                               <xsl:value-of select="@launchedCommand"/>
                                        </td>
-                               </xsl:for-each>
-                       </tr>
+                                       <td bgcolor="Beige">
+                                               <xsl:if test="@passed='0'">
+                                                       <a>
+                                                               <xsl:attribute name="title">Click for more information</xsl:attribute>
+                                                               <xsl:attribute name="class">OK2</xsl:attribute>
+                                                               <xsl:attribute name="href"><xsl:value-of select="."/></xsl:attribute>
+                                                               <xsl:value-of select="@command"/>
+                                                       </a>
+                                               </xsl:if>
+                                               <xsl:if test="@passed='1'">
+                                                       <a>
+                                                               <xsl:attribute name="title">Click for more information</xsl:attribute>
+                                                               <xsl:attribute name="class">KO2</xsl:attribute>
+                                                               <xsl:attribute name="href"><xsl:value-of select="."/></xsl:attribute>
+                                                               <xsl:value-of select="@command"/>
+                                                       </a>
+                                               </xsl:if>
+                                       </td>
+                               </tr>
+                       </xsl:for-each>
+                       
                </table>
                
-               <h1>output</h1>
-               PENSER A METTRE UN LIEN POUR OUVRIR LE FICHIER AVEC UN EDITEUR DE TEXTE
+               <h1>output 
+               <a target="_blank">
+                       <xsl:attribute name="title">Click to open in an editor</xsl:attribute>
+                       <xsl:attribute name="href"><xsl:value-of select="SATcommand/OutLog"/></xsl:attribute>
+                       <xsl:attribute name="download"><xsl:value-of select="SATcommand/OutLog"/></xsl:attribute>
+                       log
+               </a>
+               </h1>
                <xsl:variable name="txtLog">
                        <xsl:value-of select="SATcommand/OutLog"/>
                </xsl:variable>
                <iframe src="{$txtLog}" frameborder="0" class="center" width="100%" height="1500000" scrolling="no"></iframe>
        </body>
 </xsl:template>
+
 </xsl:stylesheet>
\ No newline at end of file