Salome HOME
style: black format
[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
21 import src
22 import src.salomeTools
23
24 # Define all possible option for the make command :  sat make <options>
25 parser = src.options.Options()
26 parser.add_option(
27     "j",
28     "jobs_config",
29     "string",
30     "jobs_cfg",
31     _("Mandatory: The name of the config file that contains" " the jobs configuration"),
32 )
33 parser.add_option(
34     "",
35     "name",
36     "string",
37     "job",
38     _("Mandatory: The job name from which to execute commands."),
39     "",
40 )
41
42
43 def description():
44     """method that is called when salomeTools is called with --help option.
45
46     :return: The text to display for the job command description.
47     :rtype: str
48     """
49     return _(
50         """\
51 The job command executes the commands of the job defined in the jobs configuration file
52
53 example:
54 >> sat job --jobs_config my_jobs --name my_job
55 """
56     )
57
58
59 def run(args, runner, logger):
60     """method that is called when salomeTools is called with job parameter."""
61
62     # Parse the options
63     (options, args) = parser.parse_args(args)
64
65     l_cfg_dir = runner.cfg.PATHS.JOBPATH
66
67     # Make sure the jobs_config option has been called
68     if not options.jobs_cfg:
69         message = _("The option --jobs_config is required\n")
70         logger.write(src.printcolors.printcError(message))
71         return 1
72
73     # Make sure the name option has been called
74     if not options.job:
75         message = _("The option --name is required\n")
76         logger.write(src.printcolors.printcError(message))
77         return 1
78
79     # Find the file in the directories
80     found = False
81     for cfg_dir in l_cfg_dir:
82         file_jobs_cfg = os.path.join(cfg_dir, options.jobs_cfg)
83         if not file_jobs_cfg.endswith(".pyconf"):
84             file_jobs_cfg += ".pyconf"
85
86         if not os.path.exists(file_jobs_cfg):
87             continue
88         else:
89             found = True
90             break
91
92     if not found:
93         msg = _(
94             "The file configuration %(name_file)s was not found."
95             "\nUse the --list option to get the possible files."
96         )
97         src.printcolors.printcError(msg)
98         return 1
99
100     info = [
101         (_("Platform"), runner.cfg.VARS.dist),
102         (_("File containing the jobs configuration"), file_jobs_cfg),
103     ]
104     src.print_info(logger, info)
105
106     # Read the config that is in the file
107     config_jobs = src.read_config_from_a_file(file_jobs_cfg)
108
109     # Find the job and its commands
110     found = False
111     for job in config_jobs.jobs:
112         if job.name == options.job:
113             commands = job.commands
114             found = True
115             break
116     if not found:
117         msg = _(
118             'Impossible to find the job "%(job_name)s" in '
119             "%(jobs_config_file)s"
120             % {"job_name": options.job, "jobs_config_file": file_jobs_cfg}
121         )
122         logger.write(src.printcolors.printcError(msg) + "\n")
123         return 1
124
125     # Find the maximum length of the commands in order to format the display
126     len_max_command = max([len(cmd) for cmd in commands])
127
128     # Loop over the commands and execute it
129     res = 0
130     nb_pass = 0
131     for command in commands:
132         specific_option = False
133         # Determine if it is a sat command or a shell command
134         cmd_exe = command.split(" ")[0]  # first part
135         if cmd_exe == "sat":
136             # use the salomeTools parser to get the options of the command
137             sat_parser = src.salomeTools.parser
138             input_parser = src.remove_item_from_list(command.split(" ")[1:], "")
139             (options, argus) = sat_parser.parse_args(input_parser)
140             # Verify if there is a changed option
141             for attr in dir(options):
142                 if attr.startswith("__"):
143                     continue
144                 if options.__getattr__(attr) != None:
145                     specific_option = True
146             sat_command_name = argus[0]
147             end_cmd = " ".join(argus[1:])
148         else:
149             sat_command_name = "shell"
150             end_cmd = ["--command", command]
151         # Do not change the options if no option was called in the command
152         if not (specific_option):
153             options = None
154
155         # Get dynamically the command function to call
156         sat_command = runner.__getattr__(sat_command_name)
157
158         logger.write("Executing " + src.printcolors.printcLabel(command) + " ", 3)
159         logger.write("." * (len_max_command - len(command)) + " ", 3)
160         logger.flush()
161
162         error = ""
163         stack = ""
164         # Execute the command
165         code = sat_command(
166             end_cmd, options=options, batch=True, verbose=0, logger_add_link=logger
167         )
168
169         # Print the status of the command
170         if code == 0:
171             nb_pass += 1
172             logger.write("%s\n" % src.printcolors.printc(src.OK_STATUS), 3)
173         else:
174             if sat_command_name != "test":
175                 res = 1
176             logger.write("%s %s\n" % (src.printcolors.printc(src.KO_STATUS), error), 3)
177             if len(stack) > 0:
178                 logger.write("stack: %s\n" % stack, 3)
179
180     # Print the final state
181     if res == 0:
182         final_status = "OK"
183     else:
184         final_status = "KO"
185
186     logger.write(
187         _("\nCommands: %(status)s (%(valid_result)d/%(nb_products)d)\n")
188         % {
189             "status": src.printcolors.printc(final_status),
190             "valid_result": nb_pass,
191             "nb_products": len(commands),
192         },
193         3,
194     )
195
196     return res