]> SALOME platform Git repositories - tools/sat.git/blob - commands/job.py
Salome HOME
c15afdb42988ef8288d48b31f773e45d742136e3
[tools/sat.git] / commands / job.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2012  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 import sys
21 import traceback
22 import tempfile
23
24 import src
25 import salomeTools
26
27 # Define all possible option for the make command :  sat make <options>
28 parser = src.options.Options()
29 parser.add_option('j', 'jobs_config', 'string', 'jobs_cfg', 
30                   _('Mandatory: The name of the config file that contains'
31                   ' the jobs configuration'))
32 parser.add_option('', 'name', 'string', 'job',
33     _('Mandatory: The job name from which to execute commands.'), "")
34
35 def description():
36     '''method that is called when salomeTools is called with --help option.
37     
38     :return: The text to display for the job command description.
39     :rtype: str
40     '''
41     return _("Executes the commands of the job defined"
42              " in the jobs configuration file\n\nexample:\nsat job "
43              "--jobs_config my_jobs --name my_job")
44   
45 def run(args, runner, logger):
46     '''method that is called when salomeTools is called with job parameter.
47     '''
48     
49     # Parse the options
50     (options, args) = parser.parse_args(args)
51          
52     l_cfg_dir = runner.cfg.PATHS.JOBPATH
53     
54     # Make sure the jobs_config option has been called
55     if not options.jobs_cfg:
56         message = _("The option --jobs_config is required\n")      
57         logger.write(src.printcolors.printcError(message))
58         return 1
59     
60     # Make sure the name option has been called
61     if not options.job:
62         message = _("The option --name is required\n")      
63         logger.write(src.printcolors.printcError(message))
64         return 1
65     
66     # Find the file in the directories
67     found = False
68     for cfg_dir in l_cfg_dir:
69         file_jobs_cfg = os.path.join(cfg_dir, options.jobs_cfg)
70         if not file_jobs_cfg.endswith('.pyconf'):
71             file_jobs_cfg += '.pyconf'
72         
73         if not os.path.exists(file_jobs_cfg):
74             continue
75         else:
76             found = True
77             break
78     
79     if not found:
80         msg = _("The file configuration %(name_file)s was not found."
81                 "\nUse the --list option to get the possible files.")
82         src.printcolors.printcError(msg)
83         return 1
84     
85     info = [
86     (_("Platform"), runner.cfg.VARS.dist),
87     (_("File containing the jobs configuration"), file_jobs_cfg)
88     ]
89     src.print_info(logger, info)
90     
91     # Read the config that is in the file
92     config_jobs = src.read_config_from_a_file(file_jobs_cfg)
93     
94     # Find the job and its commands
95     found = False
96     for job in config_jobs.jobs:
97         if job.name == options.job:
98             commands = job.commands
99             found = True
100             break
101     if not found:
102         msg = _("Impossible to find the job \"%(job_name)s\" in "
103                 "%(jobs_config_file)s" % {"job_name" : options.job,
104                                           "jobs_config_file" : file_jobs_cfg})
105         logger.write(src.printcolors.printcError(msg) + "\n")
106         return 1
107     
108     # Find the maximum length of the commands in order to format the display
109     len_max_command = max([len(cmd) for cmd in commands])
110     
111     # Loop over the commands and execute it
112     res = 0
113     nb_pass = 0
114     for command in commands:
115         specific_option = False
116         # Determine if it is a sat command or a shell command
117         cmd_exe = command.split(" ")[0] # first part
118         if cmd_exe == "sat":
119             # use the salomeTools parser to get the options of the command
120             sat_parser = salomeTools.parser
121             (options, argus) = sat_parser.parse_args(command.split(' ')[1:])
122             # Verify if there is a changed option
123             for attr in dir(options):
124                 if attr.startswith("__"):
125                     continue
126                 if options.__getattr__(attr) != None:
127                     specific_option = True
128             sat_command_name = argus[0]
129             end_cmd = " ".join(argus[1:])
130         else:
131             sat_command_name = "shell"
132             end_cmd = "--command " + command
133         
134         # Do not change the options if no option was called in the command
135         if not(specific_option):
136             options = None
137
138         # Get dynamically the command function to call 
139         sat_command = runner.__getattr__(sat_command_name)
140         logger.write("Executing " + 
141                      src.printcolors.printcLabel(command) + " ", 3)
142         logger.write("." * (len_max_command - len(command)) + " ", 3)
143         logger.flush()
144         
145         error = ""
146         stack = ""
147         try:
148             # Execute the command
149             code = sat_command(end_cmd,
150                                options = options,
151                                batch = True,
152                                verbose = 0,
153                                logger_add_link = logger)
154         except Exception as e:
155             code = 1
156             # Get error
157             error = str(e)
158             # get stack
159             __, __, exc_traceback = sys.exc_info()
160             fp = tempfile.TemporaryFile()
161             traceback.print_tb(exc_traceback, file=fp)
162             fp.seek(0)
163             stack = fp.read()
164             logger.add_link(_("Dead Link"),
165                             sat_command_name,
166                             code,
167                             "ERROR: %s TRACEBACK: %s" % (error,
168                                                     stack.replace('"',"'")))
169             
170         # Print the status of the command
171         if code == 0:
172             nb_pass += 1
173             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
174         else:
175             res = 1
176             logger.write('%s %s\n' % (src.printcolors.printc(src.KO_STATUS),
177                                       error), 3)
178             if len(stack) > 0:
179                 logger.write('stack: %s\n' % stack, 3)
180     
181     # Print the final state
182     if res == 0:
183         final_status = "OK"
184     else:
185         final_status = "KO"
186    
187     logger.write(_("\nCommands: %(status)s (%(valid_result)d/%(nb_products)d)\n") % \
188         { 'status': src.printcolors.printc(final_status), 
189           'valid_result': nb_pass,
190           'nb_products': len(commands) }, 3)
191     
192     return res