diff --git a/grails-core/src/main/groovy/grails/dev/commands/ApplicationCommand.groovy b/grails-core/src/main/groovy/grails/dev/commands/ApplicationCommand.groovy index 2e61c5fa442..e9086c16ee6 100644 --- a/grails-core/src/main/groovy/grails/dev/commands/ApplicationCommand.groovy +++ b/grails-core/src/main/groovy/grails/dev/commands/ApplicationCommand.groovy @@ -18,6 +18,8 @@ */ package grails.dev.commands +import groovy.transform.CompileStatic + import org.springframework.context.ConfigurableApplicationContext import grails.util.Described @@ -25,43 +27,48 @@ import grails.util.GrailsNameUtils import grails.util.Named /** - * Represents a command that is run against the {@link org.springframework.context.ApplicationContext} + * Represents a command that runs with access to the + * {@link org.springframework.context.ApplicationContext}. * * @author Graeme Rocher * @since 3.0 */ +@CompileStatic trait ApplicationCommand implements Named, Described { - private ConfigurableApplicationContext applicationContext + ConfigurableApplicationContext applicationContext /** - * Sets the application context of the command - * - * @param applicationContext The application context + * Calculates the command name as used on the command line. + *

Example: + * {@code UrlMappingsReportCommand} -> {@code url-mappings-report} + * @return The command line name of the command */ - void setApplicationContext(ConfigurableApplicationContext applicationContext) { - this.applicationContext = applicationContext - } - - ConfigurableApplicationContext getApplicationContext() { - return this.applicationContext - } - @Override String getName() { - return GrailsNameUtils.getScriptName(GrailsNameUtils.getLogicalName(getClass().getName(), 'Command')) + GrailsNameUtils.getScriptName( + GrailsNameUtils.getLogicalName( + getClass().name, + 'Command' + ) + ) } + /** + * The description of the command. + * By default this returns the name of the command. + * @return The description of the command + */ @Override String getDescription() { - getName() + name } /** - * Handles the command + * Executes the command. * * @param executionContext The execution context - * @return True if the command was successful + * @return {@code true} if the command was successful; {@code false} otherwise */ abstract boolean handle(ExecutionContext executionContext) diff --git a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy index b7c5c5d37d8..26e853ac305 100644 --- a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy +++ b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy @@ -173,7 +173,7 @@ class GrailsGradlePlugin extends GroovyPlugin { } } - private static Provider getMainClassProvider(Project project) { + protected static Provider getMainClassProvider(Project project) { Provider findMainClassTask = project.tasks.named('findMainClass', FindMainClassTask) project.provider { File cacheFile = findMainClassTask.get().mainClassCacheFile.orNull?.asFile @@ -855,6 +855,15 @@ class GrailsGradlePlugin extends GroovyPlugin { fileCollection } + protected FileCollection buildClasspath(Project project, String... configurationNames) { + buildClasspath( + project, + configurationNames.collect { + project.configurations.named(it).getOrNull() + }.findAll(/* remove nulls */) as Configuration[] + ) + } + @CompileStatic private static final class OnlyOneGrailsPlugin { String pluginClassname diff --git a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy index a42fe686dfc..af661e45c76 100644 --- a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy +++ b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy @@ -20,12 +20,10 @@ package org.grails.gradle.plugin.web import javax.inject.Inject -import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import org.gradle.api.Project -import org.gradle.api.file.FileCollection -import org.gradle.api.tasks.TaskContainer +import org.gradle.process.CommandLineArgumentProvider import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import grails.util.Environment @@ -41,24 +39,42 @@ import org.grails.gradle.plugin.core.GrailsGradlePlugin @CompileStatic class GrailsWebGradlePlugin extends GrailsGradlePlugin { + private static final String URL_MAPPINGS_REPORT = 'urlMappingsReport' + @Inject GrailsWebGradlePlugin(ToolingModelBuilderRegistry registry) { super(registry) } - @CompileDynamic @Override void apply(Project project) { super.apply(project) - TaskContainer taskContainer = project.tasks - if (taskContainer.findByName('urlMappingsReport') == null) { - FileCollection fileCollection = buildClasspath(project, project.configurations.runtimeClasspath, project.configurations.console) - taskContainer.create('urlMappingsReport', ApplicationContextCommandTask) { - classpath = fileCollection - systemProperty(Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.getName())) - command = 'url-mappings-report' - } + // The task could theoretically already be registered by + // GrailsGradlePlugin in configureApplicationCommands() + // if grails-web-urlmappings is on the build classpath + if (!project.tasks.names.contains(URL_MAPPINGS_REPORT)) { + registerUrlMappingsTask(project) + } + } + + private void registerUrlMappingsTask(Project project) { + project.tasks.register(URL_MAPPINGS_REPORT, ApplicationContextCommandTask) { task -> + task.classpath = buildClasspath( + project, + 'runtimeClasspath', 'console' + ) + task.systemProperty( + Environment.KEY, + System.getProperty( + Environment.KEY, + Environment.DEVELOPMENT.name + ) + ) + def appClassProvider = GrailsGradlePlugin.getMainClassProvider(project) + task.argumentProviders.add({ + ['url-mappings-report', appClassProvider.get()] + } as CommandLineArgumentProvider) } } } diff --git a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/reporting/UrlMappingsReportCommand.groovy b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/reporting/UrlMappingsReportCommand.groovy index 7b79d79f96e..cb581b95c92 100644 --- a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/reporting/UrlMappingsReportCommand.groovy +++ b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/reporting/UrlMappingsReportCommand.groovy @@ -24,18 +24,17 @@ import groovy.util.logging.Slf4j import grails.dev.commands.ApplicationCommand import grails.dev.commands.ExecutionContext -import grails.web.mapping.UrlMappings -import grails.web.mapping.reporting.UrlMappingsRenderer +import grails.web.mapping.UrlMappingsHolder /** - * A {@link ApplicationCommand} that renders the URL mappings + * An {@link ApplicationCommand} that renders the URL mappings. * * @author Graeme Rocher * @since 3.0 */ +@Slf4j @CompileStatic @EqualsAndHashCode -@Slf4j class UrlMappingsReportCommand implements ApplicationCommand { final String description = /Prints out a report of the project's URL mappings/ @@ -43,14 +42,16 @@ class UrlMappingsReportCommand implements ApplicationCommand { @Override boolean handle(ExecutionContext executionContext) { try { - def urlMappings = applicationContext.getBean('grailsUrlMappingsHolder', UrlMappings) - - UrlMappingsRenderer renderer = new AnsiConsoleUrlMappingsRenderer() - renderer.render(urlMappings.getUrlMappings().toList()) - return true + def urlMappingsHolder = applicationContext.getBean( + 'grailsUrlMappingsHolder', + UrlMappingsHolder + ) + new AnsiConsoleUrlMappingsRenderer() + .render(urlMappingsHolder.urlMappings.toList()) } catch (Throwable e) { - log.error("Failed to render URL mappings: ${e.message}", e) + log.error("Failed to render URL mappings: $e.message", e) return false } + return true } } diff --git a/grails-web-url-mappings/src/main/resources/META-INF/services/grails.factories b/grails-web-url-mappings/src/main/resources/META-INF/services/grails.factories deleted file mode 100644 index bb634f3af72..00000000000 --- a/grails-web-url-mappings/src/main/resources/META-INF/services/grails.factories +++ /dev/null @@ -1 +0,0 @@ -grails.dev.commands.ApplicationCommand=org.grails.web.mapping.reporting.UrlMappingsReportCommand \ No newline at end of file