Skip to content

Commit 103815f

Browse files
nhachicharozza
andauthored
Merging feature branch (Kotlin extensions) into main (mongodb#1572)
* Helper methods and extensions to improve kotlin interop. (mongodb#1478) Adds a new package `org.mongodb.mongodb-driver-kotlin-extensions`. Its both, kotlin driver and bson kotlin implementation agnostic. Can be used with any combination of `bson-kotlin`, `bson-kotlinx`, `mongodb-driver-kotlin-sync` and `mongodb-driver-kotlin-coroutine`. Initial Filters extensions support, with both inflix and nested helpers eg: ``` import com.mongodb.kotlin.client.model.Filters.eq // infix Person::name.eq(person.name) // nested val bson = eq(Person::name, person.name) ``` Also adds path based support which works with vairous annotations on the data class: `@SerialName("_id")`, `@BsonId`, `@BsonProperty("_id")`: ``` (Restaurant::reviews / Review::score).path() == "reviews.rating" ``` JAVA-5308 JAVA-5484 * Gradle: Support custom header annotation * Added since annotation to Filters.kt JAVA-5308 * Adding Kotlin extensions methods for projection. (mongodb#1515) * Adding Kotlin extensions methods for projection. Fixes JAVA-5603 --------- Co-authored-by: Ross Lawley <[email protected]> * Adding Kotlin extensions methods for updates (mongodb#1529) * Adding Kotlin extension function for Updates operations JAVA-5601 * Grouping static checks under the same task (mongodb#1526) * Grouping all static checks under the "check" task JAVA-5633 * Add extension methods for Indexes (mongodb#1532) JAVA-5604 * Adding extension methods for Sorts (mongodb#1533) JAVA-5602 * Adding extensions for Aggregators and Accumulators (mongodb#1562) * Adding extensions for Aggregators and Accumulators --------- Co-authored-by: Ross Lawley <[email protected]> Co-authored-by: Ross Lawley <[email protected]>
1 parent dc9c8a6 commit 103815f

File tree

31 files changed

+5576
-38
lines changed

31 files changed

+5576
-38
lines changed

.evergreen/run-kotlin-tests.sh

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ if [ "$SAFE_FOR_MULTI_MONGOS" == "true" ]; then
3131
export MULTI_MONGOS_URI_SYSTEM_PROPERTY="-Dorg.mongodb.test.multi.mongos.uri=${MONGODB_URI}"
3232
fi
3333

34-
echo "Running Kotlin tests"
35-
3634
./gradlew -version
37-
./gradlew kotlinCheck -Dorg.mongodb.test.uri=${MONGODB_URI} ${MULTI_MONGOS_URI_SYSTEM_PROPERTY}
35+
36+
echo "Running Kotlin Unit Tests"
37+
./gradlew :bson-kotlin:test :bson-kotlinx:test :driver-kotlin-sync:test :driver-kotlin-coroutine:test :driver-kotlin-extensions:test
38+
39+
echo "Running Kotlin Integration Tests"
40+
./gradlew :driver-kotlin-sync:integrationTest :driver-kotlin-coroutine:integrationTest -Dorg.mongodb.test.uri=${MONGODB_URI} ${MULTI_MONGOS_URI_SYSTEM_PROPERTY}

.evergreen/static-checks.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ RELATIVE_DIR_PATH="$(dirname "${BASH_SOURCE[0]:-$0}")"
1212
echo "Compiling JVM drivers"
1313

1414
./gradlew -version
15-
./gradlew -PxmlReports.enabled=true --info -x test -x integrationTest -x spotlessApply clean check scalaCheck kotlinCheck jar testClasses docs
15+
./gradlew -PxmlReports.enabled=true --info -x test -x integrationTest -x spotlessApply clean check scalaCheck jar testClasses docs

THIRD-PARTY-NOTICES

+23
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,26 @@ https://github.com/mongodb/mongo-java-driver.
161161
See the License for the specific language governing permissions and
162162
limitations under the License.
163163

164+
8) The following files (originally from https://github.com/Litote/kmongo):
165+
166+
Filters.kt
167+
Properties.kt
168+
KPropertyPath.kt
169+
FiltersTest.kt
170+
KPropertiesTest.kt
171+
172+
Copyright 2008-present MongoDB, Inc.
173+
Copyright (C) 2016/2022 Litote
174+
175+
Licensed under the Apache License, Version 2.0 (the "License");
176+
you may not use this file except in compliance with the License.
177+
You may obtain a copy of the License at
178+
179+
http://www.apache.org/licenses/LICENSE-2.0
180+
181+
Unless required by applicable law or agreed to in writing, software
182+
distributed under the License is distributed on an "AS IS" BASIS,
183+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184+
See the License for the specific language governing permissions and
185+
limitations under the License.
186+

bson-kotlin/build.gradle.kts

-7
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,6 @@ spotbugs { showProgress.set(true) }
111111
// ===========================
112112
// Test Configuration
113113
// ===========================
114-
tasks.create("kotlinCheck") {
115-
description = "Runs all the kotlin checks"
116-
group = "verification"
117-
118-
dependsOn("clean", "check")
119-
tasks.findByName("check")?.mustRunAfter("clean")
120-
}
121114

122115
tasks.test { useJUnitPlatform() }
123116

bson-kotlinx/build.gradle.kts

-7
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,6 @@ spotbugs { showProgress.set(true) }
128128
// ===========================
129129
// Test Configuration
130130
// ===========================
131-
tasks.create("kotlinCheck") {
132-
description = "Runs all the kotlin checks"
133-
group = "verification"
134-
135-
dependsOn("clean", "check")
136-
tasks.findByName("check")?.mustRunAfter("clean")
137-
}
138131

139132
tasks.test { useJUnitPlatform() }
140133

config/spotbugs/exclude.xml

+24
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,30 @@
223223
<Method name="~.*validateAnnotations.*"/>
224224
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
225225
</Match>
226+
<Match>
227+
<!-- MongoDB status: "False Positive", SpotBugs rank: 17 -->
228+
<Class name="com.mongodb.kotlin.client.model.PropertiesKt$path$1"/>
229+
<Method name="~.*invoke.*"/>
230+
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
231+
</Match>
232+
<Match>
233+
<!-- MongoDB status: "False Positive", SpotBugs rank: 17 -->
234+
<Class name="com.mongodb.kotlin.client.model.Projections"/>
235+
<Method name="~include|exclude"/>
236+
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
237+
</Match>
238+
<Match>
239+
<!-- MongoDB status: "False Positive", SpotBugs rank: 17 -->
240+
<Class name="com.mongodb.kotlin.client.model.Indexes"/>
241+
<Method name="~ascending|descending|geo2dsphere"/>
242+
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
243+
</Match>
244+
<Match>
245+
<!-- MongoDB status: "False Positive", SpotBugs rank: 17 -->
246+
<Class name="com.mongodb.kotlin.client.model.Sorts"/>
247+
<Method name="~ascending|descending"/>
248+
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
249+
</Match>
226250

227251
<!-- Spotbugs reports false positives for suspendable operations with default params
228252
see: https://github.com/Kotlin/kotlinx.coroutines/issues/3099

driver-core/src/main/com/mongodb/ServerAddress.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public ServerAddress(@Nullable final String host, final int port) {
103103
if (hostToUse.startsWith("[")) {
104104
int idx = host.indexOf("]");
105105
if (idx == -1) {
106-
throw new IllegalArgumentException("an IPV6 address must be encosed with '[' and ']'"
106+
throw new IllegalArgumentException("an IPV6 address must be enclosed with '[' and ']'"
107107
+ " according to RFC 2732.");
108108
}
109109

driver-core/src/main/com/mongodb/client/model/UnwindOptions.java

+22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.mongodb.lang.Nullable;
2020

21+
import java.util.Objects;
22+
2123
/**
2224
* The options for an unwind aggregation pipeline stage
2325
*
@@ -79,4 +81,24 @@ public String toString() {
7981
+ ", includeArrayIndex='" + includeArrayIndex + '\''
8082
+ '}';
8183
}
84+
85+
@Override
86+
public boolean equals(final Object o) {
87+
if (this == o) {
88+
return true;
89+
}
90+
if (o == null || getClass() != o.getClass()) {
91+
return false;
92+
}
93+
94+
UnwindOptions that = (UnwindOptions) o;
95+
return Objects.equals(preserveNullAndEmptyArrays, that.preserveNullAndEmptyArrays) && Objects.equals(includeArrayIndex, that.includeArrayIndex);
96+
}
97+
98+
@Override
99+
public int hashCode() {
100+
int result = Objects.hashCode(preserveNullAndEmptyArrays);
101+
result = 31 * result + Objects.hashCode(includeArrayIndex);
102+
return result;
103+
}
82104
}

driver-kotlin-coroutine/build.gradle.kts

-9
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,6 @@ val integrationTest =
156156
classpath = sourceSets["integrationTest"].runtimeClasspath
157157
}
158158

159-
tasks.create("kotlinCheck") {
160-
description = "Runs all the kotlin checks"
161-
group = "verification"
162-
163-
dependsOn("clean", "check", integrationTest)
164-
tasks.findByName("check")?.mustRunAfter("clean")
165-
tasks.findByName("integrationTest")?.mustRunAfter("check")
166-
}
167-
168159
tasks.test { useJUnitPlatform() }
169160

170161
// ===========================
+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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 io.gitlab.arturbosch.detekt.Detekt
17+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
18+
19+
plugins {
20+
id("org.jetbrains.kotlin.jvm")
21+
`java-library`
22+
23+
// Test based plugins
24+
id("com.diffplug.spotless")
25+
id("org.jetbrains.dokka")
26+
id("io.gitlab.arturbosch.detekt")
27+
}
28+
29+
repositories {
30+
mavenCentral()
31+
google()
32+
}
33+
34+
base.archivesName.set("mongodb-driver-kotlin-extensions")
35+
36+
description = "The MongoDB Kotlin Driver Extensions"
37+
38+
ext.set("pomName", "MongoDB Kotlin Driver Extensions")
39+
40+
java { registerFeature("kotlinDrivers") { usingSourceSet(sourceSets["main"]) } }
41+
42+
dependencies {
43+
// Align versions of all Kotlin components
44+
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
45+
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
46+
47+
api(project(path = ":driver-core", configuration = "default"))
48+
49+
// Some extensions require higher API like MongoCollection which are defined in the sync &
50+
// coroutine Kotlin driver
51+
"kotlinDriversImplementation"(project(path = ":driver-kotlin-sync", configuration = "default"))
52+
"kotlinDriversImplementation"(project(path = ":driver-kotlin-coroutine", configuration = "default"))
53+
54+
testImplementation("org.jetbrains.kotlin:kotlin-reflect")
55+
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
56+
testImplementation("org.assertj:assertj-core:3.24.2")
57+
testImplementation("io.github.classgraph:classgraph:4.8.154")
58+
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
59+
}
60+
61+
kotlin { explicitApi() }
62+
63+
tasks.withType<KotlinCompile> {
64+
kotlinOptions {
65+
jvmTarget = "1.8"
66+
freeCompilerArgs =
67+
listOf(
68+
// Adds OnlyInputTypes support
69+
"-Xallow-kotlin-package",
70+
)
71+
}
72+
}
73+
74+
// ===========================
75+
// Code Quality checks
76+
// ===========================
77+
val customLicenseHeader = "/^(?s)(?!.*@custom-license-header).*/"
78+
79+
spotless {
80+
kotlinGradle {
81+
ktfmt("0.39").dropboxStyle().configure { it.setMaxWidth(120) }
82+
trimTrailingWhitespace()
83+
indentWithSpaces()
84+
endWithNewline()
85+
licenseHeaderFile(rootProject.file("config/mongodb.license"), "(group|plugins|import|buildscript|rootProject)")
86+
}
87+
88+
kotlin {
89+
target("**/*.kt")
90+
ktfmt().dropboxStyle().configure { it.setMaxWidth(120) }
91+
trimTrailingWhitespace()
92+
indentWithSpaces()
93+
endWithNewline()
94+
95+
licenseHeaderFile(rootProject.file("config/mongodb.license"))
96+
.named("standard")
97+
.onlyIfContentMatches(customLicenseHeader)
98+
}
99+
100+
format("extraneous") {
101+
target("*.xml", "*.yml", "*.md")
102+
trimTrailingWhitespace()
103+
indentWithSpaces()
104+
endWithNewline()
105+
}
106+
}
107+
108+
tasks.named("check") { dependsOn("spotlessApply") }
109+
110+
detekt {
111+
allRules = true // fail build on any finding
112+
buildUponDefaultConfig = true // preconfigure defaults
113+
config = rootProject.files("config/detekt/detekt.yml") // point to your custom config defining rules to run,
114+
// overwriting default behavior
115+
baseline = rootProject.file("config/detekt/baseline.xml") // a way of suppressing issues before introducing detekt
116+
source = files(file("src/main/kotlin"), file("src/test/kotlin"))
117+
}
118+
119+
tasks.withType<Detekt>().configureEach {
120+
reports {
121+
html.required.set(true) // observe findings in your browser with structure and code snippets
122+
xml.required.set(true) // checkstyle like format mainly for integrations like Jenkins
123+
txt.required.set(false) // similar to the console output, contains issue signature to manually edit
124+
}
125+
}
126+
127+
spotbugs { showProgress.set(true) }
128+
129+
tasks.spotbugsMain {
130+
// we need the xml report to find out the "rank" (see config/spotbugs/exclude.xml)
131+
reports.getByName("xml") { required.set(true) }
132+
}
133+
134+
// ===========================
135+
// Test Configuration
136+
// ===========================
137+
138+
tasks.test { useJUnitPlatform() }
139+
140+
// ===========================
141+
// Dokka Configuration
142+
// ===========================
143+
val dokkaOutputDir = "${rootProject.buildDir}/docs/${base.archivesName.get()}"
144+
145+
tasks.dokkaHtml.configure {
146+
outputDirectory.set(file(dokkaOutputDir))
147+
moduleName.set(base.archivesName.get())
148+
}
149+
150+
val cleanDokka by tasks.register<Delete>("cleanDokka") { delete(dokkaOutputDir) }
151+
152+
project.parent?.tasks?.named("docs") {
153+
dependsOn(tasks.dokkaHtml)
154+
mustRunAfter(cleanDokka)
155+
}
156+
157+
tasks.javadocJar.configure {
158+
dependsOn(cleanDokka, tasks.dokkaHtml)
159+
archiveClassifier.set("javadoc")
160+
from(dokkaOutputDir)
161+
}
162+
163+
// ===========================
164+
// Sources publishing configuration
165+
// ===========================
166+
tasks.sourcesJar { from(project.sourceSets.main.map { it.kotlin }) }
167+
168+
afterEvaluate { tasks.jar { manifest { attributes["Automatic-Module-Name"] = "org.mongodb.driver.kotlin.core" } } }

0 commit comments

Comments
 (0)