77from typing import Iterable
88from typing import List
99from typing import Optional
10+ from typing import Text
1011from typing import Tuple
12+ from typing import Union
1113
1214from launch .some_substitutions_type import SomeSubstitutionsType
1315from launch .substitution import Substitution
16+ from launch .substitutions .text_substitution import TextSubstitution
1417from launch .launch_context import LaunchContext
1518from launch .utilities import normalize_to_list_of_substitutions
1619from launch .utilities import perform_substitutions
1720
18- _global_process_counter_lock = threading .Lock ()
19- _global_process_counter = 0 # in Python3, this number is unbounded (no rollover)
21+ _executable_process_counter_lock = threading .Lock ()
22+ _executable_process_counter = 0 # in Python3, this number is unbounded (no rollover)
23+
2024
2125class Executable :
22- """Describes an executable (typically a single process) which may be run by the launch system."""
26+ """Describes an executable (usually a single process) which may be run by the launch system."""
2327
2428 def __init__ (
2529 self , * ,
26- cmd : Iterable [SomeSubstitutionsType ],
30+ cmd : Union [ SomeSubstitutionsType , Iterable [SomeSubstitutionsType ] ],
2731 name : Optional [SomeSubstitutionsType ] = None ,
2832 cwd : Optional [SomeSubstitutionsType ] = None ,
2933 env : Optional [Dict [SomeSubstitutionsType , SomeSubstitutionsType ]] = None ,
@@ -44,7 +48,12 @@ def __init__(
4448 None, they are added to the current environment. If not, env is updated with
4549 additional_env.
4650 """
47- self .__cmd = [normalize_to_list_of_substitutions (x ) for x in cmd ]
51+ if (isinstance (cmd , Text )):
52+ self .__cmd = [[TextSubstitution (text = cmd )]]
53+ elif (isinstance (cmd , Substitution )):
54+ self .__cmd = [[cmd ]]
55+ else :
56+ self .__cmd = [normalize_to_list_of_substitutions (x ) for x in cmd ]
4857 self .__name = name if name is None else normalize_to_list_of_substitutions (name )
4958 self .__cwd = cwd if cwd is None else normalize_to_list_of_substitutions (cwd )
5059 self .__env = None # type: Optional[List[Tuple[List[Substitution], List[Substitution]]]]
@@ -88,9 +97,24 @@ def additional_env(self):
8897 return self .__additional_env
8998
9099 @property
91- def process_details (self ):
92- """Getter for the substituted executable details, e.g. cmd, cwd, env, or None if substitutions have not been performed."""
93- return self .__process_event_args
100+ def final_name (self ):
101+ """Getter for final_name."""
102+ return self .__final_name
103+
104+ @property
105+ def final_cmd (self ):
106+ """Getter for final_cmd."""
107+ return self .__final_cmd
108+
109+ @property
110+ def final_cwd (self ):
111+ """Getter for cwd."""
112+ return self .__final_cwd
113+
114+ @property
115+ def final_env (self ):
116+ """Getter for final_env."""
117+ return self .__final_env
94118
95119 def apply_context (self , context : LaunchContext ):
96120 """
@@ -100,22 +124,22 @@ def apply_context(self, context: LaunchContext):
100124 - performs substitutions on various properties
101125 """
102126 self .__expand_substitutions (context )
103- process_event_args = self .__process_event_args
104- if process_event_args is None :
105- raise RuntimeError ('process_event_args unexpectedly None' )
106127
107128 def __expand_substitutions (self , context ):
108129 # expand substitutions in arguments to async_execute_process()
109- cmd = [perform_substitutions (context , x ) for x in self .__cmd ]
130+ cmd = ' ' .join ([perform_substitutions (context , x ) for x in self .__cmd ])
131+ cmd = shlex .split (cmd )
132+ self .__final_cmd = cmd
110133 name = os .path .basename (cmd [0 ]) if self .__name is None \
111134 else perform_substitutions (context , self .__name )
112- with _global_process_counter_lock :
113- global _global_process_counter
114- _global_process_counter += 1
115- self .__name = '{ }-{}' . format ( name , _global_process_counter )
135+ with _executable_process_counter_lock :
136+ global _executable_process_counter
137+ _executable_process_counter += 1
138+ self .__final_name = f": { name } -{ _executable_process_counter } "
116139 cwd = None
117140 if self .__cwd is not None :
118141 cwd = '' .join ([context .perform_substitution (x ) for x in self .__cwd ])
142+ self .__final_cwd = cwd
119143 env = None
120144 if self .__env is not None :
121145 env = {}
@@ -128,14 +152,4 @@ def __expand_substitutions(self, context):
128152 for key , value in self .__additional_env :
129153 env ['' .join ([context .perform_substitution (x ) for x in key ])] = \
130154 '' .join ([context .perform_substitution (x ) for x in value ])
131- # store packed kwargs for all ProcessEvent based events
132- self .__process_event_args = {
133- 'description' : self ,
134- 'name' : self .__name ,
135- 'cmd' : cmd ,
136- 'cwd' : cwd ,
137- 'env' : env ,
138- # pid is added to the dictionary in the connection_made() method of the protocol.
139- }
140-
141-
155+ self .__final_env = env
0 commit comments