Add cross-platform IDEA launch commands

This commit is contained in:
张家训
2026-08-03 15:05:04 +08:00
parent 888922953c
commit 0384efae28
4 changed files with 112 additions and 9 deletions
@@ -337,15 +337,10 @@ public class GitReviewService {
private boolean startIdea(String ideaCommand, List<String> args, LogSink logs) {
List<String> configured = splitCommandLine(ideaCommand);
List<String> candidates = configured.isEmpty()
? Arrays.asList("idea64.exe", "idea.bat", "idea")
: Collections.singletonList(String.join(" ", configured));
List<List<String>> candidates = IdeaLaunchCommands.candidates(
IdeaLaunchCommands.currentOperatingSystem(), configured, args);
for (String candidate : candidates) {
List<String> command = configured.isEmpty()
? new ArrayList<>(Collections.singletonList(candidate))
: new ArrayList<>(configured);
command.addAll(args);
for (List<String> command : candidates) {
if (startProcess(command)) {
return true;
}
@@ -219,7 +219,8 @@ public class GitReviewWindow {
projectValueLabel = valueLabel();
sourceBranchValueLabel = valueLabel();
targetBranchValueLabel = valueLabel();
ideaCommandField = textField("idea64.exe");
ideaCommandField = textField("");
ideaCommandField.setPromptText("自动检测");
HBox ideaBox = new HBox(Theme.S2, ideaCommandField, smallButton("选择...", this::chooseIdeaCommand));
HBox.setHgrow(ideaCommandField, Priority.ALWAYS);
@@ -0,0 +1,53 @@
package com.example.workutils.biz.gitreview;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
final class IdeaLaunchCommands {
enum OperatingSystem { WINDOWS, MAC, LINUX }
private IdeaLaunchCommands() {
}
static OperatingSystem currentOperatingSystem() {
return detect(System.getProperty("os.name", ""));
}
static OperatingSystem detect(String osName) {
String normalized = osName.toLowerCase(Locale.ROOT);
if (normalized.contains("win")) {
return OperatingSystem.WINDOWS;
}
if (normalized.contains("mac")) {
return OperatingSystem.MAC;
}
return OperatingSystem.LINUX;
}
static List<List<String>> candidates(
OperatingSystem operatingSystem,
List<String> configured,
List<String> projectArguments) {
if (!configured.isEmpty()) {
return List.of(append(configured, projectArguments));
}
return switch (operatingSystem) {
case WINDOWS -> List.of(
append(List.of("idea64.exe"), projectArguments),
append(List.of("idea.bat"), projectArguments),
append(List.of("idea"), projectArguments));
case MAC -> List.of(
append(List.of("idea"), projectArguments),
append(List.of("open", "-a", "IntelliJ IDEA"), projectArguments));
case LINUX -> List.of(append(List.of("idea"), projectArguments));
};
}
private static List<String> append(List<String> command, List<String> arguments) {
List<String> result = new ArrayList<>(command);
result.addAll(arguments);
return List.copyOf(result);
}
}
@@ -0,0 +1,54 @@
package com.example.workutils.biz.gitreview;
import org.junit.jupiter.api.Test;
import java.util.List;
import static com.example.workutils.biz.gitreview.IdeaLaunchCommands.OperatingSystem.LINUX;
import static com.example.workutils.biz.gitreview.IdeaLaunchCommands.OperatingSystem.MAC;
import static com.example.workutils.biz.gitreview.IdeaLaunchCommands.OperatingSystem.WINDOWS;
import static org.junit.jupiter.api.Assertions.assertEquals;
class IdeaLaunchCommandsTest {
@Test
void macUsesCliThenOpenApplicationFallback() {
List<List<String>> commands = IdeaLaunchCommands.candidates(
MAC, List.of(), List.of("/项目 空间/demo"));
assertEquals(List.of("idea", "/项目 空间/demo"), commands.get(0));
assertEquals(List.of("open", "-a", "IntelliJ IDEA", "/项目 空间/demo"), commands.get(1));
}
@Test
void windowsTriesExeBatchAndPathCommands() {
List<List<String>> commands = IdeaLaunchCommands.candidates(
WINDOWS, List.of(), List.of("D:/项目 空间"));
assertEquals(List.of("idea64.exe", "D:/项目 空间"), commands.get(0));
assertEquals(List.of("idea.bat", "D:/项目 空间"), commands.get(1));
assertEquals(List.of("idea", "D:/项目 空间"), commands.get(2));
}
@Test
void linuxUsesIdeaFromPath() {
assertEquals(List.of(List.of("idea", "/项目 空间")),
IdeaLaunchCommands.candidates(LINUX, List.of(), List.of("/项目 空间")));
}
@Test
void configuredCommandAlwaysWinsAndRetainsArgumentBoundaries() {
assertEquals(
List.of(List.of("/Applications/IntelliJ IDEA.app/Contents/MacOS/idea", "--wait", "/项目 空间")),
IdeaLaunchCommands.candidates(MAC,
List.of("/Applications/IntelliJ IDEA.app/Contents/MacOS/idea", "--wait"),
List.of("/项目 空间")));
}
@Test
void operatingSystemNamesAreDetectedCaseInsensitively() {
assertEquals(WINDOWS, IdeaLaunchCommands.detect("Windows 11"));
assertEquals(MAC, IdeaLaunchCommands.detect("Mac OS X"));
assertEquals(LINUX, IdeaLaunchCommands.detect("Linux"));
}
}