From 887bfe62ab4f83b7f65cb45a2015444db4e36732 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Thu, 16 Oct 2025 13:08:55 +0200 Subject: [PATCH] Execute Idea synchronization task in the current Gradle execution --- .../gradle/vanilla/VanillaGradle.java | 35 ++------ .../internal/ProvideMinecraftPlugin.java | 46 +++++----- .../internal/ide/EclipseIntegration.java | 65 ++++++++++++++ .../IdeaIntegration.java} | 84 +++++++++---------- 4 files changed, 131 insertions(+), 99 deletions(-) create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/EclipseIntegration.java rename subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/{util/IdeConfigurer.java => ide/IdeaIntegration.java} (58%) diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/VanillaGradle.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/VanillaGradle.java index 121fef5f..b3e7cb23 100644 --- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/VanillaGradle.java +++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/VanillaGradle.java @@ -31,28 +31,22 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.initialization.Settings; -import org.gradle.api.plugins.ExtensionAware; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskProvider; import org.gradle.plugins.ide.eclipse.EclipsePlugin; -import org.gradle.plugins.ide.eclipse.model.EclipseModel; -import org.gradle.plugins.ide.idea.model.IdeaModel; import org.jetbrains.gradle.ext.IdeaExtPlugin; -import org.jetbrains.gradle.ext.ProjectSettings; -import org.jetbrains.gradle.ext.TaskTriggersConfig; import org.spongepowered.gradle.vanilla.internal.Constants; import org.spongepowered.gradle.vanilla.internal.MinecraftExtensionImpl; import org.spongepowered.gradle.vanilla.internal.ProvideMinecraftPlugin; import org.spongepowered.gradle.vanilla.internal.ResolveMinecraftLibNames; import org.spongepowered.gradle.vanilla.internal.ShadowConfigurationApplier; +import org.spongepowered.gradle.vanilla.internal.ide.EclipseIntegration; +import org.spongepowered.gradle.vanilla.internal.ide.IdeaIntegration; import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService; import org.spongepowered.gradle.vanilla.internal.repository.MinecraftRepositoryPlugin; import org.spongepowered.gradle.vanilla.internal.util.ConfigurationUtils; -import org.spongepowered.gradle.vanilla.internal.util.IdeConfigurer; import org.spongepowered.gradle.vanilla.internal.util.SelfPreferringClassLoader; import org.spongepowered.gradle.vanilla.task.DisplayMinecraftVersionsTask; import org.spongepowered.gradle.vanilla.task.DumpClassTask; @@ -64,8 +58,10 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; import java.util.stream.Stream; /** @@ -168,26 +164,9 @@ private void configureIDEIntegrations( project.getPlugins().apply(IdeaExtPlugin.class); project.getPlugins().apply(EclipsePlugin.class); - IdeConfigurer.apply(project, new IdeConfigurer.IdeImportAction() { - @Override - public void idea(final Project project, final IdeaModel idea, final ProjectSettings ideaExtension) { - // Navigate via the extension properties... - // https://github.com/JetBrains/gradle-idea-ext-plugin/wiki - final TaskTriggersConfig taskTriggers = ((ExtensionAware) ideaExtension).getExtensions().getByType(TaskTriggersConfig.class); - - // Automatically prepare a workspace after importing - if (shouldRunPrepare.get()) { - taskTriggers.afterSync(prepareWorkspaceTask); - } - } - - @Override - public void eclipse(final Project project, final EclipseModel eclipse) { - if (shouldRunPrepare.get()) { - eclipse.synchronizationTasks(prepareWorkspaceTask); - } - } - }); + final Supplier>> supplier = () -> shouldRunPrepare.get() ? Optional.of(prepareWorkspaceTask) : Optional.empty(); + IdeaIntegration.addSynchronizationTask(project, supplier); + EclipseIntegration.addSynchronizationTask(project, supplier); } private static void applyShadowConfiguration(final TaskContainer tasks, final Provider> minecraftNames, final Plugin shadowPlugin) { diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ProvideMinecraftPlugin.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ProvideMinecraftPlugin.java index 51dd73c0..21d6211a 100644 --- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ProvideMinecraftPlugin.java +++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ProvideMinecraftPlugin.java @@ -56,18 +56,16 @@ import org.gradle.api.tasks.TaskProvider; import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.jvm.toolchain.JavaToolchainService; -import org.gradle.plugins.ide.eclipse.model.EclipseModel; -import org.gradle.plugins.ide.idea.model.IdeaModel; import org.jetbrains.gradle.ext.Application; -import org.jetbrains.gradle.ext.ProjectSettings; import org.jetbrains.gradle.ext.RunConfigurationContainer; import org.spongepowered.gradle.vanilla.MinecraftExtension; +import org.spongepowered.gradle.vanilla.internal.ide.EclipseIntegration; +import org.spongepowered.gradle.vanilla.internal.ide.IdeaIntegration; import org.spongepowered.gradle.vanilla.internal.model.Library; import org.spongepowered.gradle.vanilla.internal.model.rule.OperatingSystemRule; import org.spongepowered.gradle.vanilla.internal.model.rule.RuleContext; import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService; import org.spongepowered.gradle.vanilla.internal.repository.MinecraftRepositoryPlugin; -import org.spongepowered.gradle.vanilla.internal.util.IdeConfigurer; import org.spongepowered.gradle.vanilla.internal.util.StringUtils; import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform; import org.spongepowered.gradle.vanilla.repository.MinecraftRepositoryExtension; @@ -79,6 +77,7 @@ import java.io.File; import java.util.Iterator; import java.util.Objects; +import java.util.Optional; /** * A plugin that creates the necessary tasks and configurations to provide the @@ -331,33 +330,26 @@ private void configureIDEIntegrations( final Project project, final MinecraftExtensionImpl extension ) { - IdeConfigurer.apply(project, new IdeConfigurer.IdeImportAction() { - @Override - public void idea(final Project project, final IdeaModel idea, final ProjectSettings ideaExtension) { - final RunConfigurationContainer runConfigurations = + IdeaIntegration.apply(project, (idea, ideaExtension) -> { + final RunConfigurationContainer runConfigurations = (RunConfigurationContainer) ((ExtensionAware) ideaExtension).getExtensions().getByName("runConfigurations"); - extension.getRuns().all(run -> { - final String displayName = run.getDisplayName().getOrNull(); - runConfigurations.create(displayName == null ? run.getName() + " (" + project.getName() + ")" : displayName, Application.class, ideaRun -> { - ideaRun.setMainClass(run.getMainClass().get()); - final File runDirectory = run.getWorkingDirectory().get().getAsFile(); - ideaRun.setWorkingDirectory(runDirectory.getAbsolutePath()); - runDirectory.mkdirs(); - - ideaRun.moduleRef(project, run.getIdeaRunSourceSet().orElse(run.getSourceSet()).get()); - ideaRun.setJvmArgs(StringUtils.join(run.getAllJvmArgumentProviders(), true)); - ideaRun.setProgramParameters(StringUtils.join(run.getAllArgumentProviders(), true)); - ideaRun.setEnvs(run.getActualEnvironment()); - }); + extension.getRuns().all(run -> { + final String displayName = run.getDisplayName().getOrNull(); + runConfigurations.create(displayName == null ? run.getName() + " (" + project.getName() + ")" : displayName, Application.class, ideaRun -> { + ideaRun.setMainClass(run.getMainClass().get()); + final File runDirectory = run.getWorkingDirectory().get().getAsFile(); + ideaRun.setWorkingDirectory(runDirectory.getAbsolutePath()); + runDirectory.mkdirs(); + + ideaRun.moduleRef(project, run.getIdeaRunSourceSet().orElse(run.getSourceSet()).get()); + ideaRun.setJvmArgs(StringUtils.join(run.getAllJvmArgumentProviders(), true)); + ideaRun.setProgramParameters(StringUtils.join(run.getAllArgumentProviders(), true)); + ideaRun.setEnvs(run.getActualEnvironment()); }); - } - - @Override - public void eclipse(final Project project, final EclipseModel eclipse) { - eclipse.synchronizationTasks(project.getTasks().named(Constants.Tasks.GEN_ECLIPSE_RUNS)); - } + }); }); + EclipseIntegration.addSynchronizationTask(project, () -> Optional.of(project.getTasks().named(Constants.Tasks.GEN_ECLIPSE_RUNS))); } private void createRunTasks(final MinecraftExtension extension, final TaskContainer tasks, final JavaToolchainService service) { diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/EclipseIntegration.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/EclipseIntegration.java new file mode 100644 index 00000000..c5efea78 --- /dev/null +++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/EclipseIntegration.java @@ -0,0 +1,65 @@ +/* + * This file is part of VanillaGradle, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.gradle.vanilla.internal.ide; + +import org.gradle.api.Project; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.plugins.ide.eclipse.EclipsePlugin; +import org.gradle.plugins.ide.eclipse.model.EclipseModel; + +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public final class EclipseIntegration { + + /** + * Applies the specified configuration action to configure Eclipse projects. + * + *

This does not apply the Eclipse plugin, but will perform the action when the plugin is applied.

+ * + * @param project project to apply to + * @param action the action to perform + */ + public static void apply(final Project project, final Consumer action) { + project.getPlugins().withType(EclipsePlugin.class, plugin -> { + final EclipseModel model = project.getExtensions().findByType(EclipseModel.class); + if (model == null) { + return; + } + action.accept(model); + }); + } + + /** + * Executes a task when Eclipse performs a project synchronization. + * + * @param project project of the task + * @param supplier supplier that may provide a task + */ + public static void addSynchronizationTask(final Project project, final Supplier>> supplier) { + EclipseIntegration.apply(project, (eclipseModel -> supplier.get().ifPresent(eclipseModel::synchronizationTasks))); + } +} diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/util/IdeConfigurer.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/IdeaIntegration.java similarity index 58% rename from subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/util/IdeConfigurer.java rename to subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/IdeaIntegration.java index fe637dcf..e82d4b9d 100644 --- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/util/IdeConfigurer.java +++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/ide/IdeaIntegration.java @@ -22,20 +22,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.gradle.vanilla.internal.util; +package org.spongepowered.gradle.vanilla.internal.ide; +import org.gradle.StartParameter; +import org.gradle.TaskExecutionRequest; import org.gradle.api.Project; import org.gradle.api.plugins.ExtensionAware; -import org.gradle.plugins.ide.eclipse.EclipsePlugin; -import org.gradle.plugins.ide.eclipse.model.EclipseModel; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.internal.DefaultTaskExecutionRequest; import org.gradle.plugins.ide.idea.model.IdeaModel; import org.jetbrains.gradle.ext.IdeaExtPlugin; import org.jetbrains.gradle.ext.ProjectSettings; -/** - * Configures different IDEs when applicable - */ -public final class IdeConfigurer { +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + +public final class IdeaIntegration { /** * Get whether Gradle is being invoked through IntelliJ IDEA. @@ -44,31 +50,30 @@ public final class IdeConfigurer { * * @return whether this is an IntelliJ-based invocation */ - public static boolean isIdeaImport() { + public static boolean isIdea() { return Boolean.getBoolean("idea.active"); } /** - * Get whether this Gradle invocation is from an Eclipse project import. + * Get whether Gradle is being invoked through IntelliJ IDEA project synchronization. * - * @return whether an eclipse import is ongoing + * @return whether this is an IntelliJ-based synchronization */ - public static boolean isEclipseImport() { - return System.getProperty("eclipse.application") != null; + public static boolean isIdeaSync() { + return Boolean.getBoolean("idea.sync.active"); } /** - * Applies the specified configuration action to configure IDE projects. + * Applies the specified configuration action to configure Idea projects. * - *

This does not apply the IDEs' respective plugins, but will perform - * actions when those plugins are applied.

+ *

This does not apply the Idea plugin, but will perform the action when the plugin is applied.

* * @param project project to apply to - * @param toPerform the actions to perform + * @param action the action to perform */ - public static void apply(final Project project, final IdeImportAction toPerform) { + public static void apply(final Project project, final BiConsumer action) { project.getPlugins().withType(IdeaExtPlugin.class, plugin -> { - if (!IdeConfigurer.isIdeaImport()) { + if (!IdeaIntegration.isIdea()) { return; } @@ -84,36 +89,27 @@ public static void apply(final Project project, final IdeImportAction toPerform) final ProjectSettings ideaExt = ((ExtensionAware) model.getProject()).getExtensions().getByType(ProjectSettings.class); // But actually perform the configuration with the subproject context - toPerform.idea(project, model, ideaExt); - }); - project.getPlugins().withType(EclipsePlugin.class, plugin -> { - final EclipseModel model = project.getExtensions().findByType(EclipseModel.class); - if (model == null) { - return; - } - toPerform.eclipse(project, model); + action.accept(model, ideaExt); }); } - public interface IdeImportAction { - - /** - * Configure an IntelliJ project. - * - * @param project the project to configure on import - * @param idea the basic idea gradle extension - * @param ideaExtension JetBrain's extensions to the base idea model - */ - void idea(final Project project, final IdeaModel idea, final ProjectSettings ideaExtension); + /** + * Executes a task when Idea performs a project synchronization. + * + * @param project project of the task + * @param supplier supplier that may provide a task + */ + public static void addSynchronizationTask(final Project project, final Supplier>> supplier) { + if (!IdeaIntegration.isIdeaSync()) { + return; + } - /** - * Configure an eclipse project. - * - * @param project the project being imported - * @param eclipse the eclipse project model to modify - */ - void eclipse(final Project project, final EclipseModel eclipse); + project.afterEvaluate(p -> supplier.get().ifPresent(task -> { + final StartParameter startParameter = project.getGradle().getStartParameter(); + final List taskRequests = new ArrayList<>(startParameter.getTaskRequests()); + taskRequests.add(new DefaultTaskExecutionRequest(Collections.singletonList(":" + project.getName() + ":" + task.getName()))); + startParameter.setTaskRequests(taskRequests); + })); } - }