1
- group = " org.mongodb"
2
- description = " This Bill of Materials POM simplifies dependency management when referencing multiple" +
3
- " MongoDB Java Driver artifacts in projects using Gradle or Maven."
1
+ /*
2
+ * Copyright 2008-present MongoDB, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import ProjectExtensions.configureMavenPublication
17
+ import groovy.util.Node
18
+ import groovy.util.NodeList
19
+
20
+ plugins {
21
+ id(" java-platform" )
22
+ id(" project.base" )
23
+ id(" conventions.publishing" )
24
+ id(" conventions.spotless" )
25
+ }
26
+
27
+ base.archivesName.set(" mongodb-driver-bom" )
4
28
5
29
dependencies {
6
30
constraints {
@@ -21,3 +45,109 @@ dependencies {
21
45
api(project(" :driver-scala" ))
22
46
}
23
47
}
48
+
49
+ /*
50
+ * Handle the multiple versions of Scala we support as defined in `gradle.properties`
51
+ */
52
+ val defaultScalaVersion: String = project.findProperty(" defaultScalaVersion" )!! .toString()
53
+ val scalaVersions: List <String >? = project.findProperty(" supportedScalaVersions" )?.toString()?.split(" ," )
54
+
55
+ assert (! scalaVersions.isNullOrEmpty()) {
56
+ " Scala versions must be provided as a comma-separated list in the 'supportedScalaVersions' project property"
57
+ }
58
+
59
+ /*
60
+ * Apply the Java Platform plugin to create the BOM
61
+ * Modify the generated POM to include all supported versions of Scala for driver-scala or bson-scala.
62
+ */
63
+ configureMavenPublication {
64
+ components.findByName(" javaPlatform" )?.let { from(it) }
65
+
66
+ pom {
67
+ name.set(" bom" )
68
+ description.set(
69
+ " This Bill of Materials POM simplifies dependency management when referencing multiple MongoDB Java Driver artifacts in projects using Gradle or Maven." )
70
+
71
+ withXml {
72
+ val pomXml: Node = asNode()
73
+
74
+ val dependencyManagementNode = pomXml.getNode(" dependencyManagement" )
75
+ assert (dependencyManagementNode != null ) {
76
+ " <dependencyManagement> node not found in the generated BOM POM"
77
+ }
78
+ val dependenciesNode = dependencyManagementNode.getNode(" dependencies" )
79
+ assert (dependenciesNode != null ) { " <dependencies> node not found in the generated BOM POM" }
80
+
81
+ val existingScalaDeps =
82
+ dependenciesNode!!
83
+ .children()
84
+ .map { it as Node }
85
+ .filter { it.getNode(" artifactId" )?.text()?.contains(" scala" ) ? : false }
86
+
87
+ existingScalaDeps.forEach {
88
+ val groupId: String = it.getNode(" groupId" )!! .text()
89
+ val originalArtifactId: String = it.getNode(" artifactId" )!! .text()
90
+ val artifactVersion: String = it.getNode(" version" )!! .text()
91
+
92
+ // Add multiple versions with Scala suffixes for each Scala-related dependency.
93
+ scalaVersions!! .forEach { scalaVersion ->
94
+ if (scalaVersion != defaultScalaVersion) {
95
+ // Replace scala version suffix
96
+ val newArtifactId: String = originalArtifactId.replace(defaultScalaVersion, scalaVersion)
97
+ val dependencyNode = dependenciesNode.appendNode(" dependency" )
98
+ dependencyNode.appendNode(" groupId" , groupId)
99
+ dependencyNode.appendNode(" artifactId" , newArtifactId)
100
+ dependencyNode.appendNode(" version" , artifactVersion)
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ /*
109
+ * Validate the BOM file.
110
+ */
111
+ tasks.withType<GenerateMavenPom > {
112
+ doLast {
113
+ pom.withXml {
114
+ val pomXml: Node = asNode()
115
+ val dependenciesNode = pomXml.getNode(" dependencyManagement" ).getNode(" dependencies" )
116
+ assert (dependenciesNode!! .children().isNotEmpty()) {
117
+ " BOM must contain more then one <dependency> element:\n $destination "
118
+ }
119
+
120
+ dependenciesNode
121
+ .children()
122
+ .map { it as Node }
123
+ .forEach {
124
+ val groupId: String = it.getNode(" groupId" )!! .text()
125
+ assert (groupId.startsWith(" org.mongodb" )) {
126
+ " BOM must contain only 'org.mongodb' dependencies, but found '$groupId ':\n $destination "
127
+ }
128
+
129
+ /*
130
+ * The <scope> and <optional> tags should be omitted in BOM dependencies.
131
+ * This ensures that consuming projects have the flexibility to decide whether a dependency is optional in their context.
132
+ *
133
+ * The BOM's role is to provide version information, not to dictate inclusion or exclusion of dependencies.
134
+ */
135
+ assert (it.getNode(" scope" ) == null ) {
136
+ " BOM must not contain <scope> elements in dependency:\n $destination "
137
+ }
138
+ assert (it.getNode(" optional" ) == null ) {
139
+ " BOM must not contain <optional> elements in dependency:\n $destination "
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ /* * A node lookup helper. */
147
+ private fun Node?.getNode (nodeName : String ): Node ? {
148
+ val found = this ?.get(nodeName)
149
+ if (found is NodeList && found.isNotEmpty()) {
150
+ return found[0 ] as Node
151
+ }
152
+ return null
153
+ }
0 commit comments