Skip to content

Commit 98ef321

Browse files
committed
fix: do not raise FileNotFoundError if executable not found
1 parent f7fa9c1 commit 98ef321

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1515

1616
- Modify `publish` GitHub Actions workflow to only run on release, using PyPI trusted publishing
1717
- Modify `test` GitHub Actions workflow to test multiple operating systems and Python versions
18+
- Modify `Scripts.run_script()` to not raise a `FileNotFoundError` if the script does not exist; instead, allow
19+
`subprocess.run()` to raise a `CalledProcessError` if the script command fails to run.
1820

1921
### Fixed
2022

src/python_dev_cli/scripts.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,30 +115,36 @@ def run_script(self, script_key: str, **kwargs) -> List[CompletedProcess]:
115115
the script is a template and templates are enabled, it is resolved and parsed, and the resulting list of script
116116
commands are run. Otherwise, the script is resolved and run as a list of unparsed commands.
117117
118+
If `check` is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object
119+
will have the return code in the `returncode` attribute, and output & stderr attributes if those streams were
120+
captured. If `timeout` is given, and the process takes too long, a TimeoutExpired exception will be raised.
121+
118122
:param script_key: The name of the script being run.
119123
:param kwargs: Additional keyword arguments to pass to subprocess.run().
120124
:return: A list of CompletedProcess instances; these are the return values of subprocess.run().
121125
:raises KeyError: If the script key is not found.
122126
:raises ScriptTemplateError: If an error occurs while parsing a script template.
123-
:raises FileNotFoundError: If the executable for a script command is not found.
127+
:raises CalledProcessError: If `check` is True and the exit code was non-zero.
128+
:raises TimeoutExpired: If `timeout` is given, and the process takes too long.
124129
"""
125130
output: List[CompletedProcess] = []
126131

132+
# By default, tell subprocess.run() to raise an exception if the script fails.
127133
if "check" not in kwargs:
128-
kwargs["check"] = True # By default, raise an exception if the script fails.
134+
kwargs["check"] = True
129135

130136
for script in self.get_script_command(script_key):
131137
# Split the script into a list of arguments, and replace the first argument with the full executable path.
132138
args: List[str] = shlex.split(script, posix=is_posix())
133139
executable: str = shutil.which(args[0])
134-
args[0] = executable
135140

136-
# If the executable is found, run the script and print the output. Otherwise, raise an exception.
141+
# If the executable is found, use the full path; otherwise, leave the first argument as-is.
137142
if executable:
138-
logger.info(f"Running script [{script_key}]: {script}")
139-
output.append(run(args, **kwargs))
140-
else:
141-
raise FileNotFoundError(f"Executable not found for script [{script_key}]: {script}")
143+
args[0] = executable
144+
145+
# Run the script and append the result to the output list.
146+
logger.info(f"Running script [{script_key}]: {script}")
147+
output.append(run(args, **kwargs))
142148

143149
return output
144150

0 commit comments

Comments
 (0)