Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VsCode debug support #30

Merged
merged 19 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
api "io.codechicken:DiffPatch:${project.diffpatch_version}"
api "commons-codec:commons-codec:${project.commons_codec_version}"
api "net.neoforged:EclipseLaunchConfigs:${project.eclipse_launch_configs_version}"
api "net.neoforged:VscLaunchConfigs:${project.vscode_launch_configs_version}"
api "net.neoforged:JarJarMetadata:${project.jarjar_version}"
api "net.neoforged:JarJarSelector:${project.jarjar_version}"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.jetbrains.gradle.ext.ProjectSettings;
import org.jetbrains.gradle.ext.TaskTriggersConfig;

import java.util.function.BiConsumer;
import javax.inject.Inject;

/**
Expand Down Expand Up @@ -74,13 +75,37 @@ public boolean isEclipseImport() {
return System.getProperty("eclipse.application") != null;
}

/**
* Checks whether Gradle is being invoked:
* - from Eclipse plugin and the plugin is sourced from RedHat VSCode extension
* - from VSCode Microsoft Gradle plugin
*
* @return true if should rather perform VsCode setup instead of Eclipse setup.
*/
public boolean isVscodeImport()
{
final boolean isNativeEclipse = isEclipseImport() && System.getProperty("eclipse.home.location", "").contains("redhat.java");
return isNativeEclipse || isVscodePluginImport(project);
}

/**
* Checks whether Gradle is being invoked from VSCode Microsoft Gradle plugin
*
* @return true if must perform VsCode setup instead of Eclipse setup.
* @implNote reinvestigate after https://github.com/microsoft/vscode-java-debug/issues/1106
*/
public static boolean isVscodePluginImport(final Project project)
{
return project.getPlugins().stream().anyMatch(p -> p.getClass().getName().equals("com.microsoft.gradle.GradlePlugin"));
}

/**
* Indicates if an IDE import in any of the supported IDEs is ongoing.
*
* @return {@code true} if an IDE import is ongoing, {@code false} otherwise
*/
public boolean isIdeImportInProgress() {
return isIdeaImport() || isEclipseImport();
return isIdeaImport() || isEclipseImport() || isVscodeImport();
}

/**
Expand Down Expand Up @@ -124,6 +149,12 @@ public void eclipse(Project project, EclipseModel eclipse) {
//Register the task to run after the Eclipse import is complete, via its build-in support.
eclipse.synchronizationTasks(idePostSyncTask);
}

@Override
public void vscode(Project project, EclipseModel eclipse) {
// vscode ~= eclipse
eclipse(project, eclipse);
}
});
}
else {
Expand All @@ -143,7 +174,9 @@ public void eclipse(Project project, EclipseModel eclipse) {
*/
public void apply(final IdeImportAction toPerform) {
onIdea(toPerform);
onEclipse(toPerform);
// since vscode and eclipse shares EclipseModel import only one of them
if (isVscodeImport()) onVscode(toPerform);
else onEclipse(toPerform);
onGradle(toPerform);
}

Expand Down Expand Up @@ -182,7 +215,15 @@ public void onIdea(final IdeaIdeImportAction toPerform) {
toPerform.idea(project, model, ideaExt);
});
}


public void onEclipse(final EclipseIdeImportAction toPerform) {
onCommonEclipse(toPerform::eclipse);
}

public void onVscode(final VscodeIdeImportAction toPerform) {
onCommonEclipse(toPerform::vscode);
}

/**
* Applies the specified configuration action to configure eclipse IDE projects only.
*
Expand All @@ -191,7 +232,7 @@ public void onIdea(final IdeaIdeImportAction toPerform) {
*
* @param toPerform the actions to perform
*/
public void onEclipse(final EclipseIdeImportAction toPerform) {
private void onCommonEclipse(final BiConsumer<Project, EclipseModel> toPerform) {
//When the Eclipse plugin is available, configure it
project.getPlugins().withType(EclipsePlugin.class, plugin -> {
//Do not configure the eclipse plugin if we are not importing.
Expand All @@ -204,11 +245,13 @@ public void onEclipse(final EclipseIdeImportAction toPerform) {
EclipseModel model = project.getExtensions().findByType(EclipseModel.class);
if (model == null) {
model = rootProject.getExtensions().findByType(EclipseModel.class);
return;
if (model == null) {
return;
}
}

//Configure the project, passing the model and the relevant project. Which does not need to be the root, but can be.
toPerform.eclipse(project, model);
toPerform.accept(project, model);
});
}

Expand All @@ -218,7 +261,7 @@ public void onEclipse(final EclipseIdeImportAction toPerform) {
* @param toPerform the actions to perform
*/
public void onGradle(final GradleIdeImportAction toPerform) {
if (!isEclipseImport() && !isIdeaImport()) {
if (!isEclipseImport() && !isIdeaImport() && !isVscodeImport()) {
toPerform.gradle(project);
}
}
Expand Down Expand Up @@ -262,8 +305,22 @@ public interface EclipseIdeImportAction {
void eclipse(Project project, EclipseModel eclipse);
}

/**
* A configuration action for vscode IDE projects.
*/
public interface VscodeIdeImportAction {

/**
* Configure an vscode project.
*
* @param project the project being imported
* @param eclipse the eclipse project model to modify
*/
void vscode(Project project, EclipseModel eclipse);
}

/**
* A configuration action for IDE projects.
*/
public interface IdeImportAction extends IdeaIdeImportAction, EclipseIdeImportAction, GradleIdeImportAction { }
public interface IdeImportAction extends IdeaIdeImportAction, EclipseIdeImportAction, VscodeIdeImportAction, GradleIdeImportAction { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
import net.neoforged.gradle.dsl.common.runs.run.Run;
import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils;
import net.neoforged.gradle.util.FileUtils;
import net.neoforged.vsclc.BatchedLaunchWriter;
import net.neoforged.vsclc.LaunchConfiguration;
import net.neoforged.vsclc.attribute.PathLike;
import net.neoforged.vsclc.attribute.ShortCmdBehaviour;
import net.neoforged.vsclc.writer.WritingMode;
import org.apache.commons.lang3.StringUtils;
import org.gradle.api.Action;
import org.gradle.api.NamedDomainObjectContainer;
Expand Down Expand Up @@ -218,6 +223,47 @@ public void eclipse(Project project, EclipseModel eclipse) {
});
}

@Override
public void vscode(Project project, EclipseModel eclipse)
{
ProjectUtils.afterEvaluate(project, () -> {
final BatchedLaunchWriter launchWriter = new BatchedLaunchWriter(WritingMode.MODIFY_CURRENT);
project.getExtensions().configure(RunsConstants.Extensions.RUNS, (Action<NamedDomainObjectContainer<Run>>) runs -> runs.getAsMap().forEach((name, run) -> {
final String runName = StringUtils.capitalize(project.getName() + " - " + StringUtils.capitalize(name.replace(" ", "-")));
final RunImpl runImpl = (RunImpl) run;
final TaskProvider<?> ideBeforeRunTask = createIdeBeforeRunTask(project, name, run, runImpl);

final List<TaskProvider<?>> copyProcessResourcesTasks = createEclipseCopyResourcesTasks(eclipse, run);
ideBeforeRunTask.configure(task -> copyProcessResourcesTasks.forEach(t -> task.dependsOn(t)));

final LaunchConfiguration cfg = launchWriter.createGroup("NG - " + project.getName(), WritingMode.REMOVE_EXISTING)
.createLaunchConfiguration()
.withAdditionalJvmArgs(runImpl.realiseJvmArguments())
.withArguments(runImpl.getProgramArguments().get())
.withCurrentWorkingDirectory(PathLike.ofNio(runImpl.getWorkingDirectory().get().getAsFile().toPath()))
.withEnvironmentVariables(adaptEnvironment(runImpl, RunsUtil::buildRunWithEclipseModClasses))
.withShortenCommandLine(ShortCmdBehaviour.ARGUMENT_FILE)
.withMainClass(runImpl.getMainClass().get())
.withProjectName(project.getName())
.withName(runName);

if (IdeManagementExtension.isVscodePluginImport(project))
{
cfg.withPreTaskName("gradle: " + ideBeforeRunTask.getName());
}
else
{
eclipse.autoBuildTasks(ideBeforeRunTask);
}
}));
try {
launchWriter.writeToLatestJson(project.getRootDir().toPath());
} catch (final IOException e) {
throw new RuntimeException("Failed to write launch files", e);
}
});
}

private static String quoteAndJoin(List<String> args) {
return quoteStream(args).collect(Collectors.joining(" "));
}
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jetbrains_annotations_version=23.0.0
gradle_idea_extension_version=1.1.6
groovy_dsl_improver_version=1.0.15
eclipse_launch_configs_version=0.1.3
vscode_launch_configs_version=1.0.8

#Test dependencies
junit_version=5.9.2
Expand Down
Loading