Skip to content

Commit 61f3041

Browse files
committed
Allow running an application with dependent plugin classes being placed directly on the classpath
1 parent b6a690f commit 61f3041

File tree

6 files changed

+197
-31
lines changed

6 files changed

+197
-31
lines changed

grails-bootstrap/src/main/groovy/grails/util/Environment.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ public enum Environment {
7373
*/
7474
public static String RELOAD_ENABLED = "grails.reload.enabled";
7575

76+
/**
77+
* Constant indicating whether run-app or test-app was executed
78+
*/
79+
public static String RUN_ACTIVE = "grails.run.active";
80+
7681
/**
7782
* Whether the display of full stack traces is needed
7883
*/
@@ -268,6 +273,15 @@ public static boolean isDevelopmentMode() {
268273
public static boolean isDevelopmentEnvironmentAvailable() {
269274
return BuildSettings.GRAILS_APP_DIR_PRESENT ;
270275
}
276+
277+
/**
278+
* This method will return true the application is run
279+
*
280+
* @return True if the development sources are present
281+
*/
282+
public static boolean isDevelopmentRun() {
283+
return BuildSettings.GRAILS_APP_DIR_PRESENT && Boolean.getBoolean(RUN_ACTIVE);
284+
}
271285
/**
272286
* Check whether the application is deployed
273287
* @return true if is

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.grails.gradle.plugin.core
22

33
import org.apache.tools.ant.taskdefs.condition.Os
4+
import org.gradle.api.Project
45
import org.gradle.util.ConfigureUtil
56

67
/**
@@ -10,7 +11,11 @@ import org.gradle.util.ConfigureUtil
1011
* @since 3.0
1112
*/
1213
class GrailsExtension {
14+
Project project
1315

16+
GrailsExtension(Project project) {
17+
this.project = project
18+
}
1419
/**
1520
* Whether to invoke native2ascii on resource bundles
1621
*/
@@ -34,9 +39,17 @@ class GrailsExtension {
3439
/**
3540
* Configure the reloading agent
3641
*/
37-
Agent agent(Closure configurer) {
42+
Agent agent(@DelegatesTo(Agent) Closure configurer) {
3843
ConfigureUtil.configure(configurer, agent)
3944
}
45+
46+
/**
47+
* Allows defining plugins in the available scopes
48+
*/
49+
void plugins(Closure pluginDefinitions) {
50+
def definer = new PluginDefiner(project)
51+
ConfigureUtil.configure(pluginDefinitions, definer, Closure.DELEGATE_FIRST)
52+
}
4053
/**
4154
* Configuration for the reloading agent
4255
*/
@@ -52,4 +65,6 @@ class GrailsExtension {
5265
Map<String, String> systemProperties = ['jdk.reflect.allowGetCallerClass': 'true']
5366
List<String> jvmArgs = ['-Xverify:none']
5467
}
68+
69+
5570
}

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

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,9 @@ class GrailsGradlePlugin extends GroovyPlugin {
7979
void apply(Project project) {
8080
super.apply(project)
8181

82-
def profileConfiguration = project.configurations.create(PROFILE_CONFIGURATION)
83-
84-
profileConfiguration.incoming.beforeResolve() {
85-
if(!profileConfiguration.allDependencies) {
86-
addDefaultProfile(project, profileConfiguration)
87-
}
88-
}
89-
90-
profileConfiguration.resolutionStrategy.eachDependency {
91-
DependencyResolveDetails details = (DependencyResolveDetails)it
92-
def group = details.requested.group ?: "org.grails.profiles"
93-
def version = details.requested.version ?: BuildSettings.grailsVersion
94-
details.useTarget(group: group, name:details.requested.name,version:version)
95-
}
82+
configureProfile(project)
9683

97-
98-
99-
100-
def springBoot = project.extensions.findByType(SpringBootPluginExtension)
101-
if(!springBoot) {
102-
project.plugins.apply(SpringBootPlugin)
103-
}
104-
105-
if(!project.plugins.findPlugin(DependencyManagementPlugin)) {
106-
project.plugins.apply(DependencyManagementPlugin)
107-
}
84+
applyDefaultPlugins(project)
10885

10986
registerToolingModelBuilder(project, registry)
11087

@@ -137,11 +114,38 @@ class GrailsGradlePlugin extends GroovyPlugin {
137114
createBuildPropertiesTask(project)
138115
}
139116

140-
@CompileDynamic
141-
void addDefaultProfile(Project project, Configuration profileConfig) {
142-
project.dependencies {
143-
profile ":${System.getProperty("grails.profile") ?: 'web'}:"
117+
protected void configureProfile(Project project) {
118+
def profileConfiguration = project.configurations.create(PROFILE_CONFIGURATION)
119+
120+
profileConfiguration.incoming.beforeResolve() {
121+
if (!profileConfiguration.allDependencies) {
122+
addDefaultProfile(project, profileConfiguration)
123+
}
124+
}
125+
126+
profileConfiguration.resolutionStrategy.eachDependency {
127+
DependencyResolveDetails details = (DependencyResolveDetails) it
128+
def group = details.requested.group ?: "org.grails.profiles"
129+
def version = details.requested.version ?: BuildSettings.grailsVersion
130+
details.useTarget(group: group, name: details.requested.name, version: version)
131+
}
132+
}
133+
134+
@CompileStatic
135+
protected void applyDefaultPlugins(Project project) {
136+
def springBoot = project.extensions.findByType(SpringBootPluginExtension)
137+
if (!springBoot) {
138+
project.plugins.apply(SpringBootPlugin)
144139
}
140+
141+
if (!project.plugins.findPlugin(DependencyManagementPlugin)) {
142+
project.plugins.apply(DependencyManagementPlugin)
143+
}
144+
}
145+
146+
@CompileStatic
147+
void addDefaultProfile(Project project, Configuration profileConfig) {
148+
project.dependencies.add('profile', ":${System.getProperty("grails.profile") ?: 'web'}:")
145149
}
146150

147151
protected Task createBuildPropertiesTask(Project project) {
@@ -196,7 +200,7 @@ class GrailsGradlePlugin extends GroovyPlugin {
196200
}
197201

198202
protected GrailsExtension registerGrailsExtension(Project project) {
199-
project.extensions.create("grails", GrailsExtension)
203+
project.extensions.add("grails", new GrailsExtension(project))
200204
}
201205

202206
protected void configureFileWatch(Project project) {

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ import groovy.transform.CompileStatic
2020
import org.gradle.api.Project
2121
import org.gradle.api.Task
2222
import org.gradle.api.artifacts.Configuration
23+
import org.gradle.api.artifacts.PublishArtifact
24+
import org.gradle.api.internal.tasks.DefaultTaskDependency
2325
import org.gradle.api.tasks.Copy
2426
import org.gradle.api.tasks.JavaExec
2527
import org.gradle.api.tasks.TaskContainer
28+
import org.gradle.api.tasks.TaskDependency
2629
import org.gradle.api.tasks.bundling.Jar
30+
import org.gradle.api.tasks.compile.GroovyCompile
2731
import org.gradle.language.jvm.tasks.ProcessResources
2832
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
2933

@@ -60,6 +64,8 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin {
6064

6165
configureSourcesJarTask(project)
6266

67+
configureExplodedDirConfiguration(project)
68+
6369
}
6470

6571
@CompileDynamic
@@ -70,6 +76,25 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin {
7076
}
7177
}
7278

79+
/**
80+
* Configures an exploded configuration that can be used to build the classpath of the application from subprojects that are plugins without contructing a JAR file
81+
*
82+
* @param project The project instance
83+
*/
84+
@CompileStatic
85+
protected void configureExplodedDirConfiguration(Project project) {
86+
def configurationName = "exploded"
87+
project.configurations.create(configurationName)
88+
89+
// add the subproject classes as outputs
90+
GroovyCompile groovyCompile = (GroovyCompile)project.tasks.findByName('compileGroovy')
91+
project.artifacts.add(configurationName, new ExplodedDir( groovyCompile.destinationDir, groovyCompile) )
92+
93+
// add the subproject resources as outputs
94+
ProcessResources processResources = (ProcessResources)project.tasks.findByName("processResources")
95+
project.artifacts.add(configurationName, new ExplodedDir( processResources.destinationDir, processResources) )
96+
}
97+
7398
@Override
7499
protected Task createBuildPropertiesTask(Project project) {
75100
// no-op
@@ -209,4 +234,29 @@ withConfig(configuration) {
209234
groovyOptions.configurationScript = configFile
210235
}
211236
}
237+
238+
@CompileStatic
239+
static class ExplodedDir implements PublishArtifact {
240+
final String extension = ""
241+
final String type = "dir"
242+
final Date date = new Date()
243+
244+
final File file
245+
final TaskDependency buildDependencies
246+
247+
ExplodedDir(File file, Object...tasks) {
248+
this.file = file
249+
this.buildDependencies = new DefaultTaskDependency().add(tasks)
250+
}
251+
252+
@Override
253+
String getName() {
254+
file.name
255+
}
256+
257+
@Override
258+
String getClassifier() {
259+
""
260+
}
261+
}
212262
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.grails.gradle.plugin.core
2+
3+
import grails.util.Environment
4+
import groovy.transform.CompileStatic
5+
import groovy.transform.PackageScope
6+
import org.gradle.api.Project
7+
import org.gradle.api.artifacts.Dependency
8+
9+
/**
10+
* Makes it easier to define Grails plugins and also makes them aware of the development environment so that they can be run inline without creating a JAR
11+
*
12+
* @author Graeme Rocher
13+
* @since 3.2
14+
*/
15+
@PackageScope
16+
class PluginDefiner {
17+
Project project
18+
19+
PluginDefiner(Project project) {
20+
this.project = project
21+
}
22+
23+
void methodMissing(String name, args) {
24+
Object[] argArray = (Object[])args
25+
26+
if(!argArray) {
27+
throw new MissingMethodException(name, GrailsExtension, args)
28+
}
29+
else {
30+
if(argArray[0] instanceof Map) {
31+
Map notation = (Map)argArray[0]
32+
if(!notation.containsKey('group')) {
33+
notation.put('group','org.grails.plugins')
34+
}
35+
}
36+
else if(argArray[0] instanceof CharSequence) {
37+
String str = argArray[0].toString()
38+
39+
if(str.startsWith(':')) {
40+
argArray[0] = "org.grails.plugins$str".toString()
41+
}
42+
}
43+
project.dependencies.add(name, *argArray )
44+
}
45+
}
46+
47+
@CompileStatic
48+
Dependency project(String path) {
49+
if(Environment.isDevelopmentRun()) {
50+
project.dependencies.project(path:path, configuration:'exploded')
51+
}
52+
else {
53+
project.dependencies.project(path:path)
54+
}
55+
}
56+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2015 original authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.grails.gradle.plugin.run
17+
18+
import org.gradle.api.tasks.JavaExec
19+
20+
/**
21+
* Extension to the standard JavaExec task to run Grails applications
22+
*
23+
* @author Graeme Rocher
24+
* @since 3.2
25+
*/
26+
class GrailsRunTask extends JavaExec {
27+
}

0 commit comments

Comments
 (0)