From 3c20b84b7d91f1930a483c3501dabaea350eb721 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Wed, 28 May 2025 13:22:54 +0800 Subject: [PATCH] fix: add necessary envs (if has) to validate executable binary in the PATH --- .../exhort/providers/JavaScriptProvider.java | 2 +- .../com/redhat/exhort/tools/Operations.java | 15 ++++++++++-- .../providers/Javascript_Envs_Test.java | 24 +++++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/redhat/exhort/providers/JavaScriptProvider.java b/src/main/java/com/redhat/exhort/providers/JavaScriptProvider.java index a83e31c4..91c2ff89 100644 --- a/src/main/java/com/redhat/exhort/providers/JavaScriptProvider.java +++ b/src/main/java/com/redhat/exhort/providers/JavaScriptProvider.java @@ -62,7 +62,7 @@ public abstract class JavaScriptProvider extends Provider { public JavaScriptProvider(Path manifest, Ecosystem.Type ecosystem, String cmd) { super(ecosystem, manifest); - this.cmd = Operations.getExecutable(cmd, "-v"); + this.cmd = Operations.getExecutable(cmd, "-v", getExecEnv()); try { this.manifest = new Manifest(manifest); } catch (IOException e) { diff --git a/src/main/java/com/redhat/exhort/tools/Operations.java b/src/main/java/com/redhat/exhort/tools/Operations.java index c2d3fda0..f1584ef2 100644 --- a/src/main/java/com/redhat/exhort/tools/Operations.java +++ b/src/main/java/com/redhat/exhort/tools/Operations.java @@ -242,10 +242,17 @@ public int getExitCode() { * @throws RuntimeException if the executable cannot be found, is not executable, or exits with an * error code */ - public static String getExecutable(String command, String args) { + public static String getExecutable( + String command, String args, final Map envMap) { String cmdExecutable = Operations.getCustomPathOrElse(command); try { - Process process = new ProcessBuilder(cmdExecutable, args).redirectErrorStream(true).start(); + ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.command(cmdExecutable, args); + if (envMap != null) { + processBuilder.environment().putAll(envMap); + } + Process process = processBuilder.start(); + int exitCode = process.waitFor(); if (exitCode != 0) { throw new IOException( @@ -265,4 +272,8 @@ public static String getExecutable(String command, String args) { } return cmdExecutable; } + + public static String getExecutable(String command, String args) { + return getExecutable(command, args, null); + } } diff --git a/src/test/java/com/redhat/exhort/providers/Javascript_Envs_Test.java b/src/test/java/com/redhat/exhort/providers/Javascript_Envs_Test.java index ff6b4814..c26d5064 100644 --- a/src/test/java/com/redhat/exhort/providers/Javascript_Envs_Test.java +++ b/src/test/java/com/redhat/exhort/providers/Javascript_Envs_Test.java @@ -17,7 +17,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mockStatic; +import com.redhat.exhort.tools.Operations; import com.redhat.exhort.utils.Environment; import java.io.File; import java.nio.file.Path; @@ -37,18 +41,28 @@ public class Javascript_Envs_Test { @SetSystemProperty(key = "NODE_HOME", value = "test-node-home") @SetSystemProperty(key = "PATH", value = "test-path") void test_javascript_get_envs() { - var envs = new JavaScriptNpmProvider(MANIFEST_PATH).getExecEnv(); - assertEquals( - Collections.singletonMap("PATH", "test-path" + File.pathSeparator + "test-node-home"), - envs); + try (MockedStatic mockedOperations = mockStatic(Operations.class)) { + // Configure the mock to return "npm" when getExecutable is called + mockedOperations + .when(() -> Operations.getExecutable(anyString(), anyString(), anyMap())) + .thenReturn("npm"); + var envs = new JavaScriptNpmProvider(MANIFEST_PATH).getExecEnv(); + assertEquals( + Collections.singletonMap("PATH", "test-path" + File.pathSeparator + "test-node-home"), + envs); + } } @Test @SetSystemProperty(key = "NODE_HOME", value = "test-node-home") void test_javascript_get_envs_no_path() { try (MockedStatic mockEnv = - Mockito.mockStatic(Environment.class, Mockito.CALLS_REAL_METHODS)) { + mockStatic(Environment.class, Mockito.CALLS_REAL_METHODS); + MockedStatic mockOps = mockStatic(Operations.class)) { mockEnv.when(() -> Environment.get("PATH")).thenReturn(null); + mockOps + .when(() -> Operations.getExecutable(anyString(), anyString(), anyMap())) + .thenReturn("npm"); var envs = new JavaScriptNpmProvider(MANIFEST_PATH).getExecEnv(); assertEquals(Collections.singletonMap("PATH", "test-node-home"), envs); }