Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .evergreen/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ fi
SYSTEM_PROPERTIES="-Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.internal.http.connectionTimeout=120000 -Dorg.gradle.internal.http.socketTimeout=120000"

./gradlew -version
./gradlew ${SYSTEM_PROPERTIES} --stacktrace --info ${TASK}
./gradlew ${SYSTEM_PROPERTIES} --stacktrace --info ${TASK} # Scala 2.13 is published as result of this gradle execution.
./gradlew ${SYSTEM_PROPERTIES} --stacktrace --info :bson-scala:${TASK} :driver-scala:${TASK} -PdefaultScalaVersions=2.12.12
./gradlew ${SYSTEM_PROPERTIES} --stacktrace --info :bson-scala:${TASK} :driver-scala:${TASK} -PdefaultScalaVersions=2.11.12
23 changes: 23 additions & 0 deletions bom/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
group = "org.mongodb"
description = "This Bill of Materials POM simplifies dependency management when referencing multiple" +
" MongoDB Java Driver artifacts in projects using Gradle or Maven."

dependencies {
constraints {
api(project(":mongodb-crypt"))
api(project(":driver-core"))
api(project(":bson"))
api(project(":bson-record-codec"))

api(project(":driver-sync"))
api(project(":driver-reactive-streams"))

api(project(":bson-kotlin"))
api(project(":bson-kotlinx"))
api(project(":driver-kotlin-coroutine"))
api(project(":driver-kotlin-sync"))

api(project(":bson-scala"))
api(project(":driver-scala"))
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Nit: no ending new line.

Copy link
Member Author

Choose a reason for hiding this comment

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

Applied the suggestion in another comment: #1569 (comment). Thanks!

5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ ext {

def configDir = ext.configDir
def utilProjects = project(":util").allprojects
def bomProjects = project(":bom")
def coreProjects = subprojects - utilProjects
def scalaProjects = subprojects.findAll { it.name.contains('scala') }
def javaProjects = subprojects - scalaProjects
def scalaProjects = subprojects.findAll { it.name.contains('scala') } - bomProjects
def javaProjects = subprojects - scalaProjects - bomProjects
def javaMainProjects = javaProjects - utilProjects
def javaCodeCheckedProjects = javaMainProjects.findAll { !['driver-benchmarks', 'driver-workload-executor', 'driver-lambda'].contains(it.name) }
def javaAndScalaTestedProjects = javaCodeCheckedProjects + scalaProjects
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

org.gradle.daemon=true
org.gradle.jvmargs=-Duser.country=US -Duser.language=en
## NOTE: This property is also used to generate scala compile versions in BOM.
scalaVersions=2.11.12,2.12.20,2.13.15
defaultScalaVersions=2.13.15
runOnceTasks=clean,release
Expand Down
102 changes: 99 additions & 3 deletions gradle/publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ ext {
def projectNamesNotToBePublished = ["driver-benchmarks", "driver-lambda", "driver-workload-executor", "graalvm-native-image-app", "util",
"spock", "taglets"]
def publishedProjects = subprojects.findAll { !projectNamesNotToBePublished.contains(it.name) }
def scalaProjects = publishedProjects.findAll { it.name.contains('scala') }
def javaProjects = publishedProjects - scalaProjects
def projectsWithManifest = publishedProjects.findAll {it.name != 'driver-legacy' }
def bomProjects = project(":bom")
def scalaProjects = publishedProjects.findAll { it.name.contains('scala') } - bomProjects
def javaProjects = publishedProjects - scalaProjects - bomProjects
def projectsWithManifest = publishedProjects.findAll {it.name != 'driver-legacy' } - bomProjects

configure(javaProjects) { project ->
apply plugin: 'maven-publish'
Expand Down Expand Up @@ -169,3 +170,98 @@ configure(projectsWithManifest) { project ->
jar configureJarManifestAttributes(project)
}
}

configure(bomProjects) { project ->
apply plugin: 'maven-publish'
apply plugin: 'signing'
apply plugin: 'java-platform'

// Get the Scala versions from the project property. Only major.minor versions.
def scalaVersions = project.findProperty("scalaVersions")?.split(",")
?.collect { it.split("\\.")[0] + "." + it.split("\\.")[1] }

assert scalaVersions != null && !scalaVersions.isEmpty() : "Scala versions must be provided as a comma-separated list" +
" in the 'scalaVersions' project property"

publishing {
publications {
mavenJava(MavenPublication) {
artifactId = "bom".equals(project.archivesBaseName) ? "mongodb-driver-bom" : project.archivesBaseName
from components.javaPlatform

// Modify the generated POM to add multiple compile versions of driver-scala or bson-scala.
Copy link
Member

Choose a reason for hiding this comment

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

Great catch 👍

// Scala multi-version support generates only one for BOM.
pom.withXml {
def pomXml = asNode()

def dependencyManagementNode = pomXml.get("dependencyManagement")?.getAt(0)
assert dependencyManagementNode : "<dependencyManagement> node not found in the generated BOM POM"

def dependenciesNode = dependencyManagementNode.get("dependencies")?.getAt(0)
assert dependenciesNode : "<dependencies> node not found inside <dependencyManagement>"

// Check if scala dependencies are present in the BOM.
def existingScalaDeps = dependenciesNode.children().findAll {
it.artifactId.text().contains("scala")
}

existingScalaDeps.each { existingDep ->
String groupId = existingDep.groupId.text()
String originalArtifactId = existingDep.artifactId.text()
String artifactVersion = existingDep.version.text()

// Add multiple versions with Scala suffixes for each Scala-related dependency.
scalaVersions.each { scalaVersion ->
// Remove existing Scala version suffix (_2.12, _2.13, etc.)
String baseArtifactId = originalArtifactId.replaceAll("_\\d+\\.\\d+(\\.\\d+)?\$", "")
String newArtifactId = "${baseArtifactId}_${scalaVersion}"

// Skip if Scala dependency with this scalaVersion already exists in BOM.
if(newArtifactId != originalArtifactId) {
def dependencyNode = dependenciesNode.appendNode("dependency")
dependencyNode.appendNode("groupId", groupId)
dependencyNode.appendNode("artifactId", newArtifactId)
dependencyNode.appendNode("version", artifactVersion)
}
}
}
}
}
}

repositories configureMavenRepositories(project)
}

afterEvaluate {
publishing.publications.mavenJava.pom configurePom(project)
signing {
useInMemoryPgpKeys(findProperty("signingKey"), findProperty("signingPassword"))
sign publishing.publications.mavenJava
}
}

tasks.withType(GenerateModuleMetadata) {
enabled = false
}

tasks.withType(GenerateMavenPom).configureEach {
doLast {
def xml = file(destination).text
def root = new groovy.xml.XmlSlurper().parseText(xml)

def dependencies = root.dependencyManagement.dependencies.children()
assert dependencies.children().size() > 1 : "BOM must contain more then one <dependency> element:\n$destination"

dependencies.each { dependency ->
def groupId = dependency.groupId.text()
assert groupId.startsWith('org.mongodb') : "BOM must contain only 'org.mongodb' dependencies, but found '$groupId':\n$destination"
/* The <scope> and <optional> tags should be omitted in BOM dependencies.
This ensures that consuming projects have the flexibility to decide whether a
dependency is optional in their context. The BOM's role is to provide version information,
not to dictate inclusion or exclusion of dependencies. */
assert dependency.scope.size() == 0 : "BOM must not contain <scope> elements in dependency:\n$destination"
assert dependency.optional.size() == 0 : "BOM must not contain <optional> elements in dependency:\n$destination"
}
}
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ include ':driver-scala'
include ':mongodb-crypt'
include 'util:spock'
include 'util:taglets'
include ':bom'

if(hasProperty("includeGraalvm")) {
include ':graalvm-native-image-app'
Expand Down