matrei commented on code in PR #14836:
URL: https://github.com/apache/grails-core/pull/14836#discussion_r2173797876
##########
.github/workflows/gradle.yml:
##########
@@ -91,6 +95,63 @@ jobs:
./gradlew build :grails-shell-cli:installDist groovydoc
--continue --stacktrace -PonlyCoreTests
--rerun-tasks
+ buildForge:
+ name: "🔨Grails Forge"
+ if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
+ strategy:
+ fail-fast: false
+ matrix:
+ java: [ 17, 21 ]
+ runs-on: ubuntu-24.04
+ steps:
+ - name: "Output Agent IP" # in the event RAO blocks this agent, this can
be used to debug it
+ run: curl -s https://api.ipify.org
+ - name: "📥 Checkout repository"
+ uses: actions/checkout@v4
+ - name: "☕️ Setup JDK"
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'liberica'
+ java-version: ${{ matrix.java }}
+ - name: "🐘 Setup Gradle"
+ uses: gradle/actions/setup-gradle@v4
+ with:
+ develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }}
+ - name: "🔨 Build project without tests"
+ if: ${{ contains(github.event.head_commit.message, '[skip tests]') }}
Review Comment:
Will this ever be `true`, as there is a condition on the `job`?
##########
.github/workflows/gradle.yml:
##########
@@ -91,6 +95,63 @@ jobs:
./gradlew build :grails-shell-cli:installDist groovydoc
--continue --stacktrace -PonlyCoreTests
--rerun-tasks
+ buildForge:
+ name: "🔨Grails Forge"
+ if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
+ strategy:
+ fail-fast: false
+ matrix:
+ java: [ 17, 21 ]
+ runs-on: ubuntu-24.04
+ steps:
+ - name: "Output Agent IP" # in the event RAO blocks this agent, this can
be used to debug it
+ run: curl -s https://api.ipify.org
+ - name: "📥 Checkout repository"
+ uses: actions/checkout@v4
+ - name: "☕️ Setup JDK"
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'liberica'
+ java-version: ${{ matrix.java }}
+ - name: "🐘 Setup Gradle"
+ uses: gradle/actions/setup-gradle@v4
+ with:
+ develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }}
+ - name: "🔨 Build project without tests"
+ if: ${{ contains(github.event.head_commit.message, '[skip tests]') }}
+ working-directory: 'grails-forge'
+ run: >
+ ./gradlew build
+ --continue --stacktrace -PskipTests
+ - name: "🔨 Build project with tests"
+ if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
Review Comment:
Won't this condition always be `true`, if it has passed the condition on the
`job`?
##########
gradle/publish-root-config.gradle:
##########
@@ -139,6 +139,12 @@ subprojects {
}
}
+tasks.register('publishAllPublicationsToTestCaseMavenRepoRepository').configure
{
+ dependsOn(subprojects.findAll { it.name in publishedProjects }
+ .collect { p ->
p.tasks.named('publishAllPublicationsToTestCaseMavenRepoRepository') }
+ .flatten())
+}
Review Comment:
- Do we need `.flatten()`?
```groovy
dependsOn(
subprojects
.findAll { it.name in publishedProjects }
.collect {
it.tasks.named('publishAllPublicationsToTestCaseMavenRepoRepository') }
)
```
##########
grails-forge/build.gradle:
##########
@@ -53,16 +53,28 @@ allprojects {
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*',
'.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
}
}
+ maven {
+ url = 'https://repository.apache.org/content/groups/staging'
+ content {
+ includeGroupByRegex 'org[.]apache[.]grails.*'
Review Comment:
Align on parentheses for method calls?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
Review Comment:
No need to be explicit with `project.`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
Review Comment:
Align on space after `if`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
Review Comment:
No need for explicit `it.`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
Review Comment:
Remove empty line?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
+
Review Comment:
Remove empty line?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
Review Comment:
Simplify?
```groovy
checksumDir.eachFileMatch(~/.*\.sha512/) {
def jarName = it.name - '.sha512'
def checksumLine = it.text.trim()
def checksum = checksumLine.tokenize().first()
writer.println("$jarName $checksum")
}
```
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
+ }
+ }
+ }
+
+ println "Checksum manifest written to ${outputFile}"
+ }
+}
+
+aggregatePublishedArtifacts.configure {
+ group = "publishing"
+ description = "Aggregates all published artifacts from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-artifacts.txt")
Review Comment:
Align on single quotes for strings?
##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/publishing/GrailsPublishExtension.groovy:
##########
@@ -132,11 +206,11 @@ class GrailsPublishExtension {
static final License APACHE2 = new License(name: 'The Apache Software
License, Version 2.0', url: 'https://www.apache.org/licenses/LICENSE-2.0.txt')
static final License EPL1 = new License(name: 'Eclipse Public License
- v 1.0', url: 'https://www.eclipse.org/legal/epl-v10.html')
- static final License LGPL21 = new License(name: 'GNU Lesser General
Public License, version 2.1', url:
'http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html')
- static final License LGPL = new License(name: 'GNU Lesser General
Public License', url: 'http://www.gnu.org/licenses/lgpl-3.0.html')
- static final License GPL = new License(name: 'GNU General Public
License', url: 'http://www.gnu.org/licenses/gpl-3.0.en.html')
+ static final License LGPL21 = new License(name: 'GNU Lesser General
Public License, version 2.1', url:
'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html')
+ static final License LGPL = new License(name: 'GNU Lesser General
Public License', url: 'https://www.gnu.org/licenses/lgpl-3.0.html')
+ static final License GPL = new License(name: 'GNU General Public
License', url: 'https://www.gnu.org/licenses/gpl-3.0.en.html')
static final License CPL = new License(name: "Common Public License
Version 1.0 (CPL)", url: "https://opensource.org/licenses/cpl1.0.php")
- static final License AGPL = new License(name: "GNU Affero General
Public License", url: "http://www.gnu.org/licenses/agpl-3.0.html")
+ static final License AGPL = new License(name: "GNU Affero General
Public License", url: "https://www.gnu.org/licenses/agpl-3.0.html")
static final License MIT = new License(name: "The MIT License (MIT)",
url: "https://opensource.org/licenses/MIT")
static final License BSD = new License(name: "The BSD 3-Clause
License", url: "https://opensource.org/licenses/BSD-3-Clause")
Review Comment:
Align on single quotes for strings?
##########
grails-gradle/build.gradle:
##########
@@ -27,10 +27,12 @@ file('../gradle.properties').withInputStream {
allprojects {
repositories {
// mavenLocal() // Keep, this will be uncommented and used by CI
(groovy-joint-workflow)
+ maven { url = 'https://repo.grails.org/grails/restricted' }
+ mavenCentral()
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*',
'.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
Review Comment:
- Align on parentheses for method calls?
- Do we need the inner parentheses for `((grails)|(groovy))`?
- I see that we sometimes use `'.*SNAPSHOT'` and sometimes `'.*-SNAPSHOT'`,
can we align on one way?
##########
.github/workflows/gradle.yml:
##########
@@ -215,9 +284,11 @@ jobs:
path: grails-gradle/build/grails-gradle-artifacts.txt
publish:
needs: [ publishGradle, build, functional, hibernate5Functional,
mongodbFunctional ]
- if: ${{ always() && github.repository_owner == 'apache' &&
github.event_name == 'push' && needs.publishGradle.result == 'success' &&
(needs.build.result == 'success' || needs.build.result == 'skipped') &&
(needs.functional.result == 'success' || needs.functional.result == 'skipped')
&& (needs.hibernate5Functional.result == 'success' ||
needs.hibernate5Functional.result == 'skipped') &&
(needs.mongodbFunctional.result == 'success' || needs.mongodbFunctional.result
== 'skipped') }}
+ if: ${{ always() && github.repository_owner == 'apache' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
needs.publishGradle.result == 'success' && (needs.build.result == 'success' ||
needs.build.result == 'skipped') && (needs.functional.result == 'success' ||
needs.functional.result == 'skipped') && (needs.hibernate5Functional.result ==
'success' || needs.hibernate5Functional.result == 'skipped') &&
(needs.mongodbFunctional.result == 'success' || needs.mongodbFunctional.result
== 'skipped') }}
Review Comment:
- Is `always()` needed?
- Can we break this line after `${{`, after each `&&` and before the ending
`}}`?
##########
grails-forge/buildSrc/build.gradle:
##########
@@ -48,7 +48,13 @@ repositories {
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*', '.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
+ }
+ }
+ maven {
+ url = 'https://repository.apache.org/content/groups/staging'
+ content {
+ includeGroupByRegex 'org[.]apache[.]grails.*'
Review Comment:
Align on parentheses for method calls?
##########
grails-forge/build.gradle:
##########
@@ -53,16 +53,28 @@ allprojects {
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*',
'.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
Review Comment:
- Align on parentheses for method calls?
- Are the inner parentheses needed for `((grails)|(groovy))`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
Review Comment:
- No need to be explicit with `project.`?
- Align on single quotes for strings?
##########
.github/workflows/gradle.yml:
##########
@@ -91,6 +95,63 @@ jobs:
./gradlew build :grails-shell-cli:installDist groovydoc
--continue --stacktrace -PonlyCoreTests
--rerun-tasks
+ buildForge:
+ name: "🔨Grails Forge"
+ if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
Review Comment:
Should this condition be on the `job`, and then on the `steps` also?
##########
grails-forge/build.gradle:
##########
@@ -53,16 +53,28 @@ allprojects {
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*',
'.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
}
}
+ maven {
+ url = 'https://repository.apache.org/content/groups/staging'
+ content {
+ includeGroupByRegex 'org[.]apache[.]grails.*'
+ }
+ }
+ }
+
+ tasks.withType(Test).configureEach { Task testTask ->
Review Comment:
Remove redundant explicit closure parameter?
##########
build.gradle:
##########
@@ -46,17 +46,12 @@ ext {
allprojects {
repositories {
- // workaround for
https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/164
- maven {
- name = 'localGrailsBom'
- url = file("$rootDir/grails-bom/build/repo")
- content { includeModule 'org.apache.grails', 'grails-bom' }
- }
// mavenLocal() // Keep, this will be uncommented and used by CI
(groovy-joint-workflow)
+ maven { url = 'https://repo.grails.org/grails/restricted' }
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*', '.*',
'.*-SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*', '.*-SNAPSHOT'
Review Comment:
- Align on parentheses for method calls?
- Do we need the inner parentheses on `((grails)|(groovy))`?
##########
grails-forge/buildSrc/build.gradle:
##########
@@ -48,7 +48,13 @@ repositories {
maven {
url = 'https://repository.apache.org/content/groups/snapshots'
content {
- includeVersionByRegex 'org[.]apache[.]groovy.*', '.*','.*SNAPSHOT'
+ includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*',
'.*','.*SNAPSHOT'
Review Comment:
- Align on parentheses for method calls?
- Do we need the inner parentheses for `((grails)|(groovy))`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
Review Comment:
No need to be explicit with `project.`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
Review Comment:
No need to be explicit with `project.`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
Review Comment:
Align on single quotes for strings?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
Review Comment:
- Use groovy setter?
- No need for explicit `project.`?
- Align on single quotes for strings?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
Review Comment:
- No need to be explicit with `project.`?
- Align on single quotes for strings?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
Review Comment:
No need to be explicit with `it.`?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
Review Comment:
(Same comments as above)
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
Review Comment:
Remove empty line?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
Review Comment:
- Use type-safe API?
- Use `configureEach`?
- Remove redundant explicit closure parameters?
- Use list?
- Align on space after `if`?
```groovy
extensions.configure(PublishingExtension) {
it.publications.withType(MavenPublication).configureEach {
artifacts.each {
if (it.file.name in ['grails-plugin.xml', 'profile.yml']) {
return
}
filesToChecksum << it.file
}
}
}
```
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
+
+ File artifactsFile = artifactsDir.get().asFile
+ artifactsFile.mkdirs()
+
Review Comment:
Remove empty line?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
+
+ File artifactsFile = artifactsDir.get().asFile
+ artifactsFile.mkdirs()
+
+ artifacts.entrySet().each { Map.Entry<String, String>
entry ->
+ File published = new File(artifactsFile,
"${entry.key}.txt" as String)
+ published.text = entry.value
+ }
+ }
+ }
+ }
+
+ Set<String> publishTasks = tasks.names.findAll {
it.startsWith('publishMavenPublication') }
+ publishTasks.each { taskName ->
+ tasks.named(taskName).configure { publishTask ->
+ publishTask.finalizedBy checksumTask
Review Comment:
Align on parentheses for method calls?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
+
+ File artifactsFile = artifactsDir.get().asFile
+ artifactsFile.mkdirs()
+
+ artifacts.entrySet().each { Map.Entry<String, String>
entry ->
+ File published = new File(artifactsFile,
"${entry.key}.txt" as String)
+ published.text = entry.value
+ }
+ }
+ }
+ }
+
+ Set<String> publishTasks = tasks.names.findAll {
it.startsWith('publishMavenPublication') }
Review Comment:
Use `def`?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
Review Comment:
Align on single quotes for strings?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
Review Comment:
- Spacing?
- Get `findResults` closure logic its own line for readability?
##########
grails-forge/gradle/publish-config.gradle:
##########
@@ -29,4 +31,84 @@ extensions.configure(GrailsPublishExtension) {
it.developers = findProperty('pomDevelopers') as Map<String, String> ?:
[puneetbehl: 'Peter Behl']
it.pomCustomization = findProperty('pomCustomization') as Closure
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
+}
+
+apply plugin: 'org.gradle.crypto.checksum'
+
+afterEvaluate {
+ if (project.plugins.hasPlugin('signing')) {
+ if(System.getenv('TEST_BUILD_REPRODUCIBLE')) {
+ project.logger.lifecycle("Signing is disabled for this build to
test build reproducibility.")
+ project.tasks.withType(Sign).configureEach {
+ it.enabled = false
+ }
+ }
+ }
+ if (project.plugins.hasPlugin("maven-publish")) {
+ def checksumTask = tasks.register("publishedChecksums", Checksum)
+ checksumTask.configure { Checksum check ->
+ check.checksumAlgorithm = Checksum.Algorithm.SHA512
+
check.outputDirectory.set(project.layout.buildDirectory.dir("checksums"))
+ check.dependsOn(tasks.withType(Jar))
+ }
+
+ def artifactsDir = project.layout.buildDirectory.dir("artifacts")
+ def artifactsTask = tasks.register("savePublishedArtifacts") {
+ it.outputs.dir(artifactsDir)
+ it.dependsOn(tasks.withType(Jar))
+ }
+
+ gradle.taskGraph.whenReady {
+ List filesToChecksum = []
+ publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(artifact.file.name == 'grails-plugin.xml' ||
artifact.file.name == 'profile.yml') {
+ return
+ }
+ filesToChecksum << artifact.file
+ }
+ }
+
+ checksumTask.configure { Checksum check ->
+ check.inputFiles.setFrom(filesToChecksum.unique())
+ check.finalizedBy(artifactsTask)
+
+ }
+
+ artifactsTask.configure {
+ doLast {
+ Map<String, String> artifacts = [:]
+
project.publishing.publications.withType(MavenPublication).all {
MavenPublication publication ->
+ publication.artifacts.each { MavenArtifact artifact ->
+ if(!artifact.file.exists() || artifact.file.name
== 'grails-plugin.xml' || artifact.file.name == 'profile.yml') {
+ return
+ }
+
+ if(artifact.classifier) {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}:${artifact.classifier}"
as String
+ }
+ else {
+ artifacts[artifact.file.name] =
"${publication.groupId}:${publication.artifactId}:${publication.version}" as
String
+ }
+ }
+ }
+
+ File artifactsFile = artifactsDir.get().asFile
+ artifactsFile.mkdirs()
+
+ artifacts.entrySet().each { Map.Entry<String, String>
entry ->
+ File published = new File(artifactsFile,
"${entry.key}.txt" as String)
+ published.text = entry.value
+ }
Review Comment:
Simplify?
```groovy
artifacts.each { key, value ->
new File(artifactsFile, "${key}.txt").text = value
}
```
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
Review Comment:
Align on single quotes for strings?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
+ }
+ }
+ }
+
+ println "Checksum manifest written to ${outputFile}"
+ }
+}
+
+aggregatePublishedArtifacts.configure {
+ group = "publishing"
+ description = "Aggregates all published artifacts from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-artifacts.txt")
+ outputs.file(outputFileProvider)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('savePublishedArtifacts') ?
"${it.path}:savePublishedArtifacts" : null })
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.text = "" // clear previous
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def artifactsDir =
sub.layout.buildDirectory.dir("artifacts").get().asFile
+ if (artifactsDir.exists()) {
+ artifactsDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".txt")
+ }
+ })?.each { checksumFile ->
+ def artifactName = checksumFile.name - ".txt"
+ def coordinates = checksumFile.text.trim()
+ writer.println("${artifactName} ${coordinates}")
+ }
Review Comment:
Simplify?
```groovy
artifactsDir.eachFileMatch(~/.*\.txt/) {
def artifactName = it.name - '.txt'
def coordinates = it.text.trim()
writer.println("$artifactName $coordinates")
}
```
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
+ }
+ }
+ }
+
+ println "Checksum manifest written to ${outputFile}"
+ }
+}
+
+aggregatePublishedArtifacts.configure {
+ group = "publishing"
+ description = "Aggregates all published artifacts from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-artifacts.txt")
+ outputs.file(outputFileProvider)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('savePublishedArtifacts') ?
"${it.path}:savePublishedArtifacts" : null })
Review Comment:
- Spacing?
- Get `findResults` closure logic its own line for readability?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
+ }
+ }
+ }
+
+ println "Checksum manifest written to ${outputFile}"
+ }
+}
+
+aggregatePublishedArtifacts.configure {
+ group = "publishing"
+ description = "Aggregates all published artifacts from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-artifacts.txt")
+ outputs.file(outputFileProvider)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('savePublishedArtifacts') ?
"${it.path}:savePublishedArtifacts" : null })
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.text = "" // clear previous
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def artifactsDir =
sub.layout.buildDirectory.dir("artifacts").get().asFile
Review Comment:
Align on single quotes for strings?
##########
grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/gradle/GradleRepository.java:
##########
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2025 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.grails.forge.build.gradle;
+
+import io.micronaut.core.annotation.NonNull;
+import io.micronaut.core.order.Ordered;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public interface GradleRepository extends Ordered {
+ @NonNull
+ String toSnippet(String basePadding);
+
+ static Set<GradleRepository> getDefaultRepositories(String grailsVersion) {
+ Set<GradleRepository> repositories = new HashSet<>();
+
+ String overrideRepo = System.getenv("GRAILS_REPO_URL");
+ if (overrideRepo != null && !overrideRepo.isEmpty()) {
+ repositories.add(new DefaultGradleRepository(0, overrideRepo));
+ }
+ repositories.add(new MavenCentralRepository(repositories.size()));
+ repositories.add(new DefaultGradleRepository(repositories.size(),
"https://repo.grails.org/grails/restricted"));
+ if (grailsVersion.endsWith("SNAPSHOT")) {
+ repositories.add(new DefaultGradleRepository(
+ repositories.size(),
+ "https://repository.apache.org/content/groups/snapshots",
+ null,
+ List.of(
+ new VersionRegexRepoFilter(
+ "org[.]apache[.]((grails)|(groovy)).*",
".*", ".*-SNAPSHOT"
Review Comment:
Do we need the inner parentheses in `((grails)|(groovy))`?
##########
grails-gradle/build.gradle:
##########
@@ -39,8 +41,6 @@ allprojects {
includeVersionByRegex 'cloud[.]wondrify', '.*', '.*-SNAPSHOT'
Review Comment:
- Align on parentheses for method calls?
##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/publishing/GrailsPublishExtension.groovy:
##########
@@ -93,12 +113,66 @@ class GrailsPublishExtension {
/**
* If another process will add the components set this to false so only
the publication is created
*/
- Boolean addComponents = true
+ final Property<Boolean> addComponents
/**
* The name of the publication
*/
- String publicationName = 'maven'
+ final Property<String> publicationName
+
+ /**
+ * If set, a local repository will be setup for the given path with the
name 'TestCaseMavenRepo'. This can be useful
+ * when testing plugins locally with builds that can't make use of
includedBuild
+ */
+ final Property<Directory> testRepositoryPath
+
+ @Inject
+ GrailsPublishExtension(ObjectFactory objects, Project project) {
+ githubSlug = objects.property(String).convention(
+ project.provider {
+ project.findProperty('githubSlug') as String
+ }
+ )
+ websiteUrl = objects.property(String).convention(project.provider {
+ String githubSlug = githubSlug.getOrNull()
+ githubSlug ? "https://github.com/$githubSlug" as String : null
+ })
+ scmUrl = objects.property(String).convention(project.provider {
+ String githubSlug = githubSlug.getOrNull()
+ githubSlug ? "https://github.com/$githubSlug" as String : null
+ })
+ scmUrlConnection =
objects.property(String).convention(project.provider {
+ String githubSlug = githubSlug.getOrNull()
+ githubSlug ? "scm:[email protected]:${githubSlug}.git" as String :
null
+ })
+ vcsUrl = objects.property(String).convention(project.provider {
+ String githubSlug = githubSlug.getOrNull()
+ githubSlug ? "[email protected]:${githubSlug}.git" as String : null
+ })
+ developers = objects.mapProperty(String, String).convention([:])
+ title = objects.property(String).convention(project.provider {
project.name })
+ desc = objects.property(String).convention(project.provider {
+ title.getOrNull()
+ })
+ issueTrackerName =
objects.property(String).convention(project.provider {
+ String githubSlug = githubSlug.getOrNull()
+ githubSlug ? "GitHub Issues" as String : "Issues"
Review Comment:
- Align on single quotes for strings?
- Why `as String`?
##########
grails-forge/gradle/publish-root-config.gradle:
##########
@@ -28,4 +28,78 @@ subprojects {
if (name in publishedProjects) {
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
+}
+
+
+def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')
+
+tasks.register("aggregateChecksums").configure {
+ group = "publishing"
+ description = "Aggregates all SHA-256 checksums from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-checksums.txt")
+ outputs.file(outputFileProvider)
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('publishedChecksums') ?
"${it.path}:publishedChecksums" : null })
+ finalizedBy(aggregatePublishedArtifacts)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.withPrintWriter { writer ->
+ subprojects.each { sub ->
+ def checksumDir =
sub.layout.buildDirectory.dir("checksums").get().asFile
+ if (checksumDir.exists()) {
+ checksumDir.listFiles(new FilenameFilter() {
+ boolean accept(File dir, String name) {
+ return name.endsWith(".sha512")
+ }
+ })?.each { checksumFile ->
+ def jarName = checksumFile.name - ".sha512"
+ def checksumLine = checksumFile.text.trim()
+ def checksum = checksumLine.tokenize()[0]
+ writer.println("${jarName} ${checksum}")
+ }
+ }
+ }
+ }
+
+ println "Checksum manifest written to ${outputFile}"
+ }
+}
+
+aggregatePublishedArtifacts.configure {
+ group = "publishing"
+ description = "Aggregates all published artifacts from subprojects into a
single file."
+
+ def outputFileProvider =
rootProject.layout.buildDirectory.file("grails-forge-artifacts.txt")
+ outputs.file(outputFileProvider)
+
+ outputs.upToDateWhen { false } // not worth caching
+
+ dependsOn(subprojects.findResults
{it.tasks.names.contains('savePublishedArtifacts') ?
"${it.path}:savePublishedArtifacts" : null })
+
+ doLast {
+ def outputFile = outputFileProvider.get().asFile
+ outputFile.text = "" // clear previous
Review Comment:
Align on single quotes for strings?
##########
grails-forge/gradle/test-config.gradle:
##########
@@ -35,6 +35,9 @@ tasks.withType(Test).configureEach {
showStackTraces = true
}
+ setEnvironment([
+ 'GRAILS_REPO_URL': new File(rootProject.projectDir,
'../build/local-maven').canonicalFile.absolutePath
+ ])
Review Comment:
Will this overwrite any existing?
I think the docs is quite unclear:
https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html#setEnvironment(java.util.Map)
vs
https://docs.gradle.org/current/javadoc/org/gradle/process/ProcessForkOptions.html#environment(java.lang.String,java.lang.Object)
Should we use:
```groovy
environment('GRAILS_REPO_URL', new File(rootProject.projectDir,
'../build/local-maven').canonicalFile.absolutePath)
```
##########
grails-gradle/gradle/publish-root-config.gradle:
##########
@@ -45,6 +45,11 @@ if (isReleaseVersion) {
}
}
+tasks.register('publishAllPublicationsToTestCaseMavenRepoRepository').configure
{
+ dependsOn(subprojects
+ .collect { p ->
p.tasks.named('publishAllPublicationsToTestCaseMavenRepoRepository') }
+ .flatten())
Review Comment:
Is `.flatten()` necessary?
##########
grails-forge/grails-forge-core/src/main/java/org/grails/forge/application/generator/GeneratorContext.java:
##########
@@ -80,6 +83,10 @@ public GeneratorContext(Project project,
this.coordinateResolver = coordinateResolver;
this.features = new Features(this, features, options);
this.options = options;
+
+ Set<GradleRepository> repositories =
GradleRepository.getDefaultRepositories(VersionInfo.getGrailsVersion());
Review Comment:
`VersionInfo.getGrailsVersion()` seems to be assigned to a variables below.
Should we move that assignment up and use the variable here as well?
##########
grails-gradle/tasks/src/main/groovy/org/grails/gradle/plugin/run/FindMainClassTask.groovy:
##########
@@ -156,7 +131,8 @@ abstract class FindMainClassTask extends DefaultTask {
MainClassHolder mainClassHolder = null
for (File classesDir in classesDirs) {
logger.debug("Searching for main class in: {}",
classesDir.absolutePath)
- mainClassHolder = mainClassFinder.findMainClass(classesDir, false)
// do not cache inside of the finder since gradle is responsible for caching
+ mainClassHolder = mainClassFinder.findMainClass(classesDir, false)
+ // do not cache inside of the finder since gradle is responsible
for caching
if (mainClassHolder) {
logger.debug("Found main class: {} at {}",
mainClassHolder.className, mainClassHolder.classFile.absolutePath)
Review Comment:
Align on single quotes for strings?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]