From 824e3f756f964bcb33fc1979dadab5f37ad67b89 Mon Sep 17 00:00:00 2001 From: Martin Panzer Date: Fri, 16 Jul 2021 18:23:58 +0200 Subject: [PATCH] Improve IDE detection * Test more possible cases for idea * correctly add the line argument for idea * Support detection for multi-module projects Fixes: #18676 --- .../java/io/quarkus/deployment/ide/Ide.java | 27 +++++++++++++--- .../quarkus/deployment/ide/IdeProcessor.java | 31 ++++++++++++++----- .../devmode/console/DevConsoleProcessor.java | 2 +- .../devmode/console/OpenIdeHandler.java | 18 ++++++----- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ide/Ide.java b/core/deployment/src/main/java/io/quarkus/deployment/ide/Ide.java index b46f25e54389f0..6894bdbcf3be36 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ide/Ide.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ide/Ide.java @@ -8,19 +8,22 @@ public enum Ide { - IDEA("idea", "--help"), - ECLIPSE("eclipse", (String[]) null), - VSCODE("code", "--version"), - NETBEANS("netbeans", "--help"); + // see for cli syntax of idea https://www.jetbrains.com/help/idea/opening-files-from-command-line.html + IDEA("idea", "--line %s", "--help"), + ECLIPSE("eclipse", null, (String[]) null), + VSCODE("code", null, "--version"), + NETBEANS("netbeans", null, "--help"); private final String defaultCommand; private final List markerArgs; + private final String lineNumberArg; private String machineSpecificCommand; private String effectiveCommand; - Ide(String defaultCommand, String... markerArgs) { + Ide(String defaultCommand, String lineNumberArg, String... markerArgs) { this.defaultCommand = defaultCommand; + this.lineNumberArg = lineNumberArg; this.markerArgs = markerArgs != null ? Arrays.asList(markerArgs) : Collections.emptyList(); } @@ -63,6 +66,20 @@ private String doGetEffectiveCommand() { } } + public List createFileOpeningArgs(String fileName, String line) { + if (line == null || line.isEmpty()) { + return Collections.singletonList(fileName); + } + + if (lineNumberArg == null) { + return Collections.singletonList(fileName + ":" + line); + } + + String formattedLineArg = String.format(lineNumberArg, line); + + return List.of(formattedLineArg, fileName); + } + public void setMachineSpecificCommand(String machineSpecificCommand) { this.machineSpecificCommand = machineSpecificCommand; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ide/IdeProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/ide/IdeProcessor.java index 54b40a1dea2934..18d5ed5daf2aab 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ide/IdeProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ide/IdeProcessor.java @@ -36,7 +36,9 @@ public class IdeProcessor { static { - IDE_PROCESSES.put((processInfo -> processInfo.containInCommand("idea") && processInfo.command.endsWith("java")), + IDE_PROCESSES.put( + (processInfo -> (processInfo.containInCommand("idea") || processInfo.containInCommand("IDEA")) + && (processInfo.command.endsWith("java") || processInfo.command.endsWith("java.exe"))), Ide.IDEA); IDE_PROCESSES.put((processInfo -> processInfo.containInCommand("code")), Ide.VSCODE); IDE_PROCESSES.put((processInfo -> processInfo.containInCommand("eclipse")), Ide.ECLIPSE); @@ -62,9 +64,9 @@ public class IdeProcessor { // into '/home/test/software/idea/ideaIU-203.5981.114/idea-IU-203.5981.114/bin/idea.sh' String command = processInfo.getCommand(); int jbrIndex = command.indexOf("jbr"); - if ((jbrIndex > -1) && command.endsWith("java")) { + if ((jbrIndex > -1) && (command.endsWith("java") || command.endsWith("java.exe"))) { String ideaHome = command.substring(0, jbrIndex); - return (ideaHome + "bin" + File.separator + "idea") + (IdeUtil.isWindows() ? ".exe" : ".sh"); + return (ideaHome + "bin" + File.separator + "idea") + (IdeUtil.isWindows() ? ".bat" : ".sh"); } return null; }); @@ -130,13 +132,26 @@ public IdeFileBuildItem detectIdeFiles(LaunchModeBuildItem launchModeBuildItem, if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { return null; } + Set result = new HashSet<>(2); - Path projectRoot = buildSystemTarget.getOutputDirectory().getParent(); - IDE_MARKER_FILES.forEach((file, ides) -> { - if (Files.exists(projectRoot.resolve(file))) { - result.addAll(ides); + Path root = buildSystemTarget.getOutputDirectory(); + + // hack to try and guess the IDE when using a multi-module project + for (int i = 0; i < 3; i++) { + root = root.getParent(); + for (Map.Entry> entry : IDE_MARKER_FILES.entrySet()) { + String file = entry.getKey(); + List ides = entry.getValue(); + if (Files.exists(root.resolve(file))) { + result.addAll(ides); + } } - }); + + if (!result.isEmpty()) { + break; + } + } + return new IdeFileBuildItem(result); } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java index b0eabe029d0b60..97a950f520351e 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java @@ -827,7 +827,7 @@ public Object apply(EvalContext ctx) { switch (ctxName) { case "srcMainPath": { - return srcMainPath.toAbsolutePath().toString(); + return srcMainPath.toAbsolutePath().toString().replace("\\", "/"); } case "ideLinkType": if (!effectiveIdeBuildItem.isPresent()) { diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java index d09de73c82ed15..351e194ca74c5a 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java @@ -1,7 +1,8 @@ package io.quarkus.vertx.http.deployment.devmode.console; import java.io.File; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -48,11 +49,9 @@ protected void dispatch(RoutingContext routingContext, MultiMap form) { private void typicalProcessLaunch(RoutingContext routingContext, String className, String lang, String srcMainPath, String line, Ide ide) { - String arg = toFileName(className, lang, srcMainPath); - if (!isNullOrEmpty(line)) { - arg = arg + ":" + line; - } - launchInIDE(ide, arg, routingContext); + String fileName = toFileName(className, lang, srcMainPath); + List args = ide.createFileOpeningArgs(fileName, line); + launchInIDE(routingContext, ide, args); } private String toFileName(String className, String lang, String srcMainPath) { @@ -68,7 +67,7 @@ private String toFileName(String className, String lang, String srcMainPath) { } - protected void launchInIDE(Ide ide, String arg, RoutingContext routingContext) { + protected void launchInIDE(RoutingContext routingContext, Ide ide, List args) { new Thread(new Runnable() { public void run() { try { @@ -78,7 +77,10 @@ public void run() { routingContext.response().setStatusCode(500).end(); return; } - new ProcessBuilder(Arrays.asList(effectiveCommand, arg)).inheritIO().start().waitFor(10, + List command = new ArrayList<>(); + command.add(effectiveCommand); + command.addAll(args); + new ProcessBuilder(command).inheritIO().start().waitFor(10, TimeUnit.SECONDS); routingContext.response().setStatusCode(200).end(); } catch (Exception e) {