|  | 
| 76 | 76 | def projectNamesNotToBePublished = ["driver-benchmarks", "driver-lambda", "driver-workload-executor", "graalvm-native-image-app", "util", | 
| 77 | 77 |                                     "spock", "taglets"] | 
| 78 | 78 | def publishedProjects = subprojects.findAll { !projectNamesNotToBePublished.contains(it.name) } | 
| 79 |  | -def scalaProjects = publishedProjects.findAll { it.name.contains('scala') } | 
| 80 |  | -def javaProjects = publishedProjects - scalaProjects | 
| 81 |  | -def projectsWithManifest = publishedProjects.findAll {it.name != 'driver-legacy' } | 
|  | 79 | +def bomProjects = project(":bom") | 
|  | 80 | +def scalaProjects = publishedProjects.findAll { it.name.contains('scala') } - bomProjects | 
|  | 81 | +def javaProjects = publishedProjects - scalaProjects - bomProjects | 
|  | 82 | +def projectsWithManifest = publishedProjects.findAll {it.name != 'driver-legacy' } - bomProjects | 
| 82 | 83 | 
 | 
| 83 | 84 | configure(javaProjects) { project -> | 
| 84 | 85 |     apply plugin: 'maven-publish' | 
| @@ -169,3 +170,98 @@ configure(projectsWithManifest) { project -> | 
| 169 | 170 |         jar configureJarManifestAttributes(project) | 
| 170 | 171 |     } | 
| 171 | 172 | } | 
|  | 173 | + | 
|  | 174 | +configure(bomProjects) { project -> | 
|  | 175 | +    apply plugin: 'maven-publish' | 
|  | 176 | +    apply plugin: 'signing' | 
|  | 177 | +    apply plugin: 'java-platform' | 
|  | 178 | + | 
|  | 179 | +    // Get the Scala versions from the project property. Only major.minor versions. | 
|  | 180 | +    def scalaVersions = project.findProperty("scalaVersions")?.split(",") | 
|  | 181 | +            ?.collect { it.split("\\.")[0] + "." + it.split("\\.")[1] } | 
|  | 182 | + | 
|  | 183 | +    assert scalaVersions != null && !scalaVersions.isEmpty() : "Scala versions must be provided as a comma-separated list" + | 
|  | 184 | +            " in the 'scalaVersions' project property" | 
|  | 185 | + | 
|  | 186 | +    publishing { | 
|  | 187 | +        publications { | 
|  | 188 | +            mavenJava(MavenPublication) { | 
|  | 189 | +                artifactId = "bom".equals(project.archivesBaseName) ? "mongodb-driver-bom" : project.archivesBaseName | 
|  | 190 | +                from components.javaPlatform | 
|  | 191 | + | 
|  | 192 | +                // Modify the generated POM to add multiple compile versions of driver-scala or bson-scala. | 
|  | 193 | +                // Scala multi-version support generates only one for BOM. | 
|  | 194 | +                pom.withXml { | 
|  | 195 | +                    def pomXml = asNode() | 
|  | 196 | + | 
|  | 197 | +                    def dependencyManagementNode = pomXml.get("dependencyManagement")?.getAt(0) | 
|  | 198 | +                    assert dependencyManagementNode : "<dependencyManagement> node not found in the generated BOM POM" | 
|  | 199 | + | 
|  | 200 | +                    def dependenciesNode = dependencyManagementNode.get("dependencies")?.getAt(0) | 
|  | 201 | +                    assert dependenciesNode : "<dependencies> node not found inside <dependencyManagement>" | 
|  | 202 | + | 
|  | 203 | +                    // Check if scala dependencies are present in the BOM. | 
|  | 204 | +                    def existingScalaDeps = dependenciesNode.children().findAll { | 
|  | 205 | +                        it.artifactId.text().contains("scala") | 
|  | 206 | +                    } | 
|  | 207 | + | 
|  | 208 | +                    existingScalaDeps.each { existingDep -> | 
|  | 209 | +                        String groupId = existingDep.groupId.text() | 
|  | 210 | +                        String originalArtifactId = existingDep.artifactId.text() | 
|  | 211 | +                        String artifactVersion = existingDep.version.text() | 
|  | 212 | + | 
|  | 213 | +                        // Add multiple versions with Scala suffixes for each Scala-related dependency. | 
|  | 214 | +                        scalaVersions.each { scalaVersion -> | 
|  | 215 | +                            // Remove existing Scala version suffix (_2.12, _2.13, etc.) | 
|  | 216 | +                            String baseArtifactId = originalArtifactId.replaceAll("_\\d+\\.\\d+(\\.\\d+)?\$", "") | 
|  | 217 | +                            String newArtifactId = "${baseArtifactId}_${scalaVersion}" | 
|  | 218 | + | 
|  | 219 | +                            // Skip if Scala dependency with this scalaVersion already exists in BOM. | 
|  | 220 | +                            if(newArtifactId != originalArtifactId) { | 
|  | 221 | +                                def dependencyNode = dependenciesNode.appendNode("dependency") | 
|  | 222 | +                                dependencyNode.appendNode("groupId", groupId) | 
|  | 223 | +                                dependencyNode.appendNode("artifactId", newArtifactId) | 
|  | 224 | +                                dependencyNode.appendNode("version", artifactVersion) | 
|  | 225 | +                            } | 
|  | 226 | +                        } | 
|  | 227 | +                    } | 
|  | 228 | +                } | 
|  | 229 | +            } | 
|  | 230 | +        } | 
|  | 231 | + | 
|  | 232 | +        repositories configureMavenRepositories(project) | 
|  | 233 | +    } | 
|  | 234 | + | 
|  | 235 | +    afterEvaluate { | 
|  | 236 | +        publishing.publications.mavenJava.pom configurePom(project) | 
|  | 237 | +        signing { | 
|  | 238 | +            useInMemoryPgpKeys(findProperty("signingKey"), findProperty("signingPassword")) | 
|  | 239 | +            sign publishing.publications.mavenJava | 
|  | 240 | +        } | 
|  | 241 | +    } | 
|  | 242 | + | 
|  | 243 | +    tasks.withType(GenerateModuleMetadata) { | 
|  | 244 | +        enabled = false | 
|  | 245 | +    } | 
|  | 246 | + | 
|  | 247 | +    tasks.withType(GenerateMavenPom).configureEach { | 
|  | 248 | +        doLast { | 
|  | 249 | +            def xml = file(destination).text | 
|  | 250 | +            def root = new groovy.xml.XmlSlurper().parseText(xml) | 
|  | 251 | + | 
|  | 252 | +            def dependencies = root.dependencyManagement.dependencies.children() | 
|  | 253 | +            assert dependencies.children().size() > 1 : "BOM must contain more then one <dependency> element:\n$destination" | 
|  | 254 | + | 
|  | 255 | +            dependencies.each { dependency -> | 
|  | 256 | +                def groupId = dependency.groupId.text() | 
|  | 257 | +                assert groupId.startsWith('org.mongodb') : "BOM must contain only 'org.mongodb' dependencies, but found '$groupId':\n$destination" | 
|  | 258 | +                /* The <scope> and <optional> tags should be omitted in BOM dependencies. | 
|  | 259 | +                   This ensures that consuming projects have the flexibility to decide whether a | 
|  | 260 | +                   dependency is optional in their context. The BOM's role is to provide version information, | 
|  | 261 | +                   not to dictate inclusion or exclusion of dependencies. */ | 
|  | 262 | +                assert dependency.scope.size() == 0 : "BOM must not contain <scope> elements in dependency:\n$destination" | 
|  | 263 | +                assert dependency.optional.size() == 0 : "BOM must not contain <optional> elements in dependency:\n$destination" | 
|  | 264 | +            } | 
|  | 265 | +        } | 
|  | 266 | +    } | 
|  | 267 | +} | 
0 commit comments