11from functools import lru_cache
22import subprocess
33import re
4+ import os
45
56def create_sim_config(args):
67 # creates a generic simulation config
@@ -143,11 +144,43 @@ def constructConfigKeyArg(config):
143144 arg = arg + '"'
144145 return arg
145146
147+ def load_env_file(env_file):
148+ """Transform an environment file generated with 'export > env.txt' into a python dictionary."""
149+ env_vars = {}
150+ with open(env_file, "r") as f:
151+ for line in f:
152+ line = line.strip()
153+
154+ # Ignore empty lines or comments
155+ if not line or line.startswith("#"):
156+ continue
157+
158+ # Remove 'declare -x ' if present
159+ if line.startswith("declare -x "):
160+ line = line.replace("declare -x ", "", 1)
161+
162+ # Handle case: "FOO" without "=" (assign empty string)
163+ if "=" not in line:
164+ key, value = line.strip(), ""
165+ else:
166+ key, value = line.split("=", 1)
167+ value = value.strip('"') # Remove surrounding quotes if present
168+
169+ env_vars[key.strip()] = value
170+ return env_vars
171+
146172# some functions to determine dpl option availability on the fly
147- def parse_dpl_help_output(executable):
173+ def parse_dpl_help_output(executable, envfile ):
148174 """Parses the --help full output of an executable to extract available options."""
149175 try:
150- output = subprocess.check_output([executable, "--help", "full"], text=True)
176+ env = os.environ.copy()
177+ if envfile != None:
178+ print ("Loading from alternative environment")
179+ env = load_env_file(envfile)
180+
181+ # the DEVNULL is important for o2-dpl workflows not to hang on non-interactive missing tty environments
182+ # it is cleaner that the echo | trick
183+ output = subprocess.check_output([executable, "--help", "full"], env=env, text=True, stdin=subprocess.DEVNULL, timeout = 10)
151184 except subprocess.CalledProcessError:
152185 return {}, {}
153186
@@ -172,11 +205,11 @@ def parse_dpl_help_output(executable):
172205 return sections, inverse_lookup
173206
174207@lru_cache(maxsize=10)
175- def get_dpl_options_for_executable(executable):
208+ def get_dpl_options_for_executable(executable, envfile ):
176209 """Returns available options and inverse lookup for a given executable, caching the result."""
177- return parse_dpl_help_output(executable)
210+ return parse_dpl_help_output(executable, envfile )
178211
179- def option_if_available(executable, option):
212+ def option_if_available(executable, option, envfile = None ):
180213 """Checks if an option is available for a given executable and returns it as a string. Otherwise empty string"""
181- _, inverse_lookup = get_dpl_options_for_executable(executable)
214+ _, inverse_lookup = get_dpl_options_for_executable(executable, envfile )
182215 return ' ' + option if option in inverse_lookup else ''
0 commit comments