From 1989584751226d2ff852f68021f0e44877c5998f Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Mon, 2 Mar 2015 15:42:13 -0500 Subject: [PATCH] Replace EclipseModel based classpath resolution with custom Gradle ToolingModelBuilder implementation --- .../model/DefaultGrailsClasspath.groovy | 22 ++++++++++ .../plugin/model/GrailsClasspath.groovy | 26 ++++++++++++ grails-gradle-plugin/build.gradle | 1 + .../plugin/core/GrailsGradlePlugin.groovy | 16 ++++++++ .../core/GrailsPluginGradlePlugin.groovy | 8 ++++ .../GrailsClasspathToolingModelBuilder.groovy | 40 +++++++++++++++++++ .../plugin/web/GrailsWebGradlePlugin.groovy | 7 ++++ grails-shell/build.gradle | 1 + .../groovy/org/grails/cli/GrailsCli.groovy | 10 ++--- .../cli/gradle/ClasspathBuildAction.groovy | 8 ++-- settings.gradle | 3 +- 11 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/DefaultGrailsClasspath.groovy create mode 100644 grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspath.groovy create mode 100644 grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspathToolingModelBuilder.groovy diff --git a/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/DefaultGrailsClasspath.groovy b/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/DefaultGrailsClasspath.groovy new file mode 100644 index 00000000000..6207621750d --- /dev/null +++ b/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/DefaultGrailsClasspath.groovy @@ -0,0 +1,22 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.grails.gradle.plugin.model + +class DefaultGrailsClasspath implements GrailsClasspath { + private static final long serialVersionUID = 1L + List dependencies +} diff --git a/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspath.groovy b/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspath.groovy new file mode 100644 index 00000000000..40e6c2dabd2 --- /dev/null +++ b/grails-gradle-model/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspath.groovy @@ -0,0 +1,26 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.grails.gradle.plugin.model + +/** + * Gradle ToolingModel class that is used to return Classpath to Grails cli + * + * this file is also in grails-shell project + */ +interface GrailsClasspath extends Serializable { + List getDependencies() +} diff --git a/grails-gradle-plugin/build.gradle b/grails-gradle-plugin/build.gradle index cd0e3cc7087..5f061e1cde9 100644 --- a/grails-gradle-plugin/build.gradle +++ b/grails-gradle-plugin/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'groovy' dependencies { compile gradleApi() + compile project(":grails-gradle-model") compile project(":grails-bootstrap"), { exclude group:"org.fusesource.jansi", module:"jansi" exclude group:"jline", module:"jline" diff --git a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy index b4d081ea105..cd2218068cb 100644 --- a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy +++ b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy @@ -21,20 +21,32 @@ import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.compile.GroovyCompile import org.gradle.api.tasks.testing.Test import org.gradle.process.JavaForkOptions +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.grails.build.parsing.CommandLineParser import org.grails.gradle.plugin.agent.AgentTasksEnhancer import org.grails.gradle.plugin.commands.ApplicationContextCommandTask +import org.grails.gradle.plugin.model.GrailsClasspathToolingModelBuilder import org.grails.gradle.plugin.run.FindMainClassTask import org.grails.io.support.FactoriesLoaderSupport +import javax.inject.Inject + class GrailsGradlePlugin extends GroovyPlugin { public static final String APPLICATION_CONTEXT_COMMAND_CLASS = "grails.dev.commands.ApplicationCommand" List> basePluginClasses = [ProvidedBasePlugin, IntegrationTestGradlePlugin] List excludedGrailsAppSourceDirs = ['migrations', 'assets'] List grailsAppResourceDirs = ['views', 'i18n', 'conf'] + private final ToolingModelBuilderRegistry registry + + @Inject + GrailsGradlePlugin(ToolingModelBuilderRegistry registry) { + this.registry = registry + } void apply(Project project) { super.apply(project) + registerToolingModelBuilder(project, registry) + registerGrailsExtension(project) applyBasePlugins(project) @@ -60,6 +72,10 @@ class GrailsGradlePlugin extends GroovyPlugin { configureApplicationCommands(project) } + protected void registerToolingModelBuilder(Project project, ToolingModelBuilderRegistry registry) { + registry.register(new GrailsClasspathToolingModelBuilder()) + } + @CompileStatic protected void applyBasePlugins(Project project) { basePluginClasses.each { Class cls -> project.plugins.apply(cls) } diff --git a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy index c1d4939b46d..56fff25324e 100644 --- a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy +++ b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy @@ -5,6 +5,9 @@ import org.gradle.api.tasks.Copy import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.bundling.Jar import org.gradle.language.jvm.tasks.ProcessResources +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry + +import javax.inject.Inject /* * Copyright 2014 original authors @@ -31,6 +34,11 @@ import org.gradle.language.jvm.tasks.ProcessResources */ class GrailsPluginGradlePlugin extends GrailsGradlePlugin { + @Inject + GrailsPluginGradlePlugin(ToolingModelBuilderRegistry registry) { + super(registry) + } + @Override void apply(Project project) { super.apply(project) diff --git a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspathToolingModelBuilder.groovy b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspathToolingModelBuilder.groovy new file mode 100644 index 00000000000..fe1bc882f22 --- /dev/null +++ b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspathToolingModelBuilder.groovy @@ -0,0 +1,40 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.grails.gradle.plugin.model + +import org.gradle.api.Project +import org.gradle.api.artifacts.ResolvedArtifact +import org.gradle.tooling.provider.model.ToolingModelBuilder + +/** + * Builds the GrailsClasspath instance that contains the URLs of the resolved dependencies + */ +class GrailsClasspathToolingModelBuilder implements ToolingModelBuilder { + + @Override + boolean canBuild(String modelName) { + return modelName == GrailsClasspath.name + } + + @Override + Object buildAll(String modelName, Project project) { + List runtimeDependencies = project.getConfigurations().getByName("runtime").getResolvedConfiguration().getResolvedArtifacts().collect { ResolvedArtifact artifact -> + artifact.getFile().toURI().toURL() + } + new DefaultGrailsClasspath(dependencies: runtimeDependencies) + } +} diff --git a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy index c050dc33e8b..73469671b0a 100644 --- a/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy +++ b/grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy @@ -16,9 +16,12 @@ package org.grails.gradle.plugin.web import org.gradle.api.Project +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.grails.gradle.plugin.commands.ApplicationContextCommandTask import org.grails.gradle.plugin.core.GrailsGradlePlugin +import javax.inject.Inject + /** * Adds web specific extensions * @@ -26,6 +29,10 @@ import org.grails.gradle.plugin.core.GrailsGradlePlugin * @since 3.0 */ class GrailsWebGradlePlugin extends GrailsGradlePlugin { + @Inject + GrailsWebGradlePlugin(ToolingModelBuilderRegistry registry) { + super(registry) + } @Override void apply(Project project) { diff --git a/grails-shell/build.gradle b/grails-shell/build.gradle index 8d4c2533597..b6479e035fd 100644 --- a/grails-shell/build.gradle +++ b/grails-shell/build.gradle @@ -13,6 +13,7 @@ ext { dependencies { compile project(":grails-bootstrap") + compile project(":grails-gradle-model") compile "org.apache.ant:ant:$antVersion" compile "org.codehaus.groovy:groovy-ant:$groovyVersion" compile "org.codehaus.groovy:groovy-json:$groovyVersion" diff --git a/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy b/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy index ad21e7be221..4ea739ba67b 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy @@ -28,8 +28,6 @@ import jline.console.completer.ArgumentCompleter import jline.internal.NonBlockingInputStream import org.gradle.tooling.BuildCancelledException import org.gradle.tooling.ProjectConnection -import org.gradle.tooling.model.ExternalDependency -import org.gradle.tooling.model.eclipse.EclipseProject import org.grails.build.parsing.CommandLine import org.grails.build.parsing.CommandLineParser import org.grails.build.parsing.DefaultCommandLine @@ -45,6 +43,7 @@ import org.grails.cli.profile.commands.CommandRegistry import org.grails.cli.profile.git.GitProfileRepository import org.grails.config.CodeGenConfig import org.grails.exceptions.ExceptionUtils +import org.grails.gradle.plugin.model.GrailsClasspath import java.util.concurrent.* @@ -363,11 +362,8 @@ class GrailsCli { @Override List readFromGradle(ProjectConnection connection) { - EclipseProject project = GradleUtil.runBuildActionWithConsoleOutput(connection, projectContext, new ClasspathBuildAction()) - - List classpathUrls = project.getClasspath().collect { dependency -> ((ExternalDependency)dependency).file.toURI().toURL() } - - return classpathUrls + GrailsClasspath grailsClasspath = GradleUtil.runBuildActionWithConsoleOutput(connection, projectContext, new ClasspathBuildAction()) + return grailsClasspath.dependencies } }.call() diff --git a/grails-shell/src/main/groovy/org/grails/cli/gradle/ClasspathBuildAction.groovy b/grails-shell/src/main/groovy/org/grails/cli/gradle/ClasspathBuildAction.groovy index 15d1cdff499..7f884ea6d6c 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/gradle/ClasspathBuildAction.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/gradle/ClasspathBuildAction.groovy @@ -17,7 +17,7 @@ package org.grails.cli.gradle import org.gradle.tooling.BuildAction import org.gradle.tooling.BuildController -import org.gradle.tooling.model.eclipse.EclipseProject +import org.grails.gradle.plugin.model.GrailsClasspath /** * Gets the EclipseProject which helps obtain the classpath necessary @@ -25,9 +25,9 @@ import org.gradle.tooling.model.eclipse.EclipseProject * @author Graeme Rocher * @since 3.0 */ -class ClasspathBuildAction implements BuildAction, Serializable { +class ClasspathBuildAction implements BuildAction, Serializable { @Override - EclipseProject execute(BuildController controller) { - controller.getModel(EclipseProject) + GrailsClasspath execute(BuildController controller) { + controller.getModel(GrailsClasspath) } } diff --git a/settings.gradle b/settings.gradle index ee7b67dd337..80e227db4f2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -63,5 +63,6 @@ include ( 'grails-compat', // Gradle Plugin - 'grails-gradle-plugin' + 'grails-gradle-plugin', + 'grails-gradle-model' )