Skip to content

Commit b6c9f59

Browse files
committed
fix profile resolution from inside of a grails project
1 parent fa7bfe2 commit b6c9f59

File tree

16 files changed

+90
-133
lines changed

16 files changed

+90
-133
lines changed

grails-doc/src/en/guide/profiles/profileInheritance.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ One profile can extend one or many different parent profiles. To define profile
2222
[source,groovy]
2323
----
2424
dependencies {
25-
profileRuntimeOnly "org.apache.grails.profiles:base:{version}"
25+
profileRuntimeApi "org.apache.grails.profiles:base:{version}"
2626
}
2727
----
2828

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

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import org.gradle.api.Task
3636
import org.gradle.api.artifacts.Configuration
3737
import org.gradle.api.artifacts.Dependency
3838
import org.gradle.api.artifacts.DependencyResolveDetails
39+
import org.gradle.api.artifacts.DependencySet
3940
import org.gradle.api.file.Directory
4041
import org.gradle.api.file.DuplicatesStrategy
4142
import org.gradle.api.file.FileCollection
@@ -79,7 +80,6 @@ import javax.inject.Inject
7980
@CompileStatic
8081
class GrailsGradlePlugin extends GroovyPlugin {
8182
public static final String APPLICATION_CONTEXT_COMMAND_CLASS = 'grails.dev.commands.ApplicationCommand'
82-
public static final String PROFILE_CONFIGURATION = 'profile'
8383

8484
protected static final List<String> CORE_GORM_LIBRARIES = ['async', 'core', 'simple', 'web', 'rest-client', 'gorm', 'gorm-validation', 'gorm-plugin-support', 'gorm-support', 'test-support', 'hibernate-core', 'gorm-test', 'rx', 'rx-plugin-support']
8585
// NOTE: mongodb, neo4j etc. should NOT be included here so they can be independently versioned
@@ -269,11 +269,28 @@ class GrailsGradlePlugin extends GroovyPlugin {
269269
}
270270

271271
protected void configureProfile(Project project) {
272-
if(!project.configurations.names.contains(PROFILE_CONFIGURATION)) {
273-
project.configurations.register(PROFILE_CONFIGURATION).configure { Configuration profileConfiguration ->
274-
profileConfiguration.incoming.beforeResolve() {
275-
if (!profileConfiguration.allDependencies) {
276-
addDefaultProfile(project, profileConfiguration)
272+
if(!project.configurations.names.contains(GrailsClasspathToolingModelBuilder.PROFILE_CONFIGURATION_NAME)) {
273+
project.configurations.register(GrailsClasspathToolingModelBuilder.PROFILE_CONFIGURATION_NAME).configure { Configuration profileConfiguration ->
274+
profileConfiguration.description = "Configuration that allows for finding profile artifacts so commands, scripts, and other helpers can be found by the Grails Shell"
275+
profileConfiguration.canBeConsumed = false
276+
profileConfiguration.canBeResolved = true
277+
profileConfiguration.transitive = true
278+
279+
profileConfiguration.defaultDependencies { DependencySet deps ->
280+
String defaultProfileCoordinates = "org.apache.grails.profiles:${System.getProperty("grails.profile") ?: getDefaultProfile()}:${project.properties['grailsVersion'] ?: BuildSettings.grailsVersion}" as String
281+
project.logger.info('No Grails profile is defined for project {}, defaulting to: {}', project.name, defaultProfileCoordinates)
282+
deps.add (
283+
project.dependencies.create(defaultProfileCoordinates)
284+
)
285+
}
286+
287+
profileConfiguration.resolutionStrategy.eachDependency { details ->
288+
if(details.requested.group == 'org.apache.grails.profiles' && !details.requested.version) {
289+
String grailsVersion = (project.findProperty('grailsVersion') ?: BuildSettings.grailsVersion) as String
290+
project.logger.info('Dependency: {}:{} did not define a version, defaulting to grails version {}', details.requested.group, details.requested.name, grailsVersion)
291+
292+
details.useVersion(grailsVersion)
293+
details.because("Grails Profile defined without a version, defaulting to configured Grails Version")
277294
}
278295
}
279296
}
@@ -317,12 +334,6 @@ class GrailsGradlePlugin extends GroovyPlugin {
317334
'web'
318335
}
319336

320-
void addDefaultProfile(Project project, Configuration profileConfig) {
321-
def bomProject = project.rootProject.subprojects.find { it.name == 'grails-bom' }
322-
project.dependencies.add(PROFILE_CONFIGURATION, project.dependencies.platform(bomProject ?: "org.apache.grails:grails-bom:${project.properties.get('grailsVersion')}"))
323-
project.dependencies.add(PROFILE_CONFIGURATION, "org.apache.grails.profiles:${System.getProperty("grails.profile") ?: defaultProfile}:")
324-
}
325-
326337
@CompileDynamic
327338
protected Task createBuildPropertiesTask(Project project) {
328339
if (project.tasks.findByName('buildProperties') == null) {

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/model/GrailsClasspathToolingModelBuilder.groovy

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder
3030
*/
3131
@CompileStatic
3232
class GrailsClasspathToolingModelBuilder implements ToolingModelBuilder {
33+
public static final String PROFILE_CONFIGURATION_NAME = "profile"
34+
3335
@Override
3436
boolean canBuild(String modelName) {
3537
return modelName == GrailsClasspath.name
3638
}
3739

3840
@Override
3941
Object buildAll(String modelName, Project project) {
40-
// testRuntimeClasspath includes provided
4142
try {
42-
4343
List<URL> runtimeDependencies = project.getConfigurations().getByName("testRuntimeClasspath").getResolvedConfiguration().getResolvedArtifacts().collect { ResolvedArtifact artifact ->
4444
artifact.getFile().toURI().toURL()
4545
}
4646

4747
DefaultGrailsClasspath grailsClasspath = new DefaultGrailsClasspath(dependencies: runtimeDependencies)
4848

49-
Configuration profileConfiguration = project.getConfigurations().getByName("profile")
49+
Configuration profileConfiguration = project.getConfigurations().getByName(PROFILE_CONFIGURATION_NAME)
5050
if (profileConfiguration != null) {
51-
grailsClasspath.profileDependencies = profileConfiguration.getResolvedConfiguration().getResolvedArtifacts().collect() { ResolvedArtifact artifact ->
52-
artifact.getFile().toURI().toURL()
51+
grailsClasspath.profileDependencies = profileConfiguration.resolvedConfiguration.resolvedArtifacts.collect() { ResolvedArtifact artifact ->
52+
artifact.file.toURI().toURL()
5353
}
5454
}
5555
return grailsClasspath

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy

Lines changed: 38 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,16 @@ import org.gradle.api.Plugin
2222
import org.gradle.api.Project
2323
import org.gradle.api.Task
2424
import org.gradle.api.artifacts.Configuration
25-
import org.gradle.api.attributes.AttributeCompatibilityRule
26-
import org.gradle.api.attributes.Bundling
2725
import org.gradle.api.attributes.Category
28-
import org.gradle.api.attributes.CompatibilityCheckDetails
29-
import org.gradle.api.attributes.LibraryElements
3026
import org.gradle.api.attributes.Usage
31-
import org.gradle.api.component.AdhocComponentWithVariants
3227
import org.gradle.api.component.SoftwareComponentFactory
3328
import org.gradle.api.file.CopySpec
3429
import org.gradle.api.file.Directory
3530
import org.gradle.api.file.SyncSpec
3631
import org.gradle.api.model.ObjectFactory
3732
import org.gradle.api.plugins.BasePlugin
33+
import org.gradle.api.plugins.GroovyPlugin
34+
import org.gradle.api.plugins.JavaLibraryPlugin
3835
import org.gradle.api.tasks.TaskProvider
3936
import org.gradle.api.tasks.bundling.Jar
4037
import org.grails.gradle.plugin.profiles.tasks.ProfileCompilerTask
@@ -52,11 +49,8 @@ import static org.gradle.api.plugins.BasePlugin.BUILD_GROUP
5249
@CompileStatic
5350
class GrailsProfileGradlePlugin implements Plugin<Project> {
5451

55-
static final String USAGE_PROFILE_NAME = 'profile-runtime'
56-
static final String COMPONENT_NAME = 'profile'
57-
static final String RUNTIME_API_CONFIGURATION = 'profileRuntimeApi'
58-
// to add dependencies for that profile's scripts
59-
static final String RUNTIME_ONLY_CONFIGURATION = 'profileRuntimeOnly' // to be used to extend profiles
52+
// to be used to extend profiles
53+
static final String PROFILE_API_CONFIGURATION = 'profileRuntimeApi'
6054

6155
private final SoftwareComponentFactory softwareComponentFactory
6256
private final ObjectFactory objectFactory
@@ -70,50 +64,26 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
7064
@Override
7165
void apply(Project project) {
7266
project.pluginManager.apply(BasePlugin)
73-
74-
Usage profileUsage = objectFactory.named(Usage, USAGE_PROFILE_NAME)
75-
76-
project.dependencies.attributesSchema {
77-
it.attribute(Usage.USAGE_ATTRIBUTE) {
78-
it.compatibilityRules.add(JavaRuntimeCompatibility)
67+
project.pluginManager.apply(GroovyPlugin)
68+
project.pluginManager.apply(JavaLibraryPlugin)
69+
70+
NamedDomainObjectProvider<Configuration> runtimeOnlyConfiguration = project.configurations.register(PROFILE_API_CONFIGURATION)
71+
runtimeOnlyConfiguration.configure { Configuration config ->
72+
config.description = 'Profiles to inherit for this profile project'
73+
config.canBeConsumed = true
74+
config.canBeResolved = true
75+
76+
config.attributes {
77+
it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage, Usage.JAVA_RUNTIME))
78+
it.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category, Category.LIBRARY))
7979
}
8080
}
8181

82-
AdhocComponentWithVariants profileComponent = softwareComponentFactory.adhoc(COMPONENT_NAME)
83-
project.components.add(profileComponent)
82+
project.configurations.named("apiElements")
83+
.configure { it.extendsFrom(runtimeOnlyConfiguration.get()) }
8484

85-
NamedDomainObjectProvider<Configuration> runtimeApiConfiguration = project.configurations.register(RUNTIME_API_CONFIGURATION)
86-
runtimeApiConfiguration.configure { Configuration it ->
87-
it.description = 'Dependencies exported transitively to other profile projects'
88-
it.canBeConsumed = false
89-
it.canBeResolved = false
90-
it.attributes {
91-
it.attribute(Usage.USAGE_ATTRIBUTE, profileUsage)
92-
it.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objectFactory.named(LibraryElements, LibraryElements.CLASSES))
93-
it.attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category, Category.LIBRARY))
94-
it.attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling, Bundling.EXTERNAL))
95-
}
96-
profileComponent.addVariantsFromConfiguration(it) {
97-
it.mapToMavenScope('compile')
98-
}
99-
}
100-
101-
NamedDomainObjectProvider<Configuration> runtimeOnlyConfiguration = project.configurations.register(RUNTIME_ONLY_CONFIGURATION)
102-
runtimeOnlyConfiguration.configure { Configuration it ->
103-
it.description = 'Dependencies required to compile a profile project'
104-
it.canBeConsumed = true
105-
it.canBeResolved = true
106-
it.extendsFrom(runtimeApiConfiguration.get())
107-
it.attributes {
108-
it.attribute(Usage.USAGE_ATTRIBUTE, profileUsage)
109-
it.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objectFactory.named(LibraryElements, LibraryElements.JAR))
110-
it.attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category, Category.LIBRARY))
111-
it.attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling, Bundling.EXTERNAL))
112-
}
113-
profileComponent.addVariantsFromConfiguration(it) {
114-
it.mapToMavenScope('runtime')
115-
}
116-
}
85+
project.configurations.named("runtimeElements")
86+
.configure { it.extendsFrom(runtimeOnlyConfiguration.get()) }
11787

11888
TaskProvider<Task> processProfileResourcesTask = project.tasks.register('processProfileResources')
11989
processProfileResourcesTask.configure { Task task ->
@@ -203,22 +173,21 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
203173
}
204174
return null
205175
}
206-
it.classpath = runtimeOnlyConfiguration.get()
176+
it.classpath = project.files(runtimeOnlyConfiguration.get(), project.configurations.named('runtimeClasspath').get())
207177
}
208178

209-
TaskProvider<Jar> jarTask = project.tasks.register('profileJar', Jar)
179+
TaskProvider<Jar> jarTask = project.tasks.named('jar', Jar)
210180
jarTask.configure { Jar jar ->
211-
jar.group = BUILD_GROUP
212-
jar.dependsOn(processProfileResourcesTask, compileTask, project.tasks.named('jar', Jar).orNull)
181+
jar.dependsOn(processProfileResourcesTask, compileTask)
213182

214183
jar.from(project.files(project.layout.buildDirectory.dir('resources/profile'), project.layout.buildDirectory.dir('classes/profile')))
215-
jar.destinationDirectory.set(project.layout.buildDirectory.dir('libs'))
216-
jar.description = 'Assembles a jar archive containing the profile classes.'
217184
jar.reproducibleFileOrder = true
218185
jar.preserveFileTimestamps = false
186+
jar.dirMode = 0755 // To avoid platform specific defaults
187+
jar.fileMode = 0644 // to avoid platform specific defaults
219188
}
220189

221-
TaskProvider<Jar> sourcesJarTask = project.tasks.register('sourcesProfileJar', Jar)
190+
TaskProvider<Jar> sourcesJarTask = project.tasks.register('sourcesJar', Jar)
222191
sourcesJarTask.configure { Jar jar ->
223192
jar.from(project.layout.projectDirectory.dir('commands'))
224193
if (project.file('profile.yml').exists()) {
@@ -235,7 +204,8 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
235204
jar.description = 'Assembles a jar archive containing the profile sources.'
236205
jar.reproducibleFileOrder = true
237206
jar.preserveFileTimestamps = false
238-
jar.group = BUILD_GROUP
207+
jar.dirMode = 0755 // To avoid platform specific defaults
208+
jar.fileMode = 0644 // to avoid platform specific defaults
239209
}
240210

241211
def profileReadme = project.layout.buildDirectory.file('profile.txt')
@@ -251,8 +221,17 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
251221
}
252222
}
253223

254-
TaskProvider<Jar> javadocJarTask = project.tasks.register('javadocProfileJar', Jar)
224+
project.tasks.named('javadoc').configure {
225+
it.enabled = false // will replace the java doc
226+
}
227+
228+
TaskProvider<Jar> javadocJarTask = project.tasks.register('javadocJar', Jar)
255229
javadocJarTask.configure { Jar jar ->
230+
jar.reproducibleFileOrder = true
231+
jar.preserveFileTimestamps = false
232+
jar.dirMode = 0755 // To avoid platform specific defaults
233+
jar.fileMode = 0644 // to avoid platform specific defaults
234+
256235
jar.dependsOn(readmeGeneration)
257236
// https://central.sonatype.org/publish/requirements/#supply-javadoc-and-sources
258237
jar.from(profileReadme) { CopySpec spec ->
@@ -262,25 +241,6 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
262241
jar.destinationDirectory.set(new File(project.layout.buildDirectory.asFile.get(), 'libs'))
263242
jar.description = 'Assembles a jar archive containing the profile javadoc.'
264243
jar.group = BUILD_GROUP
265-
jar.reproducibleFileOrder = true
266-
jar.preserveFileTimestamps = false
267-
}
268-
269-
project.tasks.named('assemble').configure { Task it ->
270-
it.dependsOn(jarTask)
271-
}
272-
}
273-
}
274-
275-
/**
276-
* I'm not sure why a separate configuration was originally created for the profiles, but maybe they are combined
277-
* into a single gradle project. For compatibility purposes, treat java-runtime as a usable substitute
278-
*/
279-
class JavaRuntimeCompatibility implements AttributeCompatibilityRule<Usage> {
280-
@Override
281-
void execute(CompatibilityCheckDetails<Usage> d) {
282-
if (d.consumerValue.name == GrailsProfileGradlePlugin.USAGE_PROFILE_NAME && d.producerValue.name == Usage.JAVA_RUNTIME) {
283-
d.compatible()
284244
}
285245
}
286246
}

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfilePublishGradlePlugin.groovy

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ package org.grails.gradle.plugin.profiles
2121
import groovy.transform.CompileStatic
2222
import org.gradle.api.GradleException
2323
import org.gradle.api.Project
24-
import org.gradle.api.attributes.Usage
2524
import org.gradle.api.model.ObjectFactory
2625
import org.gradle.api.publish.maven.MavenPublication
2726
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
@@ -75,18 +74,6 @@ class GrailsProfilePublishGradlePlugin extends GrailsPublishGradlePlugin {
7574

7675
@Override
7776
protected void doAddArtefact(Project project, MavenPublication publication) {
78-
publication.from(project.components.named(GrailsProfileGradlePlugin.COMPONENT_NAME).get())
79-
publication.artifact(project.tasks.named('profileJar'))
80-
publication.artifact(project.tasks.named('sourcesProfileJar'))
81-
publication.artifact(project.tasks.named('javadocProfileJar'))
82-
83-
publication.versionMapping {
84-
it.variant(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage, GrailsProfileGradlePlugin.USAGE_PROFILE_NAME)) {
85-
it.fromResolutionOf(GrailsProfileGradlePlugin.RUNTIME_API_CONFIGURATION)
86-
}
87-
it.variant(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage, GrailsProfileGradlePlugin.USAGE_PROFILE_NAME)) {
88-
it.fromResolutionOf(GrailsProfileGradlePlugin.RUNTIME_ONLY_CONFIGURATION)
89-
}
90-
}
77+
publication.from project.components.named('java').get()
9178
}
9279
}

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/profiles/tasks/ProfileCompilerTask.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class ProfileCompilerTask extends AbstractCompile {
139139

140140
if (!profileData.containsKey('extends')) {
141141
List<String> dependencies = []
142-
project.configurations.named(GrailsProfileGradlePlugin.RUNTIME_ONLY_CONFIGURATION).get().dependencies.all { Dependency d ->
142+
project.configurations.named(GrailsProfileGradlePlugin.PROFILE_API_CONFIGURATION).get().dependencies.all { Dependency d ->
143143
String profileName = d.name
144144
if (d instanceof DefaultProjectDependency) {
145145
DefaultProjectDependency projectDependency = (DefaultProjectDependency) d

grails-profiles/base/build.gradle

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717
plugins {
18-
id 'groovy'
1918
id 'org.apache.grails.gradle.grails-profile'
2019
}
2120

@@ -30,9 +29,9 @@ ext {
3029
}
3130

3231
dependencies {
33-
profileRuntimeApi platform(project(':grails-bom'))
34-
profileRuntimeApi project(':grails-shell-cli')
35-
profileRuntimeApi 'org.apache.groovy:groovy-jmx' // stop script uses GroovyMBean
32+
implementation platform(project(':grails-bom'))
33+
api project(':grails-shell-cli')
34+
api 'org.apache.groovy:groovy-jmx' // stop script uses GroovyMBean
3635
}
3736

3837
TaskProvider<Copy> copyWrapper = tasks.register('copyGrailsWrapperScripts', Copy)
@@ -47,7 +46,7 @@ copyWrapper.configure { Copy copy ->
4746
copy.into(project.layout.projectDirectory.dir('skeleton'))
4847
}
4948

50-
tasks.named('sourcesProfileJar').configure {
49+
tasks.named('sourcesJar').configure {
5150
it.dependsOn(copyWrapper)
5251
}
5352

grails-profiles/plugin/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717
plugins {
18-
id 'groovy'
1918
id 'org.apache.grails.gradle.grails-profile'
2019
}
2120

@@ -30,7 +29,7 @@ ext {
3029
}
3130

3231
dependencies {
33-
profileRuntimeOnly project(":grails-profiles-base")
32+
profileRuntimeApi project(":grails-profiles-base")
3433
}
3534

3635
apply {

0 commit comments

Comments
 (0)