Skip to content

Commit

Permalink
fix: Debug run config invalid with Gradle
Browse files Browse the repository at this point in the history
Fixes #1311

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Sep 16, 2024
1 parent e246f7f commit eba23f0
Show file tree
Hide file tree
Showing 12 changed files with 459 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
******************************************************************************/
package com.redhat.devtools.intellij.quarkus.buildtool;

import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
Expand All @@ -21,6 +22,7 @@
import com.intellij.util.messages.MessageBusConnection;
import com.redhat.devtools.intellij.quarkus.run.QuarkusRunConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenId;

import java.io.File;
Expand Down Expand Up @@ -179,7 +181,9 @@ public static BuildToolDelegate[] getDelegates() {
return delegates;
}

RunnerAndConfigurationSettings getConfigurationDelegate(Module module, QuarkusRunConfiguration configuration);
RunnerAndConfigurationSettings getConfigurationDelegate(@NotNull Module module,
@NotNull QuarkusRunConfiguration configuration,
@Nullable Integer debugPort);

/**
* Add project import listener.
Expand All @@ -189,4 +193,9 @@ public static BuildToolDelegate[] getDelegates() {
* @param listener the project import listener.
*/
void addProjectImportListener(@NotNull Project project, @NotNull MessageBusConnection connection, @NotNull ProjectImportListener listener);

@Nullable
default Executor getOverridedExecutor() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
******************************************************************************/
package com.redhat.devtools.intellij.quarkus.buildtool.gradle;

import com.intellij.execution.Executor;
import com.intellij.execution.ExecutorRegistry;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
Expand Down Expand Up @@ -38,6 +40,7 @@
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.projectImport.ProjectImportBuilder;
import com.intellij.projectImport.ProjectImportProvider;
import com.intellij.util.concurrency.NonUrgentExecutor;
Expand Down Expand Up @@ -358,12 +361,14 @@ private ProjectImportProvider getGradleProjectImportProvider() {
}

@Override
public RunnerAndConfigurationSettings getConfigurationDelegate(Module module, QuarkusRunConfiguration configuration) {
public RunnerAndConfigurationSettings getConfigurationDelegate(@NotNull Module module,
@NotNull QuarkusRunConfiguration configuration,
@Nullable Integer debugPort) {
RunnerAndConfigurationSettings settings = RunManager.getInstance(module.getProject()).createConfiguration(module.getName() + " Quarkus (Gradle)", GradleExternalTaskConfigurationType.class);
GradleRunConfiguration gradleConfiguration = (GradleRunConfiguration) settings.getConfiguration();
gradleConfiguration.getSettings().getTaskNames().add("quarkusDev");
gradleConfiguration.getSettings().setEnv(configuration.getEnv());
String parameters = "-Ddebug=" + configuration.getPort();
String parameters = debugPort != null ? ("-Ddebug=" + Integer.toString(debugPort)) : "";
if (StringUtils.isNotBlank(configuration.getProfile())) {
parameters += " -Dquarkus.profile=" + configuration.getProfile();
}
Expand Down Expand Up @@ -407,4 +412,9 @@ private static boolean isValidGradleModule(Module module) {
String name = module.getName();
return !(name.endsWith(".integrationTest") || name.endsWith(".native-test") || name.endsWith(".test"));
}

@Override
public @Nullable Executor getOverridedExecutor() {
return ExecutorRegistry.getInstance().getExecutorById(ToolWindowId.RUN);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.redhat.devtools.intellij.quarkus.buildtool.gradle;

import com.intellij.build.BuildView;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.runners.RunContentBuilder;
import com.intellij.execution.testframework.HistoryTestRunnableState;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunnableState;
import com.redhat.devtools.intellij.quarkus.buildtool.BuildToolDelegate;
import com.redhat.devtools.intellij.quarkus.buildtool.maven.MavenToolDelegate;
import com.redhat.devtools.intellij.quarkus.run.QuarkusRunConfiguration;
import org.jetbrains.concurrency.Promises;

/**
* Program runner to run/debug a Gradle configuration.
* <p>
* This class is a copy/paste from the Intellij
* <a href="https://github.com/JetBrains/intellij-community/blob/master/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.kt">ExternalSystemTaskRunner</a>
* since this class cannot be extended.
*/
public class GradleRunAndDebugProgramRunner implements ProgramRunner<RunnerSettings> {

private static final String RUNNER_ID = "QuarkusExternalSystemTaskRunner";

@Override
public String getRunnerId() {
return RUNNER_ID;
}

@Override
public boolean canRun(String executorId, RunProfile profile) {
if (profile instanceof QuarkusRunConfiguration quarkusRunConfiguration) {
BuildToolDelegate delegate = BuildToolDelegate.getDelegate(quarkusRunConfiguration.getModule());
return !(delegate instanceof MavenToolDelegate);
}
return false;
}

@Override
public void execute(ExecutionEnvironment environment) throws ExecutionException {
RunProfileState state = environment.getState();
if (state == null) {
return;
}
ExecutionManager.getInstance(environment.getProject()).startRunProfile(environment, () -> {
try {
return Promises.resolvedPromise(doExecute(state, environment));
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
});
}

private RunContentDescriptor doExecute(RunProfileState state, ExecutionEnvironment environment) throws ExecutionException {
if (!(state instanceof ExternalSystemRunnableState) && !(state instanceof HistoryTestRunnableState)) {
return null;
}

RunContentDescriptor runContentDescriptor;
ExecutionResult executionResult = state.execute(environment.getExecutor(), this);
if (executionResult == null) {
return null;
}
runContentDescriptor = new RunContentBuilder(executionResult, environment).showRunContent(environment.getContentToReuse());
if (runContentDescriptor == null) {
return null;
}

if (state instanceof HistoryTestRunnableState) {
return runContentDescriptor;
}

((ExternalSystemRunnableState) state).setContentDescriptor(runContentDescriptor);

if (executionResult.getExecutionConsole() instanceof BuildView) {
return runContentDescriptor;
}

RunContentDescriptor descriptor = new RunContentDescriptor(
runContentDescriptor.getExecutionConsole(),
runContentDescriptor.getProcessHandler(),
runContentDescriptor.getComponent(),
runContentDescriptor.getDisplayName(),
runContentDescriptor.getIcon(),
null,
runContentDescriptor.getRestartActions()
) {
@Override
public boolean isHiddenContent() {
return true;
}
};
descriptor.setRunnerLayoutUi(runContentDescriptor.getRunnerLayoutUi());
return descriptor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.redhat.devtools.intellij.quarkus.run.QuarkusRunConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.execution.MavenRunConfiguration;
import org.jetbrains.idea.maven.execution.MavenRunConfigurationType;
import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
Expand All @@ -39,7 +40,6 @@
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.server.MavenEmbedderWrapper;
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
import org.jetbrains.idea.maven.utils.MavenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -260,7 +260,7 @@ private MavenEmbedderWrapper createEmbedderWrapper(Project project, String worki
}

@Override
public RunnerAndConfigurationSettings getConfigurationDelegate(Module module, QuarkusRunConfiguration configuration) {
public RunnerAndConfigurationSettings getConfigurationDelegate(Module module, QuarkusRunConfiguration configuration, @Nullable Integer debugPort) {
RunnerAndConfigurationSettings settings = RunManager.getInstance(module.getProject()).createConfiguration(module.getName() + " Quarkus (Maven)", MavenRunConfigurationType.class);
MavenRunConfiguration mavenConfiguration = (MavenRunConfiguration) settings.getConfiguration();
mavenConfiguration.getRunnerParameters().setResolveToWorkspace(true);
Expand All @@ -271,7 +271,9 @@ public RunnerAndConfigurationSettings getConfigurationDelegate(Module module, Qu
if (StringUtils.isNotBlank(configuration.getProfile())) {
mavenConfiguration.getRunnerSettings().getMavenProperties().put("quarkus.profile", configuration.getProfile());
}
mavenConfiguration.getRunnerSettings().getMavenProperties().put("debug", Integer.toString(configuration.getPort()));
if (debugPort != null) {
mavenConfiguration.getRunnerSettings().getMavenProperties().put("debug", Integer.toString(debugPort));
}
mavenConfiguration.setBeforeRunTasks(configuration.getBeforeRunTasks());
return settings;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.devtools.intellij.quarkus.buildtool.maven;

import com.intellij.debugger.impl.GenericDebuggerRunner;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.redhat.devtools.intellij.quarkus.buildtool.BuildToolDelegate;
import com.redhat.devtools.intellij.quarkus.run.QuarkusRunConfiguration;
import org.jetbrains.annotations.NotNull;

/**
* Program runner to debug a Maven configuration.
*/
public class QuarkusMavenDebugProgramRunner extends GenericDebuggerRunner {

private static final String RUNNER_ID = "QuarkusMavenDebugProgramRunner";

@Override
public String getRunnerId() {
return RUNNER_ID;
}

@Override
public boolean canRun(@NotNull final String executorId, @NotNull final RunProfile profile) {
if (!executorId.equals(DefaultDebugExecutor.EXECUTOR_ID)) {
return false;
}
if (profile instanceof QuarkusRunConfiguration quarkusRunConfiguration) {
BuildToolDelegate delegate = BuildToolDelegate.getDelegate(quarkusRunConfiguration.getModule());
return (delegate instanceof MavenToolDelegate);
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.devtools.intellij.quarkus.buildtool.maven;

import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.impl.DefaultJavaProgramRunner;
import com.redhat.devtools.intellij.quarkus.buildtool.BuildToolDelegate;
import com.redhat.devtools.intellij.quarkus.run.QuarkusRunConfiguration;

/**
* Program runner to run a Maven configuration.
*/
public class QuarkusMavenRunProgramRunner extends DefaultJavaProgramRunner {

private static final String RUNNER_ID = "QuarkusMavenRunProgramRunner";

@Override
public String getRunnerId() {
return RUNNER_ID;
}

@Override
public boolean canRun(String executorId, RunProfile profile) {
if (!executorId.equals(DefaultRunExecutor.EXECUTOR_ID)) {
return false;
}
if (profile instanceof QuarkusRunConfiguration quarkusRunConfiguration) {
BuildToolDelegate delegate = BuildToolDelegate.getDelegate(quarkusRunConfiguration.getModule());
return (delegate instanceof MavenToolDelegate);
}
return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.redhat.devtools.intellij.quarkus.run;

import com.intellij.execution.ExecutionListener;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

class AttachDebuggerExecutionListener implements ExecutionListener {

private final @NotNull Project project;

AttachDebuggerExecutionListener(@NotNull Project project) {
this.project = project;
}

public void processStarting(@NotNull String executorId,
@NotNull ExecutionEnvironment env,
@NotNull ProcessHandler handler) {
if (!DefaultDebugExecutor.EXECUTOR_ID.equals(executorId)) {
return;
}
RunnerAndConfigurationSettings settings = env.getRunnerAndConfigurationSettings();
if (settings != null && settings.getConfiguration() instanceof QuarkusRunConfiguration) {
handler.addProcessListener(new AttachDebuggerProcessListener(project, env));
}
}

}
Loading

0 comments on commit eba23f0

Please sign in to comment.