Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Groovy 4 for projects, Groovy 3 for Gradle plugins #337

Merged
merged 2 commits into from
Sep 22, 2024

Conversation

codeconsole
Copy link
Contributor

@codeconsole codeconsole commented Sep 21, 2024

If groovyVersion is set to 3.x, forces groovy 3. if `groovyVersion is set to 4.x, forces groovy 4.

No need for adding a bunch one configure code to every project.

FYI @jamesfredley the groovy 3 version used by gradle is whatever groovy version that is set by the project. Setting the version to GroovySystem.version will not be the same for every project unless it is explicitly set using groovyVersion

@codeconsole
Copy link
Contributor Author

codeconsole commented Sep 21, 2024

So you don't have to add thing like gpc/fields#356

    configurations.configureEach {
        resolutionStrategy.eachDependency { DependencyResolveDetails details ->
            if ((details.requested.group == 'org.codehaus.groovy' || details.requested.group == 'org.apache.groovy') && details.requested.name != 'groovy-bom') {
                details.useTarget(group: 'org.codehaus.groovy', name: details.requested.name, version: "$GroovySystem.version")
                details.because "Use version of Groovy provided by Gradle"
            }
        }
    }

if grails-gradle-plugin is used by the project

If we are trying to keep all our projects coordinated, we should try and eliminate these configurations blocks in all of them.

@matrei
Copy link
Contributor

matrei commented Sep 21, 2024

the groovy 3 version used by gradle is whatever groovy version that is set by the project. Setting the version to GroovySystem.version will not be the same for every project unless it is explicitly set using groovyVersion

I might be misunderstanding you here, but I'm not sure this statement is correct. Try the following gradle task:

tasks.register('printGroovyVersions') {
    doLast {
        println "Project Groovy version: ${project.findProperty('groovyVersion')}"
        println "Gradle Groovy version: $GroovySystem.version"
    }
}

@jamesfredley
Copy link
Contributor

jamesfredley commented Sep 21, 2024

@codeconsole I love centralizing the config in the grails-gradle-plugin, and that is the predominant case. But there are some exceptions that will need to be supported.

This may need some modifications for the following, I'll figure that out as I get that work for grails-core wrapped up and then test this against it.

Gradle still using 3.0.x presents the need for projects to have 3.0.x used for compileOnly on Gradle Plugins and dependencies used by Gradle Plugins, while groovyVersion is set to 4.0.x, such as in grails-core. And in cases like grails-shell and grails-boot in grails-core, after it is compiled with 3.0.x, we then test it with 4.0.x to make sure it is cross version compatible, since it will be run in 3.0.x by Gradle during build in other projects and 4.0.x when the Grails project runs tasks other than build.

I really wish Gradle was on 4.0.x, because this work to compile with Gradle's version seems unuseful, but needs to happen to prevent releases that don't run during the build.

And then buildSrc and buildscript{} are being run in Groovy 3.0.x by gradle, even when dependencies have been forced to org.apache.groovy with 4.0.x. That works fine as long as the package in the code exists in the org.apache.groovy jars, which still includes several org.codehause.groovy packages in addition to org.apache.groovy packages.

@jamesfredley
Copy link
Contributor

We have been able to remove most of the version override blocks with the current grails-gradle-plugin. For example there are none in my fork of your website demo for Grails 7, since we have migrated all of the dependencies to 4.

Projects with dependencies like io.github.groovylang.groovydoc:groovydoc-gradle-plugin:1.0.1 are a current exception, because it is on groovy 2.x.

@jamesfredley
Copy link
Contributor

grails-core is not using the grails-gradle-plugin during build, so this change will not impact the work in grails/grails-core#13653.

@codeconsole
Copy link
Contributor Author

the groovy 3 version used by gradle is whatever groovy version that is set by the project. Setting the version to GroovySystem.version will not be the same for every project unless it is explicitly set using groovyVersion

I might be misunderstanding you here, but I'm not sure this statement is correct. Try the following gradle task:

tasks.register('printGroovyVersions') {
    doLast {
        println "Project Groovy version: ${project.findProperty('groovyVersion')}"
        println "Gradle Groovy version: $GroovySystem.version"
    }
}

@matrei This was the behavior I observed, perhaps coincidental when I set groovyVersion to 3.0.22 in the fields plugin? Is the default groovy for 8.10.1 really 3.0.22??

./gradlew --version

------------------------------------------------------------
Gradle 8.10.1
------------------------------------------------------------

Build time:    2024-09-09 07:42:56 UTC
Revision:      8716158d3ec8c59e38f87a67f1f311f297b79576

Kotlin:        1.9.24
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM:  21.0.2 (Oracle Corporation 21.0.2+13-58)

I assumed that since Gradle can't upgrade to 4, they most likely can not keep the Gradle Groovy version up to date.

Either way, this code works by setting any Groovy 3 version to GroovySystem.version if groovyVersion is set which is the intention of the code.

@codeconsole
Copy link
Contributor Author

@jamesfredley this code only works if groovyVersion is set. If it is not set, it does nothing.

details.useTarget "org.apache.groovy:groovy:$groovyVersion"
} else {
details.useTarget "org.apache.groovy:$dependencyName:$groovyVersion"
if (groovyVersion.startsWith("4.")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should flip this if/else so that it works without change when we go to Groovy 5. Something like this:


            if (groovyVersion.startsWith("3.")) {
                project.configurations.configureEach { Configuration configuration ->
                    configuration.resolutionStrategy.eachDependency { DependencyResolveDetails details ->
                        if ((details.requested.group == 'org.codehaus.groovy' || details.requested.group == 'org.apache.groovy') && details.requested.name != 'groovy-bom') {
                            details.useTarget(group: 'org.codehaus.groovy', name: details.requested.name, version: "$GroovySystem.version")
                            details.because "Use Groovy version $GroovySystem.version provided by Gradle"
                        }
                    }
                }
            } else {
                project.configurations.configureEach { Configuration configuration ->
                    configuration.resolutionStrategy.eachDependency { DependencyResolveDetails details ->
                        String dependencyName = details.requested.name
                        String group = details.requested.group
                        if (group == 'org.codehaus.groovy') {
                            if (dependencyName == 'groovy-all') {
                                details.useTarget "org.apache.groovy:groovy:$groovyVersion"
                            } else {
                                details.useTarget "org.apache.groovy:$dependencyName:$groovyVersion"
                            }
                            details.because("Groovy version substituted for Groovy $groovyVersion")
                        } else if (group == 'org.apache.groovy' && dependencyName.startsWith('groovy')) {
                            details.useVersion(groovyVersion)
                        }
                    }
                }
            }

@jamesfredley
Copy link
Contributor

I've tested this on grails-profile:base, gorm-hibernate5 and fields. On fields it is not yet possible to remove the groovy substitution from buildscript{}.

A problem occurred configuring root project 'fields'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not resolve org.codehaus.groovy:groovy-groovydoc:2.4.6.
     Required by:
         root project : > io.github.groovylang.groovydoc:groovydoc-gradle-plugin:1.0.1
      > Module 'org.codehaus.groovy:groovy-groovydoc' has been rejected:
           Cannot select module with conflict on capability 'org.codehaus.groovy:groovy-groovydoc:2.4.6' also provided by [org.apache.groovy:groovy-groovydoc:4.0.22(groovyRuntimeElements)]

@codeconsole
Copy link
Contributor Author

I've tested this on grails-profile:base, gorm-hibernate5 and fields. On fields it is not yet possible to remove the groovy substitution from buildscript{}.

A problem occurred configuring root project 'fields'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not resolve org.codehaus.groovy:groovy-groovydoc:2.4.6.
     Required by:
         root project : > io.github.groovylang.groovydoc:groovydoc-gradle-plugin:1.0.1
      > Module 'org.codehaus.groovy:groovy-groovydoc' has been rejected:
           Cannot select module with conflict on capability 'org.codehaus.groovy:groovy-groovydoc:2.4.6' also provided by [org.apache.groovy:groovy-groovydoc:4.0.22(groovyRuntimeElements)]

@jamesfredley
You have to set the groovyVersion in gradle.properties. Otherwise it does nothing. I tested it on fields and it worked.

jamesfredley

This comment was marked as resolved.

@codeconsole codeconsole merged commit b5f8479 into grails:7.0.x Sep 22, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants