Skip to content

Commit 6e2849d

Browse files
jameskleehgraemerocher
authored andcommitted
Add ability to execute Groovy scripts in a Grails environment with th… (#10056)
* Add ability to execute Groovy scripts in a Grails environment with the Gradle 'runScript' task. * Use Environment static properties * Cleanup
1 parent dcfa7e1 commit 6e2849d

File tree

4 files changed

+101
-21
lines changed

4 files changed

+101
-21
lines changed

grails-console/src/main/groovy/grails/ui/script/GrailsApplicationScriptRunner.groovy

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@
1515
*/
1616
package grails.ui.script
1717

18+
import grails.config.Config
19+
import grails.core.GrailsApplication
20+
import grails.persistence.support.PersistenceContextInterceptor
1821
import grails.ui.support.DevelopmentGrailsApplication
1922
import groovy.transform.CompileStatic
23+
import org.codehaus.groovy.control.CompilerConfiguration
24+
import org.codehaus.groovy.control.customizers.ImportCustomizer
2025
import org.springframework.context.ConfigurableApplicationContext
2126
/**
2227
* Used to run Grails scripts within the context of a Grails application
@@ -26,15 +31,15 @@ import org.springframework.context.ConfigurableApplicationContext
2631
*/
2732
@CompileStatic
2833
class GrailsApplicationScriptRunner extends DevelopmentGrailsApplication {
29-
File script
34+
List<File> scripts
3035

31-
private GrailsApplicationScriptRunner(File script, Object... sources) {
36+
private GrailsApplicationScriptRunner(List<File> scripts, Object... sources) {
3237
super(sources)
33-
this.script = script
38+
this.scripts = scripts
3439
}
3540

3641
@Override
37-
ConfigurableApplicationContext run(String... args) {
42+
ConfigurableApplicationContext run(String...args) {
3843
ConfigurableApplicationContext ctx
3944
try {
4045
ctx = super.run(args)
@@ -45,39 +50,77 @@ class GrailsApplicationScriptRunner extends DevelopmentGrailsApplication {
4550

4651
def binding = new Binding()
4752
binding.setVariable("ctx", ctx)
48-
try {
49-
new GroovyShell(binding).evaluate(script)
50-
} catch (Throwable e) {
51-
System.err.println("Script execution error: $e.message")
52-
System.exit(1)
53+
54+
Config config = ctx.getBean('grailsApplication', GrailsApplication).config
55+
String defaultPackageKey = 'grails.codegen.defaultPackage'
56+
GroovyShell sh
57+
CompilerConfiguration configuration = CompilerConfiguration.DEFAULT
58+
if (config.containsProperty(defaultPackageKey)) {
59+
ImportCustomizer importCustomizer = new ImportCustomizer()
60+
importCustomizer.addStarImports config.getProperty(defaultPackageKey, String)
61+
configuration.addCompilationCustomizers(importCustomizer)
5362
}
54-
finally {
63+
sh = new GroovyShell(binding, configuration)
64+
65+
Collection<PersistenceContextInterceptor> interceptors = ctx.getBeansOfType(PersistenceContextInterceptor).values()
66+
67+
try {
68+
scripts.each {
69+
try {
70+
for(i in interceptors) {
71+
i.init()
72+
}
73+
sh.evaluate(it)
74+
for(i in interceptors) {
75+
i.destroy()
76+
}
77+
} catch (Throwable e) {
78+
System.err.println("Script execution error: $e.message")
79+
System.exit(1)
80+
}
81+
}
82+
} finally {
5583
try {
84+
for(i in interceptors) {
85+
i.destroy()
86+
}
5687
ctx?.close()
5788
} catch (Throwable e) {
5889
// ignore
5990
}
6091
}
92+
93+
6194
return ctx
6295
}
6396
/**
6497
* Main method to run an existing Application class
6598
*
66-
* @param args The first argument is the Application class name
99+
* @param args The last argument is the Application class name. All other args are script names
67100
*/
68101
public static void main(String[] args) {
69102
if(args.size() > 1) {
70-
def applicationClass = Thread.currentThread().contextClassLoader.loadClass(args[0])
71-
File script = new File(args[1]);
72-
if(script.exists()) {
73-
new GrailsApplicationScriptRunner(script, applicationClass).run(args[1..-1] as String[])
74-
}
75-
else {
76-
System.err.println("Specified script [$script] does not exist")
103+
Class applicationClass
104+
try {
105+
applicationClass = Thread.currentThread().contextClassLoader.loadClass(args.last())
106+
} catch (Throwable e) {
107+
System.err.println("Application class not found")
77108
System.exit(1)
78109
}
79-
}
80-
else {
110+
String[] scriptNames = args.init() as String[]
111+
List<File> scripts = []
112+
scriptNames.each { String scriptName ->
113+
File script = new File(scriptName)
114+
if (script.exists()) {
115+
scripts.add(script)
116+
} else {
117+
System.err.println("Specified script [${scriptName}] not found")
118+
System.exit(1)
119+
}
120+
}
121+
122+
new GrailsApplicationScriptRunner(scripts, applicationClass).run(args)
123+
} else {
81124
System.err.println("Missing application class name and script name arguments")
82125
System.exit(1)
83126
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.grails.gradle.plugin.commands
2+
3+
import groovy.transform.CompileStatic
4+
import org.gradle.api.tasks.JavaExec
5+
6+
@CompileStatic
7+
class ApplicationContextScriptTask extends JavaExec {
8+
9+
ApplicationContextScriptTask() {
10+
setMain("grails.ui.script.GrailsApplicationScriptRunner")
11+
dependsOn("classes", "findMainClass")
12+
systemProperties(System.properties.findAll { it.key.toString().startsWith('grails.') } as Map<String, Object>)
13+
}
14+
15+
}

grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
5151
import org.grails.build.parsing.CommandLineParser
5252
import org.grails.gradle.plugin.agent.AgentTasksEnhancer
5353
import org.grails.gradle.plugin.commands.ApplicationContextCommandTask
54+
import org.grails.gradle.plugin.commands.ApplicationContextScriptTask
5455
import org.grails.gradle.plugin.model.GrailsClasspathToolingModelBuilder
5556
import org.grails.gradle.plugin.run.FindMainClassTask
5657
import org.grails.gradle.plugin.util.SourceSets
@@ -119,6 +120,8 @@ class GrailsGradlePlugin extends GroovyPlugin {
119120

120121
createBuildPropertiesTask(project)
121122

123+
configureRunScript(project)
124+
122125
configurePathingJar(project)
123126
}
124127

@@ -232,6 +235,7 @@ class GrailsGradlePlugin extends GroovyPlugin {
232235
project.tasks.create(taskName, ApplicationContextCommandTask) {
233236
classpath = project.sourceSets.main.runtimeClasspath + project.configurations.console
234237
command = commandName
238+
systemProperty Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.name)
235239
if (project.hasProperty('args')) {
236240
args(CommandLineParser.translateCommandline(project.args))
237241
}
@@ -355,6 +359,9 @@ class GrailsGradlePlugin extends GroovyPlugin {
355359
project.tasks.withType(ApplicationContextCommandTask) { ApplicationContextCommandTask task ->
356360
task.args mainClassName
357361
}
362+
project.tasks.withType(ApplicationContextScriptTask) { ApplicationContextScriptTask task ->
363+
task.args mainClassName
364+
}
358365
}
359366

360367
consoleTask.dependsOn(tasks.findByName('classes'), findMainClass)
@@ -493,6 +500,16 @@ class GrailsGradlePlugin extends GroovyPlugin {
493500
}
494501
}
495502

503+
protected void configureRunScript(Project project) {
504+
project.tasks.create("runScript", ApplicationContextScriptTask) {
505+
classpath = project.sourceSets.main.runtimeClasspath + project.configurations.console
506+
systemProperty Environment.KEY, System.getProperty(Environment.KEY, Environment.DEVELOPMENT.name)
507+
if (project.hasProperty('args')) {
508+
args(CommandLineParser.translateCommandline(project.args))
509+
}
510+
}
511+
}
512+
496513
protected void configurePathingJar(Project project) {
497514
project.afterEvaluate {
498515
ConfigurationContainer configurations = project.configurations
@@ -523,7 +540,7 @@ class GrailsGradlePlugin extends GroovyPlugin {
523540

524541
if (grailsExt.pathingJar && Os.isFamily(Os.FAMILY_WINDOWS)) {
525542
project.tasks.withType(JavaExec) { JavaExec task ->
526-
if (task.name in ['console', 'shell'] || task instanceof ApplicationContextCommandTask) {
543+
if (task.name in ['console', 'shell'] || task instanceof ApplicationContextCommandTask || task instanceof ApplicationContextScriptTask) {
527544
task.dependsOn(pathingJarCommand)
528545
task.doFirst {
529546
classpath = pathingClasspathCommand
@@ -535,8 +552,11 @@ class GrailsGradlePlugin extends GroovyPlugin {
535552
}
536553
}
537554
}
555+
538556
}
539557
}
540558
}
541559

560+
561+
542562
}

grails-gradle-plugin/src/main/groovy/org/grails/gradle/plugin/web/GrailsWebGradlePlugin.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.grails.gradle.plugin.web
1717

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

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

0 commit comments

Comments
 (0)