From 1a91ad042011202306badaacab452df338c8e893 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Mon, 14 Aug 2017 18:24:24 +0300 Subject: [PATCH] POC: Import IDE configuration from external systems Extract gradle model to plugin --- .../importing/GradleMiscImportingTest.java | 9 ++++++++- .../IntelliJProjectSettingsBuilder.groovy | 3 +-- .../builder/IntelliJSettingsBuilder.groovy | 3 +-- .../gradle/tooling/internal/init/init.gradle | 12 ------------ .../gradle-idea-ext.jar | Bin 0 -> 10388 bytes 5 files changed, 10 insertions(+), 17 deletions(-) create mode 100644 plugins/gradle/tooling-extension-impl/testData/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleMiscImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleMiscImportingTest.java index f11cd68036af..5715e892b738 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleMiscImportingTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleMiscImportingTest.java @@ -167,8 +167,15 @@ public class GradleMiscImportingTest extends GradleImportingTestCase { @Test public void testCompilerConfigurationSettingsImport() throws Exception { + final String pathToPlugin = getClass().getResource("/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar").toString(); + importProject( - "apply plugin: 'idea'\n" + + "buildscript {\n" + + " dependencies {\n" + + " classpath files('" + pathToPlugin + "')\n" + + " }\n" + + "}\n" + + "apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'\n" + "idea {\n" + " project.settings {\n" + " compiler {\n" + diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJProjectSettingsBuilder.groovy b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJProjectSettingsBuilder.groovy index 8f803a96bed7..8415e07925ce 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJProjectSettingsBuilder.groovy +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJProjectSettingsBuilder.groovy @@ -23,7 +23,6 @@ import org.jetbrains.plugins.gradle.model.DefaultIntelliJSettings import org.jetbrains.plugins.gradle.model.IntelliJProjectSettings import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder import org.jetbrains.plugins.gradle.tooling.ModelBuilderService -import org.jetbrains.plugins.gradle.tooling.internal.DynamicSettings /** * @author Vladislav.Soroka @@ -41,7 +40,7 @@ class IntelliJProjectSettingsBuilder implements ModelBuilderService { ExtensionAware extensionAware = project.plugins.findPlugin(IdeaPlugin.class)?.model?.project as ExtensionAware if (extensionAware) { def object = extensionAware.extensions.findByName("settings") - if (object instanceof DynamicSettings && !object.objects.isEmpty()) { + if (object) { return new DefaultIntelliJSettings(object.toString()) } } diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJSettingsBuilder.groovy b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJSettingsBuilder.groovy index d9be555d79da..6ef3894da2da 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJSettingsBuilder.groovy +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/IntelliJSettingsBuilder.groovy @@ -24,7 +24,6 @@ import org.jetbrains.plugins.gradle.model.DefaultIntelliJSettings import org.jetbrains.plugins.gradle.model.IntelliJSettings import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder import org.jetbrains.plugins.gradle.tooling.ModelBuilderService -import org.jetbrains.plugins.gradle.tooling.internal.DynamicSettings /** * @author Vladislav.Soroka @@ -42,7 +41,7 @@ class IntelliJSettingsBuilder implements ModelBuilderService { ExtensionAware extensionAware = project.plugins.findPlugin(IdeaPlugin.class)?.model?.module as ExtensionAware if (extensionAware) { def object = extensionAware.extensions.findByName("settings") - if (object instanceof DynamicSettings && !(object as DynamicSettings).objects.isEmpty()) { + if (object) { return new DefaultIntelliJSettings(object.toString()) } } diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle index b44c64dde80c..552bcd0cafb8 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle @@ -1,6 +1,5 @@ import org.gradle.api.internal.project.ProjectInternal import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry -import org.jetbrains.plugins.gradle.tooling.internal.DynamicSettings import org.jetbrains.plugins.gradle.tooling.internal.ExtraModelBuilder System.setProperty("idea.active", "true") @@ -55,16 +54,5 @@ class JetGradlePlugin implements Plugin { it.register(extraModelBuilderInstance) } } - gradle.allprojects { project -> - project.pluginManager.withPlugin('idea') { plugin -> - def ideaModel = project.extensions.getByName('idea') - if (project.parent == null && !ideaModel.project.extensions.findByName('settings')) { - ideaModel.project.extensions.create('settings', DynamicSettings) - } - if (!ideaModel.module.extensions.findByName('settings')) { - ideaModel.module.extensions.create('settings', DynamicSettings) - } - } - } } } diff --git a/plugins/gradle/tooling-extension-impl/testData/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar b/plugins/gradle/tooling-extension-impl/testData/testCompilerConfigurationSettingsImport/gradle-idea-ext.jar new file mode 100644 index 0000000000000000000000000000000000000000..288c066560c58ba9a3505fbd00199a10bfb0b253 GIT binary patch literal 10388 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