|
15 | 15 | */ |
16 | 16 | package com.diffplug.spotless.cli; |
17 | 17 |
|
| 18 | +import java.nio.file.Path; |
18 | 19 | import java.util.ArrayList; |
| 20 | +import java.util.LinkedHashMap; |
19 | 21 | import java.util.List; |
| 22 | +import java.util.Map; |
| 23 | +import java.util.Optional; |
20 | 24 |
|
21 | 25 | import com.diffplug.spotless.ProcessRunner; |
22 | 26 | import com.diffplug.spotless.ThrowingEx; |
23 | 27 |
|
24 | 28 | public class SpotlessCLIRunnerInExternalJavaProcess extends SpotlessCLIRunner { |
25 | 29 |
|
26 | | - static final String SPOTLESS_CLI_SHADOW_JAR_SYSPROP = "spotless.cli.shadowJar"; |
| 30 | + static final String SPOTLESS_CLI_PROCESS_LAUNCHER = "spotless.cli.processLauncher"; |
| 31 | + static final String SPOTLESS_CLI_PROCESS_LAUNCHER_JAVA_HOME = "spotless.cli.processLauncher.javaHome"; // optional |
27 | 32 |
|
28 | 33 | public SpotlessCLIRunnerInExternalJavaProcess() { |
29 | 34 | super(); |
30 | | - if (System.getProperty(SPOTLESS_CLI_SHADOW_JAR_SYSPROP) == null) { |
| 35 | + if (System.getProperty(SPOTLESS_CLI_PROCESS_LAUNCHER) == null) { |
31 | 36 | throw new IllegalStateException( |
32 | | - "spotless.cli.shadowJar system property must be set to the path of the shadow jar"); |
| 37 | + SPOTLESS_CLI_PROCESS_LAUNCHER + " system property must be set to the path of the launcher"); |
33 | 38 | } |
34 | 39 | } |
35 | 40 |
|
36 | 41 | protected Result executeCommand(List<String> args) { |
37 | 42 | try (ProcessRunner runner = new ProcessRunner()) { |
38 | 43 |
|
39 | 44 | ProcessRunner.Result pResult = |
40 | | - ThrowingEx.get(() -> runner.exec(workingDir(), System.getenv(), null, processArgs(args))); |
| 45 | + ThrowingEx.get(() -> runner.exec(workingDir(), envWithCurrentJava(), null, processArgs(args))); |
41 | 46 |
|
42 | 47 | return new Result(pResult.exitCode(), null, pResult.stdOutUtf8(), pResult.stdErrUtf8()); |
43 | 48 | } |
44 | 49 | } |
45 | 50 |
|
46 | 51 | private List<String> processArgs(List<String> args) { |
47 | 52 | List<String> processArgs = new ArrayList<>(); |
48 | | - processArgs.add(currentJavaExecutable()); |
49 | | - processArgs.add("-jar"); |
50 | | - String jarPath = System.getProperty(SPOTLESS_CLI_SHADOW_JAR_SYSPROP); |
51 | | - processArgs.add(jarPath); |
52 | | - |
53 | | - // processArgs.add(SpotlessCLI.class.getProtectionDomain().getCodeSource().getLocation().getPath()); |
54 | | - |
| 53 | + processArgs.add(System.getProperty(SPOTLESS_CLI_PROCESS_LAUNCHER)); |
55 | 54 | processArgs.addAll(args); |
56 | 55 | return processArgs; |
57 | 56 | } |
58 | 57 |
|
| 58 | + private Map<String, String> envWithCurrentJava() { |
| 59 | + // put current java |
| 60 | + Map<String, String> env = new LinkedHashMap<>(System.getenv()); |
| 61 | + |
| 62 | + // Override JAVA_HOME if specified via sysprop or use current java |
| 63 | + Optional<String> javaHomeOpt = javaHomeFromSyspropOrCurrent(); |
| 64 | + javaHomeOpt.ifPresentOrElse(javaHome -> env.put("JAVA_HOME", javaHome), () -> env.remove("JAVA_HOME")); |
| 65 | + |
| 66 | + // Prepend current java bin to PATH |
| 67 | + String currentJavaBin = currentJavaExecutable(); |
| 68 | + if (!"java".equals(currentJavaBin)) { |
| 69 | + String currentJavaDir = Path.of(currentJavaBin).getParent().toString(); |
| 70 | + String currentPath = env.get("PATH"); |
| 71 | + if (currentPath == null || currentPath.isEmpty()) { |
| 72 | + currentPath = currentJavaDir; |
| 73 | + } else { |
| 74 | + currentPath = currentJavaDir + System.getProperty("path.separator") + currentPath; |
| 75 | + } |
| 76 | + env.put("PATH", currentPath); |
| 77 | + } |
| 78 | + return env; |
| 79 | + } |
| 80 | + |
| 81 | + private Optional<String> javaHomeFromSyspropOrCurrent() { |
| 82 | + String javaHome = System.getProperty(SPOTLESS_CLI_PROCESS_LAUNCHER_JAVA_HOME); |
| 83 | + if (javaHome != null && !javaHome.isEmpty()) { |
| 84 | + return Optional.of(javaHome); |
| 85 | + } |
| 86 | + String currentJavaBin = currentJavaExecutable(); |
| 87 | + if ("java".equals(currentJavaBin)) { |
| 88 | + return Optional.empty(); // unset |
| 89 | + } |
| 90 | + |
| 91 | + return Optional.of(Path.of(currentJavaBin).getParent().getParent().toString()); |
| 92 | + } |
| 93 | + |
59 | 94 | private String currentJavaExecutable() { |
60 | 95 | return ProcessHandle.current().info().command().orElse("java"); |
61 | 96 | } |
|
0 commit comments