@@ -27,7 +27,7 @@ def __init__(self, workflow_dir: Path, logger: Logger, parameter_manager: Parame
2727
2828 def run_multiple_commands (
2929 self , commands : list [str ]
30- ) -> None :
30+ ) -> bool :
3131 """
3232 Executes multiple shell commands concurrently in separate threads.
3333
@@ -38,17 +38,28 @@ def run_multiple_commands(
3838 Args:
3939 commands (list[str]): A list where each element is a list representing
4040 a command and its arguments.
41+
42+ Returns:
43+ bool: True if all commands succeeded, False if any failed.
4144 """
4245 # Log the start of command execution
4346 self .logger .log (f"Running { len (commands )} commands in parallel..." , 1 )
4447 start_time = time .time ()
4548
49+ results = []
50+ lock = threading .Lock ()
51+
52+ def run_and_track (cmd ):
53+ success = self .run_command (cmd )
54+ with lock :
55+ results .append (success )
56+
4657 # Initialize a list to keep track of threads
4758 threads = []
4859
4960 # Start a new thread for each command
5061 for cmd in commands :
51- thread = threading .Thread (target = self . run_command , args = (cmd ,))
62+ thread = threading .Thread (target = run_and_track , args = (cmd ,))
5263 thread .start ()
5364 threads .append (thread )
5465
@@ -60,7 +71,9 @@ def run_multiple_commands(
6071 end_time = time .time ()
6172 self .logger .log (f"Total time to run { len (commands )} commands: { end_time - start_time :.2f} seconds" , 1 )
6273
63- def run_command (self , command : list [str ]) -> None :
74+ return all (results )
75+
76+ def run_command (self , command : list [str ]) -> bool :
6477 """
6578 Executes a specified shell command and logs its execution details.
6679
@@ -110,7 +123,9 @@ def run_command(self, command: list[str]) -> None:
110123
111124 # Check for errors
112125 if process .returncode != 0 :
113- self .logger .log (f"ERRORS OCCURRED: Process exited with code { process .returncode } " , 2 )
126+ self .logger .log (f"ERROR: Command failed with exit code { process .returncode } : { command [0 ]} " , 0 )
127+ return False
128+ return True
114129
115130 def _stream_output (self , process : subprocess .Popen ) -> None :
116131 """
@@ -157,7 +172,7 @@ def read_stderr():
157172 stdout_thread .join ()
158173 stderr_thread .join ()
159174
160- def run_topp (self , tool : str , input_output : dict , custom_params : dict = {}) -> None :
175+ def run_topp (self , tool : str , input_output : dict , custom_params : dict = {}) -> bool :
161176 """
162177 Constructs and executes commands for the specified tool OpenMS TOPP tool based on the given
163178 input and output configurations. Ensures that all input/output file lists
@@ -176,6 +191,9 @@ def run_topp(self, tool: str, input_output: dict, custom_params: dict = {}) -> N
176191 input_output (dict): A dictionary specifying the input/output parameter names (as key) and their corresponding file paths (as value).
177192 custom_params (dict): A dictionary of custom parameters to pass to the tool.
178193
194+ Returns:
195+ bool: True if all commands succeeded, False if any failed.
196+
179197 Raises:
180198 ValueError: If the lengths of input/output file lists are inconsistent,
181199 except for single string inputs.
@@ -240,9 +258,9 @@ def run_topp(self, tool: str, input_output: dict, custom_params: dict = {}) -> N
240258
241259 # Run command(s)
242260 if len (commands ) == 1 :
243- self .run_command (commands [0 ])
261+ return self .run_command (commands [0 ])
244262 elif len (commands ) > 1 :
245- self .run_multiple_commands (commands )
263+ return self .run_multiple_commands (commands )
246264 else :
247265 raise Exception ("No commands to execute." )
248266
0 commit comments