jamesfredley commented on code in PR #14133: URL: https://github.com/apache/grails-core/pull/14133#discussion_r2042979679
########## grails-gradle/dependencies.gradle: ########## @@ -0,0 +1,55 @@ +// see https://github.com/dependabot/dependabot-core/issues/1618 Review Comment: Let's add a comment to each of the dependencies.gradle files referencing the other one since the versions are now split between them. ########## grails-bootstrap/build.gradle: ########## @@ -12,18 +12,17 @@ group = 'org.apache.grails.bootstrap' dependencies { implementation platform(project(':grails-bom')) - // compile grails-bootstap with the Groovy version provided by Gradle - // to ensure build compatibility with Gradle, currently Groovy 3.0.x - // when used by grails-gradle-plugin - // see: https://docs.gradle.org/current/userguide/compatibility.html#groovy implementation "org.springframework:spring-context" implementation "org.springframework.boot:spring-boot-autoconfigure" + api 'org.apache.grails.gradle:grails-gradle-model', { + exclude group: 'org.codehaus.groovy' + } - compileOnly "org.codehaus.groovy:groovy:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-templates:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-xml:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-ant:$GroovySystem.version" + compileOnly "org.apache.groovy:groovy" Review Comment: I think we still want to compile `grails-bootstrap` with with `$GroovySystem.version` since it is used by the gradle plugin when running the build. It technically works when compiled with Groovy 4, since the classes are Groovy 3 compatible, but that is lucky. ########## grails-bom/build.gradle: ########## @@ -12,221 +15,237 @@ javaPlatform { allowDependencies() } -def versions = new Properties() -versions.load(new StringReader(new File("$projectDir.parentFile/gradle.properties").text)) + ext { isReleaseBuild = System.getenv('GRAILS_PUBLISH_RELEASE') == 'true' isPublishedExternal = System.getenv().containsKey('NEXUS_PUBLISH_STAGING_PROFILE_ID') +} - // When making changes in the dependencyVersions, remember to also update the Grails BOM Documentation: - // https://docs.grails.org/snapshot/ref/Dependency%20Versions/Grails%20BOM.html - // Grails dependencies are listed in SCOTTL format: - // groupId:artifactId-prefixes:artifactId-suffixes:version:versionNameOverride - // version name = versionNameOverride ?: artifactId-prefixes[0] - dependenciesOverview = """\ - com.bertramlabs.plugins:asset-pipeline-gradle:: - com.bertramlabs.plugins:asset-pipeline-grails:: - com.fasterxml.jackson:jackson-bom:::jackson - com.github.javaparser:javaparser-core:: - com.h2database:h2:: - commons-codec:commons-codec:: - io.methvin:directory-watcher:: - io.reactivex.rxjava2:rxjava:::rxjava2 - io.reactivex.rxjava3:rxjava:::rxjava3 - io.reactivex:rxjava:::rxjava - jline:jline:: - net.bytebuddy:byte-buddy:: - net.java.dev.jna:jna:: - org.apache.ant:ant:,junit: - org.apache.commons:commons-text:: - org.apache.grails.data:grails-data:hibernate5-core,mongodb-core,mongodb-ext,mongodb-bson,simple::grails-datastore - org.apache.grails:grails-data:hibernate5,hibernate5-dbmigration,hibernate5-spring-boot,mongodb,mongodb-spring-boot,mongodb-gson-templates::grails-datastore - org.apache.grails.data:grails-datamapping:core,core-test,async,support,rx,validation,tck-tests::grails-datastore - org.apache.grails.data:grails-datastore:async,core,web::grails-datastore - org.apache.grails:grails-testing-support-datamapping:::grails-datastore - org.apache.grails.views:grails:gsp,gsp-core,web-gsp,web-taglib::gsp - org.apache.grails:grails:gsp,web-testing-support,testing-support-views-gson,testing-support-web::gsp - org.apache.grails:grails:fields,scaffolding,views-gson,views-markup::gsp - org.apache.grails:grails-gradle-plugins:: - org.apache.grails:grails:cache::grails-cache - org.apache.grails:grails:geb::grails-geb - org.apache.groovy:groovy:bom::: - org.asciidoctor:asciidoctorj:: - org.fusesource.jansi:jansi:: - org.gebish:geb-spock:: - org.grails.profiles:base,plugin,profile,web,rest-api,web-plugin,rest-api-plugin,react,vue,angular:::profiles - org.grails:grails-gdoc-engine:: - org.jsoup:jsoup:: - org.liquibase.ext:liquibase-hibernate5:::liquibase-hibernate5 - org.liquibase:liquibase-cdi,liquibase-core:::liquibase-hibernate5 - org.mongodb:bson:,record-codec::mongodb - org.mongodb:mongodb-driver:core,sync::mongodb - org.objenesis:objenesis:: - org.spockframework:spock-core,spock-spring:::spock - org.springframework.boot:spring-boot-cli,spring-boot-gradle-plugin:::spring-boot - org.springframework:springloaded:: - org.webjars.npm:bootstrap-icons:: - org.webjars.npm:bootstrap:: - org.webjars.npm:jquery:: - org.xhtmlrenderer:flying-saucer-pdf-openpdf:: - """.stripIndent(true).trim().readLines().collect { - def info = it.toString().split(':', -1) - def dep = [group: info[0], names: info[1].split(','), modules: info[2].split(','), version: info.length >= 4? info[3] : null] - dep.name = info.length == 5? info[4] : dep.names[0] // allow name override - dep.version = dep.version ?: versions.get("${dep.name}.version".toString()) ?: '\t\t\t\t*** UNDEFINED **' - dep - }.collectEntries { - def depList = GroovyCollections - .combinations(it.names, it.modules) - .collect { it.join('-') } - .collect { it.endsWith('-') ? it[0..-2] : it } - [(it):depList] +dependencies { + api platform("org.apache.grails:grails-gradle-bom:${projectVersion}"), { + exclude group: 'org.codehaus.groovy' + exclude group: 'org.spockframework' } - dependencyList = dependenciesOverview.collectMany { dependency, artifacts -> - artifacts.collect { artifactId -> - [groupId: dependency.group, artifactId: artifactId, - versionValue: dependency.version, name: dependency.name] + api platform(bomPlatformDependencies['groovy_bom']) + api platform(bomPlatformDependencies['spock_bom']) + api platform(bomPlatformDependencies['jackson_bom']) + + constraints { + api bomDependencies['asset_pipeline_grails'] + api bomDependencies['bootstrap'] + api bomDependencies['bootstrap_icons'] + api bomDependencies['commons_codec'] + api bomDependencies['fields'] + api bomDependencies['geb_spock'] + api bomDependencies['grails_cache'] + api bomDependencies['grails_data_hibernate5'] + api bomDependencies['grails_data_hibernate5_core'] + api bomDependencies['grails_data_hibernate5_dbmigration'] + api bomDependencies['grails_data_hibernate5_spring_boot'] + api bomDependencies['grails_data_mongodb'] + api bomDependencies['grails_data_mongodb_bson'] + api bomDependencies['grails_data_mongodb_core'] + api bomDependencies['grails_data_mongodb_ext'] + api bomDependencies['grails_data_mongodb_gson_templates'] + api bomDependencies['grails_data_mongodb_spring_boot'] + api bomDependencies['grails_data_simple'] + api bomDependencies['grails_datamapping_async'] + api bomDependencies['grails_datamapping_core'] + api bomDependencies['grails_datamapping_core_test'] + api bomDependencies['grails_datamapping_rx'] + api bomDependencies['grails_datamapping_support'] + api bomDependencies['grails_datamapping_tck_tests'] + api bomDependencies['grails_datamapping_validation'] + api bomDependencies['grails_datastore_async'] + api bomDependencies['grails_datastore_core'] + api bomDependencies['grails_datastore_web'] + api bomDependencies['grails_geb'] + api bomDependencies['grails_gsp'] + api bomDependencies['grails_gsp_core'] + api bomDependencies['grails_profiles_angular'] + api bomDependencies['grails_profiles_base'] + api bomDependencies['grails_profiles_plugin'] + api bomDependencies['grails_profiles_profile'] + api bomDependencies['grails_profiles_react'] + api bomDependencies['grails_profiles_rest_api'] + api bomDependencies['grails_profiles_rest_api_plugin'] + api bomDependencies['grails_profiles_vue'] + api bomDependencies['grails_profiles_web'] + api bomDependencies['grails_profiles_web_plugin'] + api bomDependencies['grails_testing_support_datamapping'] + api bomDependencies['grails_testing_support_views_gson'] + api bomDependencies['grails_testing_support_web'] + api bomDependencies['grails_web_gsp'] + api bomDependencies['grails_web_taglib'] + api bomDependencies['h2'] + api bomDependencies['jquery'] + api bomDependencies['liquibase_hibernate5'] + api bomDependencies['liquibase_hibernate5_cdi'] + api bomDependencies['liquibase_hibernate5_core'] + api bomDependencies['liquibase_hibernate5_ext'] + api bomDependencies['mongodb_bson'] + api bomDependencies['mongodb_driver_core'] + api bomDependencies['mongodb_driver_sync'] + api bomDependencies['mongodb_record_codec'] + api bomDependencies['rxjava'] + api bomDependencies['rxjava2'] + api bomDependencies['rxjava3'] + api bomDependencies['scaffolding'] + api bomDependencies['views_gson'] + api bomDependencies['views_markup'] + + for (Project subproject : rootProject.subprojects) { + if(subproject.path == project.path || subproject.name in testProjects) { + continue // ignore self & test projects + } + + api project(":${subproject.path}") } } - dependenciesVersions = dependencyList.sort { it.name } - .groupBy { it.name }.collect { it.value.first() } // remove duplicates - - allDependencies = dependencyList.sort { it.name + it.artifactId } - allDependencies.each { it << [version: "${it.name}.version"] } } -if(ext.isReleaseBuild && ext.isPublishedExternal) { - allDependencies.each { - if (version.endsWith("-SNAPSHOT")) { - throw new GradleException("Releases cannot have a snapshot dependency: $it.groupId:$it.name ($it.version)") +tasks.register('validateNoSnapshotDependencies') { + doLast { + configurations.each { config -> + config.allDependencies.each { dep -> + if (dep.version && dep.version.contains('-SNAPSHOT')) { + throw new GradleException("Releases cannot have a snapshot dependency: ${dep.group}:${dep.name} (${dep.version})") + } + } } } } -// Generate a valid gradle constraint as well as the pom that's generated so we can use either platform() -// or the spring dependency management plugin -dependencies { - api platform("org.springframework.boot:spring-boot-dependencies:${project['spring-boot.version']}") - api platform("org.apache.groovy:groovy-bom:${project['groovy.version']}") - api platform("com.fasterxml.jackson:jackson-bom:${project['jackson.version']}") +if(ext.isReleaseBuild && ext.isPublishedExternal) { + tasks.named('generateMetadataFileForMavenPublication').configure { + dependsOn(tasks.named('validateNoSnapshotDependencies')) + } + tasks.named('generatePomFileForMavenPublication').configure { + dependsOn(tasks.named('validateNoSnapshotDependencies')) + } +} - constraints { - allDependencies.each { - api "${it.groupId}:${it.artifactId}:${it.versionValue}" - } +Closure determinePropertyName = { String groupId, String artifactId, String version, boolean isBom -> + Map<String, String> toSearch = isBom ? bomPlatformDependencies : bomDependencies - project.parent.subprojects.each { - if (it.name == 'grails-bom' || it.name in testProjects) return null + Map.Entry<String, String> found = toSearch.entrySet().find { "$groupId:$artifactId:$version" as String == it.value as String } + if(!found) { + return null + } - api project(it.path) + Map<String, String> versions = bomDependencyVersions + + //TODO: this isn't the correct way to do this, but with project mergers it may not matter + String possibleKey = found.key.replace('_', '-') + .replace('grails-datamapping', 'grails-data') + .replace('grails-datastore', 'grails-data') + .replace('grails-testing-support-datamapping', 'grails-data') + .replace('grails-gsp', 'gsp') + .replace('grails-web-gsp', 'gsp') + .replace('grails-web-taglib', 'gsp') + .replace('scaffolding', 'gsp') + .replace('fields', 'gsp') + .replace('grails-testing-support-views-gson', 'gsp') + .replace('grails-testing-support-web', 'gsp') + .replace('views-markup', 'gsp') + .replace('views-gson', 'gsp') + while(possibleKey != null) { + String propertyName = "${possibleKey}.version" as String + if(versions.containsKey(propertyName)) { + return propertyName } + + int lastIndex = possibleKey.lastIndexOf('-') + possibleKey = lastIndex > 0 ? possibleKey.substring(0, lastIndex) : null } + + throw new GradleException("Could not determine artifact property key for $groupId:$artifactId:$version") } ext { pomDescription = "Grails BOM (Bill of Materials) for managing dependency versions used by Grails Projects" pomCustomization = { -> def root = asNode() - def propsNode = root.appendNode('properties') - dependenciesVersions.each { - propsNode.appendNode(it.version, it.versionValue) - } - - def appendNodes = { node, attrs -> - attrs.each { - node.appendNode(it.key, it.value) + def propertiesNode = root.properties ? root.properties[0] : root.appendNode('properties') + + def depMgmt = root.dependencyManagement?.getAt(0) + def deps = depMgmt?.dependencies?.getAt(0) + if (deps) { + Map<String, String> pomProperties = [:] + deps.dependency.each { dep -> + String groupId = dep.groupId.text().trim() + String artifactId = dep.artifactId.text().trim() + boolean isBom = dep.scope.text().trim() == 'import' + + String inlineVersion = dep.version.text().trim() + if(inlineVersion == 'null') { + inlineVersion = null + } + + if (inlineVersion) { + String propertyName = determinePropertyName(groupId, artifactId, inlineVersion, isBom) + if(propertyName) { + // Replace the version in the pom with a property reference + String propertyReference = "\${${propertyName}}" + dep.version[0].value = propertyReference + + // Add an entry in the <properties> node with the actual version number + pomProperties.put(propertyName, inlineVersion) + } + } + else if(!inlineVersion) { + throw new GradleException("Dependency $groupId:$artifactId does not have a version.") + } } - } - - def dpm = root.appendNode('dependencyManagement') - def deps = dpm.appendNode('dependencies') - - appendNodes(deps.appendNode('dependency'), [ - groupId: 'org.apache.groovy', - artifactId: 'groovy-bom', - version: '${groovy.version}', - type: 'pom', - scope: 'import' - ]) - - appendNodes(deps.appendNode('dependency'), [ - groupId: 'com.fasterxml.jackson', - artifactId: 'jackson-bom', - version: '${jackson.version}', - type: 'pom', - scope: 'import' - ]) - - appendNodes(deps.appendNode('dependency'), [ - groupId: 'org.springframework.boot', - artifactId: 'spring-boot-dependencies', - version: '${spring-boot.version}', - type: 'pom', - scope: 'import' - ]) - - project.parent.subprojects.findResults { - if (it.name == 'grails-bom' || it.name in testProjects) return null - return [ - groupId: it.group, - artifactId: it.findProperty('pomArtifactId') ?: it.name, - version: it.version - ] - }.each { - appendNodes(deps.appendNode('dependency'), it) - } - allDependencies.collect { def m = it.subMap('groupId', 'artifactId', 'version') - m + [version: "\${${m.version}}"] - }.each { - if(it.artifactId !in ['groovy-bom', 'jackson-bom']) { - appendNodes(deps.appendNode('dependency'), it) + for (Map.Entry<String, String> property : pomProperties.entrySet()) { + propertiesNode.appendNode(property.key, property.value) } } } } -tasks.register('syncProps') { - doLast { - def gradlePropertiesFile = rootProject.layout.projectDirectory.file('gradle.properties').asFile - String oldProperties = gradlePropertiesFile.text - gradlePropertiesFile.write(oldProperties.substring(0, oldProperties.indexOf("# Generated on")) + """\ - # Generated on ${new Date()} by: ./gradlew :grails-bom:${name} - # Only version value modifications allowed after this point. Do not insert or change version names. - ${dependenciesVersions.collect { "$it.version=$it.versionValue" }.join('\n ')} - """.stripIndent(true).trim()) - println "${gradlePropertiesFile} updated." - } -} - -tasks.register('dependabotBuild') { - doLast { - def dependabotBuildFile = rootProject.layout.projectDirectory.file('dependabot/build.gradle').asFile - dependabotBuildFile.parentFile.mkdirs() - dependabotBuildFile.write("""\ - // Generated on ${new Date()} by: ./gradlew :grails-bom:${name} - plugins { - id 'java-library' - } - - dependencies { - ${allDependencies.collect { " api \"${it.groupId}:${it.artifactId}:\${project['${it.version}']}\"" }.join('\n ')} - } - """.stripIndent(true).trim()) - println "${dependabotBuildFile} created." - } -} - -tasks.register('dependabot') { - group = 'Dependency Management' - description = 'This task updates the dependabot/build.gradle and gradle.properties files by syncing them with the latest external dependencies listed in the Grails BOM (Bill of Materials). This ensures that Dependabot can monitor these dependencies and automatically create pull requests when newer versions become available.' - - dependsOn 'syncProps', 'dependabotBuild' -} +//tasks.register('syncProps') { Review Comment: Can we remove? ########## grails-gradle/gradle/docs-config.gradle: ########## @@ -0,0 +1,42 @@ +configurations.register('documentation') +dependencies { + add('documentation', platform(project(':grails-gradle-bom'))) + add('documentation', 'org.fusesource.jansi:jansi') + add('documentation', 'jline:jline') + add('documentation', 'com.github.javaparser:javaparser-core') + add('documentation', "org.codehaus.groovy:groovy") Review Comment: single quotes above, double quotes below. lets standardize these lines. ########## grails-bootstrap/build.gradle: ########## @@ -12,18 +12,17 @@ group = 'org.apache.grails.bootstrap' dependencies { implementation platform(project(':grails-bom')) - // compile grails-bootstap with the Groovy version provided by Gradle - // to ensure build compatibility with Gradle, currently Groovy 3.0.x - // when used by grails-gradle-plugin - // see: https://docs.gradle.org/current/userguide/compatibility.html#groovy implementation "org.springframework:spring-context" implementation "org.springframework.boot:spring-boot-autoconfigure" + api 'org.apache.grails.gradle:grails-gradle-model', { + exclude group: 'org.codehaus.groovy' + } - compileOnly "org.codehaus.groovy:groovy:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-templates:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-xml:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-ant:$GroovySystem.version" + compileOnly "org.apache.groovy:groovy" Review Comment: This was due to grails-shell dependencies https://github.com/apache/grails-core/blob/7.0.x/grails-shell-cli/build.gradle#L74 ########## grails-bootstrap/build.gradle: ########## @@ -12,18 +12,17 @@ group = 'org.apache.grails.bootstrap' dependencies { implementation platform(project(':grails-bom')) - // compile grails-bootstap with the Groovy version provided by Gradle - // to ensure build compatibility with Gradle, currently Groovy 3.0.x - // when used by grails-gradle-plugin - // see: https://docs.gradle.org/current/userguide/compatibility.html#groovy implementation "org.springframework:spring-context" implementation "org.springframework.boot:spring-boot-autoconfigure" + api 'org.apache.grails.gradle:grails-gradle-model', { + exclude group: 'org.codehaus.groovy' + } - compileOnly "org.codehaus.groovy:groovy:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-templates:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-xml:$GroovySystem.version" - compileOnly "org.codehaus.groovy:groovy-ant:$GroovySystem.version" + compileOnly "org.apache.groovy:groovy" Review Comment: It was done in these 3: https://github.com/search?q=repo%3Aapache%2Fgrails-core+%22the+Groovy+version+provided+by+Gradle%22&type=code -- 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]
