1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#!/usr/bin/env python3
"""
subprocess_utils.py - Secure subprocess utilities for all Python scripts
This module provides secure subprocess wrappers that:
- Use full executable paths instead of command names
- Validate executables exist before running
- Provide consistent error handling
- Mitigate security vulnerabilities flagged by Bandit
All scripts should use these functions instead of calling subprocess directly.
"""
"""Raised when a required executable is not found in PATH."""
"""
Get the full path to an executable, validating it exists.
Args:
command: Command name to find (e.g., "git", "cargo")
Returns:
Full path to the executable
Raises:
ExecutableNotFoundError: If executable is not found in PATH
"""
=
return
"""
Build secure kwargs for subprocess.run with consistent hardening.
Args:
function_name: Name of the calling function (for error messages)
**kwargs: User-provided kwargs to validate and merge
Returns:
Validated and hardened kwargs dict for subprocess.run
Raises:
ValueError: If insecure parameters are provided
"""
# Disallow shell=True to preserve security guarantees
= f
# Disallow overriding the program to execute
= f
# Enforce text mode for stable typing (CompletedProcess[str])
=
# Prefer deterministic UTF-8 unless caller overrides
return
"""
Run a git command securely using full executable path.
Args:
args: Git command arguments (without 'git' prefix)
cwd: Working directory for the command
**kwargs: Additional arguments passed to subprocess.run
(e.g., capture_output=True, text=True, check=True, timeout=60)
Returns:
CompletedProcess result
Raises:
ExecutableNotFoundError: If git is not found
subprocess.CalledProcessError: If command fails and check=True
subprocess.TimeoutExpired: If command times out
Note:
Uses UTF-8 encoding by default for deterministic behavior across environments.
Override by passing encoding="<other>" via kwargs if needed.
"""
=
=
return
"""
Run a cargo command securely using full executable path.
Args:
args: Cargo command arguments (without 'cargo' prefix)
cwd: Working directory for the command
**kwargs: Additional arguments passed to subprocess.run
(e.g., capture_output=True, text=True, check=True, timeout=60)
Returns:
CompletedProcess result
Raises:
ExecutableNotFoundError: If cargo is not found
subprocess.CalledProcessError: If command fails and check=True
subprocess.TimeoutExpired: If command times out
"""
=
=
return
"""
Run any command securely using full executable path.
Args:
command: Command name to run (e.g., "rustc", "nproc")
args: Command arguments
cwd: Working directory for the command
**kwargs: Additional arguments passed to subprocess.run
(e.g., capture_output=True, text=True, check=True)
Returns:
CompletedProcess result
Raises:
ExecutableNotFoundError: If command is not found
subprocess.CalledProcessError: If command fails and check=True
"""
=
=
return
# Convenience functions for commonly used git commands
"""Get the current git commit hash.
Args:
cwd: Working directory for the git command (defaults to current process cwd)
Returns:
Current commit hash
Raises:
ExecutableNotFoundError: If git is not found
subprocess.CalledProcessError: If git command fails
"""
=
return
"""Get the URL of a git remote.
Args:
remote: Remote name (default: "origin")
cwd: Working directory for the git command (defaults to current process cwd)
Returns:
Remote URL
Raises:
ExecutableNotFoundError: If git is not found
subprocess.CalledProcessError: If git command fails
"""
=
return
"""
Check if current directory is in a git repository.
Returns:
True if in a git repository, False otherwise
"""
return True
return False
"""
Check if git repository has commit history.
Returns:
True if git history exists, False otherwise
"""
return True
return False
"""
Run a git command securely with stdin input using full executable path.
Args:
args: Git command arguments (without 'git' prefix)
input_data: Data to send to stdin
cwd: Working directory for the command
**kwargs: Additional arguments passed to subprocess.run
(e.g., text=True, check=True, timeout=60)
Returns:
CompletedProcess result
Raises:
ExecutableNotFoundError: If git is not found
subprocess.CalledProcessError: If command fails and check=True
subprocess.TimeoutExpired: If command times out
Note:
Uses UTF-8 encoding by default for deterministic behavior across environments.
Override by passing encoding="<other>" via kwargs if needed.
"""
=
=
return
# Project navigation utilities
"""Raised when project root directory cannot be located."""
"""Find the project root by looking for Cargo.toml.
Returns:
Path to project root directory
Raises:
ProjectRootNotFoundError: If Cargo.toml cannot be found in any parent directory
"""
=
=
return
=
=