Skip to content

Commit 818a677

Browse files
committed
Propagate SSL/proxy environment to pip and uv subprocesses
The environment map configured via PythonRewriteRpc.builder().environment() was applied to the RPC server process but not to the pip bootstrap subprocess (bootstrapOpenrewrite) or uv subprocesses (via UvExecutor). This caused pip install and uv commands to fail behind corporate proxies with SSL inspection, since they never received SSL_CERT_FILE, PIP_CERT, or proxy configuration. - Apply environment to the pip ProcessBuilder in bootstrapOpenrewrite() - Add static default environment to UvExecutor that gets applied to all subprocess ProcessBuilders - Set the UvExecutor default environment in PythonRewriteRpc.Builder.get() so DependencyWorkspace, UvLockRegeneration, and all other uv callers automatically inherit SSL/proxy configuration
1 parent 20efcb1 commit 818a677

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

rewrite-python/src/main/java/org/openrewrite/python/internal/UvExecutor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import java.nio.file.Path;
2727
import java.nio.file.Paths;
2828
import java.util.ArrayList;
29+
import java.util.Collections;
2930
import java.util.List;
31+
import java.util.Map;
3032
import java.util.concurrent.TimeUnit;
3133

3234
/**
@@ -37,6 +39,18 @@ public class UvExecutor {
3739

3840
private static final long DEFAULT_TIMEOUT_SECONDS = 120;
3941
private static @Nullable String cachedUvPath;
42+
private static volatile Map<String, String> defaultEnvironment = Collections.emptyMap();
43+
44+
/**
45+
* Set the default environment variables to apply to all uv subprocesses.
46+
* This is used to propagate SSL/proxy configuration (e.g., SSL_CERT_FILE,
47+
* HTTP_PROXY) from the parent process to uv invocations.
48+
*
49+
* @param environment the environment variables to apply
50+
*/
51+
public static void setDefaultEnvironment(Map<String, String> environment) {
52+
defaultEnvironment = Collections.unmodifiableMap(new java.util.HashMap<>(environment));
53+
}
4054

4155
@Value
4256
public static class RunResult {
@@ -61,6 +75,7 @@ public static RunResult run(Path workDir, String uvPath, String... args) throws
6175

6276
ProcessBuilder pb = new ProcessBuilder(command);
6377
pb.directory(workDir.toFile());
78+
pb.environment().putAll(defaultEnvironment);
6479
pb.redirectErrorStream(false);
6580

6681
Process process = pb.start();

rewrite-python/src/main/java/org/openrewrite/python/rpc/PythonRewriteRpc.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.openrewrite.marketplace.RecipeBundleResolver;
2424
import org.openrewrite.marketplace.RecipeMarketplace;
2525
import org.openrewrite.python.*;
26+
import org.openrewrite.python.internal.UvExecutor;
2627
import org.openrewrite.python.marker.PythonResolutionResult;
2728
import org.openrewrite.python.marker.PythonResolutionResult.Dependency;
2829
import org.openrewrite.python.marker.PythonResolutionResult.ResolvedDependency;
@@ -527,6 +528,12 @@ public Builder pythonVersion(String pythonVersion) {
527528

528529
@Override
529530
public PythonRewriteRpc get() {
531+
// Propagate SSL/proxy environment to uv subprocesses (used by
532+
// DependencyWorkspace, UvLockRegeneration, etc.)
533+
if (!environment.isEmpty()) {
534+
UvExecutor.setDefaultEnvironment(environment);
535+
}
536+
530537
String version = StringUtils.readFully(
531538
PythonRewriteRpc.class.getResourceAsStream("/META-INF/rewrite-python-version.txt")).trim();
532539
boolean isDevBuild = version.isEmpty() || version.endsWith(".dev0") || "unspecified".equals(version);
@@ -718,6 +725,7 @@ private void bootstrapOpenrewrite(Path pipPackagesPath, String version) {
718725
"--target=" + pipPackagesPath.toAbsolutePath().normalize(),
719726
"openrewrite==" + version
720727
);
728+
pb.environment().putAll(environment);
721729
pb.redirectErrorStream(true);
722730
if (log != null) {
723731
File logFile = log.toAbsolutePath().normalize().toFile();

0 commit comments

Comments
 (0)