Skip to content

Commit

Permalink
Add ability to execute Groovy scripts in a Grails environment with th… (
Browse files Browse the repository at this point in the history
#10056)

* Add ability to execute Groovy scripts in a Grails environment with the Gradle 'runScript' task.

* Use Environment static properties

* Cleanup
  • Loading branch information
jameskleeh authored and graemerocher committed Jul 20, 2016
1 parent dcfa7e1 commit 6e2849d
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 21 deletions.
Expand Up @@ -15,8 +15,13 @@
*/
package grails.ui.script

import grails.config.Config
import grails.core.GrailsApplication
import grails.persistence.support.PersistenceContextInterceptor
import grails.ui.support.DevelopmentGrailsApplication
import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.ImportCustomizer
import org.springframework.context.ConfigurableApplicationContext
/**
* Used to run Grails scripts within the context of a Grails application
Expand All @@ -26,15 +31,15 @@ import org.springframework.context.ConfigurableApplicationContext
*/
@CompileStatic
class GrailsApplicationScriptRunner extends DevelopmentGrailsApplication {
File script
List<File> scripts

private GrailsApplicationScriptRunner(File script, Object... sources) {
private GrailsApplicationScriptRunner(List<File> scripts, Object... sources) {
super(sources)
this.script = script
this.scripts = scripts
}

@Override
ConfigurableApplicationContext run(String... args) {
ConfigurableApplicationContext run(String...args) {
ConfigurableApplicationContext ctx
try {
ctx = super.run(args)
Expand All @@ -45,39 +50,77 @@ class GrailsApplicationScriptRunner extends DevelopmentGrailsApplication {

def binding = new Binding()
binding.setVariable("ctx", ctx)
try {
new GroovyShell(binding).evaluate(script)
} catch (Throwable e) {
System.err.println("Script execution error: $e.message")
System.exit(1)

Config config = ctx.getBean('grailsApplication', GrailsApplication).config
String defaultPackageKey = 'grails.codegen.defaultPackage'
GroovyShell sh
CompilerConfiguration configuration = CompilerConfiguration.DEFAULT
if (config.containsProperty(defaultPackageKey)) {
ImportCustomizer importCustomizer = new ImportCustomizer()
importCustomizer.addStarImports config.getProperty(defaultPackageKey, String)
configuration.addCompilationCustomizers(importCustomizer)
}
finally {
sh = new GroovyShell(binding, configuration)

Collection<PersistenceContextInterceptor> interceptors = ctx.getBeansOfType(PersistenceContextInterceptor).values()

try {
scripts.each {
try {
for(i in interceptors) {
i.init()
}
sh.evaluate(it)
for(i in interceptors) {
i.destroy()
}
} catch (Throwable e) {
System.err.println("Script execution error: $e.message")
System.exit(1)
}
}
} finally {
try {
for(i in interceptors) {
i.destroy()
}
ctx?.close()
} catch (Throwable e) {
// ignore
}
}


return ctx
}
/**
* Main method to run an existing Application class
*
* @param args The first argument is the Application class name
* @param args The last argument is the Application class name. All other args are script names
*/
public static void main(String[] args) {
if(args.size() > 1) {
def applicationClass = Thread.currentThread().contextClassLoader.loadClass(args[0])
File script = new File(args[1]);
if(script.exists()) {
new GrailsApplicationScriptRunner(script, applicationClass).run(args[1..-1] as String[])
}
else {
System.err.println("Specified script [$script] does not exist")
Class applicationClass
try {
applicationClass = Thread.currentThread().contextClassLoader.loadClass(args.last())
} catch (Throwable e) {
System.err.println("Application class not found")
System.exit(1)
}
}
else {
String[] scriptNames = args.init() as String[]
List<File> scripts = []
scriptNames.each { String scriptName ->
File script = new File(scriptName)
if (script.exists()) {
scripts.add(script)
} else {
System.err.println("Specified script [${scriptName}] not found")
System.exit(1)
}
}

new GrailsApplicationScriptRunner(scripts, applicationClass).run(args)
} else {
System.err.println("Missing application class name and script name arguments")
System.exit(1)
}
Expand Down
@@ -0,0 +1,15 @@
package org.grails.gradle.plugin.commands

import groovy.transform.CompileStatic
import org.gradle.api.tasks.JavaExec

@CompileStatic
class ApplicationContextScriptTask extends JavaExec {

ApplicationContextScriptTask() {
setMain("grails.ui.script.GrailsApplicationScriptRunner")
dependsOn("classes", "findMainClass")
systemProperties(System.properties.findAll { it.key.toString().startsWith('grails.') } as Map<String, Object>)
}

}
Expand Up @@ -51,6 +51,7 @@ 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.commands.ApplicationContextScriptTask
import org.grails.gradle.plugin.model.GrailsClasspathToolingModelBuilder
import org.grails.gradle.plugin.run.FindMainClassTask
import org.grails.gradle.plugin.util.SourceSets
Expand Down Expand Up @@ -119,6 +120,8 @@ class GrailsGradlePlugin extends GroovyPlugin {

createBuildPropertiesTask(project)

configureRunScript(project)

configurePathingJar(project)
}

Expand Down Expand Up @@ -232,6 +235,7 @@ class GrailsGradlePlugin extends GroovyPlugin {
project.tasks.create(taskName, ApplicationContextCommandTask) {
classpath = project.sourceSets.main.runtimeClasspath + project.configurations.console
command = commandName
systemProperty Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.name)
if (project.hasProperty('args')) {
args(CommandLineParser.translateCommandline(project.args))
}
Expand Down Expand Up @@ -355,6 +359,9 @@ class GrailsGradlePlugin extends GroovyPlugin {
project.tasks.withType(ApplicationContextCommandTask) { ApplicationContextCommandTask task ->
task.args mainClassName
}
project.tasks.withType(ApplicationContextScriptTask) { ApplicationContextScriptTask task ->
task.args mainClassName
}
}

consoleTask.dependsOn(tasks.findByName('classes'), findMainClass)
Expand Down Expand Up @@ -493,6 +500,16 @@ class GrailsGradlePlugin extends GroovyPlugin {
}
}

protected void configureRunScript(Project project) {
project.tasks.create("runScript", ApplicationContextScriptTask) {
classpath = project.sourceSets.main.runtimeClasspath + project.configurations.console
systemProperty Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.name)
if (project.hasProperty('args')) {
args(CommandLineParser.translateCommandline(project.args))
}
}
}

protected void configurePathingJar(Project project) {
project.afterEvaluate {
ConfigurationContainer configurations = project.configurations
Expand Down Expand Up @@ -523,7 +540,7 @@ class GrailsGradlePlugin extends GroovyPlugin {

if (grailsExt.pathingJar && Os.isFamily(Os.FAMILY_WINDOWS)) {
project.tasks.withType(JavaExec) { JavaExec task ->
if (task.name in ['console', 'shell'] || task instanceof ApplicationContextCommandTask) {
if (task.name in ['console', 'shell'] || task instanceof ApplicationContextCommandTask || task instanceof ApplicationContextScriptTask) {
task.dependsOn(pathingJarCommand)
task.doFirst {
classpath = pathingClasspathCommand
Expand All @@ -535,8 +552,11 @@ class GrailsGradlePlugin extends GroovyPlugin {
}
}
}

}
}
}



}
Expand Up @@ -15,6 +15,7 @@
*/
package org.grails.gradle.plugin.web

import grails.util.Environment
import org.gradle.api.Project
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.grails.gradle.plugin.commands.ApplicationContextCommandTask
Expand All @@ -40,6 +41,7 @@ class GrailsWebGradlePlugin extends GrailsGradlePlugin {

project.tasks.create("urlMappingsReport", ApplicationContextCommandTask) {
classpath = project.sourceSets.main.runtimeClasspath + project.configurations.console
systemProperty Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.name)
command = 'url-mappings-report'
}
}
Expand Down

0 comments on commit 6e2849d

Please sign in to comment.