Skip to content

Commit e5f8eb9

Browse files
authored
Auto install Spring Boot 4 and Spring 7 modules (#980)
1 parent 4dd2302 commit e5f8eb9

File tree

12 files changed

+379
-0
lines changed

12 files changed

+379
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
- Add upload functionality for size analysis ([#915](https://github.com/getsentry/sentry-android-gradle-plugin/pull/915))
88
- Add VCS info extension for build uploads with customizable version control metadata ([#969](https://github.com/getsentry/sentry-android-gradle-plugin/pull/969))
99
- Include version in logs if auto install refuses to install a dependency ([#979](https://github.com/getsentry/sentry-android-gradle-plugin/pull/979))
10+
- Auto install Spring Boot 4 (`sentry-spring-boot-4`) and Spring 7 (`sentry-spring-7`) modules ([#980](https://github.com/getsentry/sentry-android-gradle-plugin/pull/980))
1011

1112
### Fixes
1213

1314
- Enable caching for BundleSourcesTask ([#894](https://github.com/getsentry/sentry-android-gradle-plugin/pull/894)
1415
- Add support for Kotlin 2.2.0 for Sentry Kotlin Compiler Plugin ([#944](https://github.com/getsentry/sentry-android-gradle-plugin/pull/944))
16+
- Sentry dependencies intended for Spring Boot 3 / Spring 6 will no longer be installed for Spring Boot 4 / Spring 7 ([#980](https://github.com/getsentry/sentry-android-gradle-plugin/pull/980))
1517
- Allow lazily configured version details for ProGuard mappings ([#974](https://github.com/getsentry/sentry-android-gradle-plugin/pull/974))
1618

1719
### Breaking Changes

plugin-build/src/main/kotlin/io/sentry/android/gradle/autoinstall/AutoInstall.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import io.sentry.android.gradle.autoinstall.override.WarnOnOverrideStrategy
1414
import io.sentry.android.gradle.autoinstall.quartz.QuartzInstallStrategy
1515
import io.sentry.android.gradle.autoinstall.spring.Spring5InstallStrategy
1616
import io.sentry.android.gradle.autoinstall.spring.Spring6InstallStrategy
17+
import io.sentry.android.gradle.autoinstall.spring.Spring7InstallStrategy
1718
import io.sentry.android.gradle.autoinstall.spring.SpringBoot2InstallStrategy
1819
import io.sentry.android.gradle.autoinstall.spring.SpringBoot3InstallStrategy
20+
import io.sentry.android.gradle.autoinstall.spring.SpringBoot4InstallStrategy
1921
import io.sentry.android.gradle.autoinstall.sqlite.SQLiteInstallStrategy
2022
import io.sentry.android.gradle.autoinstall.timber.TimberInstallStrategy
2123
import io.sentry.android.gradle.extensions.SentryPluginExtension
@@ -48,8 +50,10 @@ private val delayedStrategies =
4850
listOf(
4951
Spring5InstallStrategy.Registrar,
5052
Spring6InstallStrategy.Registrar,
53+
Spring7InstallStrategy.Registrar,
5154
SpringBoot2InstallStrategy.Registrar,
5255
SpringBoot3InstallStrategy.Registrar,
56+
SpringBoot4InstallStrategy.Registrar,
5357
)
5458

5559
fun Project.installDependencies(extension: SentryPluginExtension, isAndroid: Boolean) {
@@ -115,6 +119,7 @@ private fun DependencySet.findSentryVersion(isAndroid: Boolean): String? =
115119
(it.name == SentryModules.SENTRY.name ||
116120
it.name == SentryModules.SENTRY_SPRING_BOOT2.name ||
117121
it.name == SentryModules.SENTRY_SPRING_BOOT3.name ||
122+
it.name == SentryModules.SENTRY_SPRING_BOOT4.name ||
118123
it.name == SentryModules.SENTRY_BOM.name ||
119124
it.name == SentryModules.SENTRY_OPENTELEMETRY_AGENTLESS.name ||
120125
it.name == SentryModules.SENTRY_OPENTELEMETRY_AGENTLESS_SPRING.name) &&

plugin-build/src/main/kotlin/io/sentry/android/gradle/autoinstall/override/WarnOnOverrideStrategy.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ abstract class WarnOnOverrideStrategy : ComponentMetadataRule {
7676
SentryModules.SENTRY_QUARTZ,
7777
SentryModules.SENTRY_SPRING5,
7878
SentryModules.SENTRY_SPRING6,
79+
SentryModules.SENTRY_SPRING7,
7980
SentryModules.SENTRY_SPRING_BOOT2,
8081
SentryModules.SENTRY_SPRING_BOOT3,
82+
SentryModules.SENTRY_SPRING_BOOT4,
8183
)
8284

8385
override fun register(component: ComponentMetadataHandler) {

plugin-build/src/main/kotlin/io/sentry/android/gradle/autoinstall/spring/Spring6InstallStrategy.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ abstract class Spring6InstallStrategy : AbstractInstallStrategy {
2525
override val minSupportedThirdPartyVersion: SemVer
2626
get() = MIN_SUPPORTED_VERSION
2727

28+
override val maxSupportedThirdPartyVersion: SemVer
29+
get() = MAX_SUPPORTED_VERSION
30+
2831
override val minSupportedSentryVersion: SemVer
2932
get() = SemVer(6, 7, 0)
3033

@@ -34,6 +37,7 @@ abstract class Spring6InstallStrategy : AbstractInstallStrategy {
3437
internal const val SENTRY_SPRING_6_ID = "sentry-spring-jakarta"
3538

3639
private val MIN_SUPPORTED_VERSION = SemVer(6, 0, 0)
40+
private val MAX_SUPPORTED_VERSION = SemVer(6, 9999, 9999)
3741

3842
override fun register(component: ComponentMetadataHandler) {
3943
component.withModule("$SPRING_GROUP:$SPRING_6_ID", Spring6InstallStrategy::class.java) {}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.sentry.android.gradle.autoinstall.spring
2+
3+
import io.sentry.android.gradle.SentryPlugin
4+
import io.sentry.android.gradle.autoinstall.AbstractInstallStrategy
5+
import io.sentry.android.gradle.autoinstall.InstallStrategyRegistrar
6+
import io.sentry.android.gradle.util.SemVer
7+
import javax.inject.Inject
8+
import org.gradle.api.artifacts.dsl.ComponentMetadataHandler
9+
import org.slf4j.Logger
10+
11+
// @CacheableRule
12+
abstract class Spring7InstallStrategy : AbstractInstallStrategy {
13+
14+
constructor(logger: Logger) : super() {
15+
this.logger = logger
16+
}
17+
18+
@Suppress("unused") // used by Gradle
19+
@Inject // inject is needed to avoid Gradle error
20+
constructor() : this(SentryPlugin.logger)
21+
22+
override val sentryModuleId: String
23+
get() = SENTRY_SPRING_7_ID
24+
25+
override val minSupportedThirdPartyVersion: SemVer
26+
get() = MIN_SUPPORTED_VERSION
27+
28+
override val maxSupportedThirdPartyVersion: SemVer
29+
get() = MAX_SUPPORTED_VERSION
30+
31+
override val minSupportedSentryVersion: SemVer
32+
get() = SemVer(8, 21, 0)
33+
34+
companion object Registrar : InstallStrategyRegistrar {
35+
private const val SPRING_GROUP = "org.springframework"
36+
private const val SPRING_7_ID = "spring-core"
37+
internal const val SENTRY_SPRING_7_ID = "sentry-spring-7"
38+
39+
private val MIN_SUPPORTED_VERSION = SemVer(7, 0, 0, "M1")
40+
private val MAX_SUPPORTED_VERSION = SemVer(7, 9999, 9999)
41+
42+
override fun register(component: ComponentMetadataHandler) {
43+
component.withModule("$SPRING_GROUP:$SPRING_7_ID", Spring7InstallStrategy::class.java) {}
44+
}
45+
}
46+
}

plugin-build/src/main/kotlin/io/sentry/android/gradle/autoinstall/spring/SpringBoot3InstallStrategy.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ abstract class SpringBoot3InstallStrategy : AbstractInstallStrategy {
2525
override val minSupportedThirdPartyVersion: SemVer
2626
get() = MIN_SUPPORTED_VERSION
2727

28+
override val maxSupportedThirdPartyVersion: SemVer
29+
get() = MAX_SUPPORTED_VERSION
30+
2831
override val minSupportedSentryVersion: SemVer
2932
get() = SemVer(6, 28, 0)
3033

@@ -34,6 +37,7 @@ abstract class SpringBoot3InstallStrategy : AbstractInstallStrategy {
3437
internal const val SENTRY_SPRING_BOOT_3_ID = "sentry-spring-boot-jakarta"
3538

3639
private val MIN_SUPPORTED_VERSION = SemVer(3, 0, 0)
40+
private val MAX_SUPPORTED_VERSION = SemVer(3, 9999, 9999)
3741

3842
override fun register(component: ComponentMetadataHandler) {
3943
component.withModule(
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.sentry.android.gradle.autoinstall.spring
2+
3+
import io.sentry.android.gradle.SentryPlugin
4+
import io.sentry.android.gradle.autoinstall.AbstractInstallStrategy
5+
import io.sentry.android.gradle.autoinstall.InstallStrategyRegistrar
6+
import io.sentry.android.gradle.util.SemVer
7+
import javax.inject.Inject
8+
import org.gradle.api.artifacts.dsl.ComponentMetadataHandler
9+
import org.slf4j.Logger
10+
11+
// @CacheableRule
12+
abstract class SpringBoot4InstallStrategy : AbstractInstallStrategy {
13+
14+
constructor(logger: Logger) : super() {
15+
this.logger = logger
16+
}
17+
18+
@Suppress("unused") // used by Gradle
19+
@Inject // inject is needed to avoid Gradle error
20+
constructor() : this(SentryPlugin.logger)
21+
22+
override val sentryModuleId: String
23+
get() = SENTRY_SPRING_BOOT_4_ID
24+
25+
override val minSupportedThirdPartyVersion: SemVer
26+
get() = MIN_SUPPORTED_VERSION
27+
28+
override val maxSupportedThirdPartyVersion: SemVer
29+
get() = MAX_SUPPORTED_VERSION
30+
31+
override val minSupportedSentryVersion: SemVer
32+
get() = SemVer(8, 21, 0)
33+
34+
companion object Registrar : InstallStrategyRegistrar {
35+
private const val SPRING_GROUP = "org.springframework.boot"
36+
private const val SPRING_BOOT_4_ID = "spring-boot"
37+
internal const val SENTRY_SPRING_BOOT_4_ID = "sentry-spring-boot-4"
38+
39+
private val MIN_SUPPORTED_VERSION = SemVer(4, 0, 0, "M1")
40+
private val MAX_SUPPORTED_VERSION = SemVer(4, 9999, 9999)
41+
42+
override fun register(component: ComponentMetadataHandler) {
43+
component.withModule(
44+
"$SPRING_GROUP:$SPRING_BOOT_4_ID",
45+
SpringBoot4InstallStrategy::class.java,
46+
) {}
47+
}
48+
}
49+
}

plugin-build/src/main/kotlin/io/sentry/android/gradle/util/Versions.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ internal object SentryModules {
5757
internal val SENTRY_QUARTZ = DefaultModuleIdentifier.newId("io.sentry", "sentry-quartz")
5858
internal val SENTRY_SPRING5 = DefaultModuleIdentifier.newId("io.sentry", "sentry-spring")
5959
internal val SENTRY_SPRING6 = DefaultModuleIdentifier.newId("io.sentry", "sentry-spring-jakarta")
60+
internal val SENTRY_SPRING7 = DefaultModuleIdentifier.newId("io.sentry", "sentry-spring-7")
6061
internal val SENTRY_SPRING_BOOT2 =
6162
DefaultModuleIdentifier.newId("io.sentry", "sentry-spring-boot")
6263
internal val SENTRY_SPRING_BOOT3 =
6364
DefaultModuleIdentifier.newId("io.sentry", "sentry-spring-boot-jakarta")
65+
internal val SENTRY_SPRING_BOOT4 =
66+
DefaultModuleIdentifier.newId("io.sentry", "sentry-spring-boot-4")
6467
internal val SENTRY_BOM = DefaultModuleIdentifier.newId("io.sentry", "sentry-bom")
6568
internal val SENTRY_OPENTELEMETRY_AGENTLESS =
6669
DefaultModuleIdentifier.newId("io.sentry", "sentry-opentelemetry-agentless")

plugin-build/src/test/kotlin/io/sentry/android/gradle/autoinstall/spring/Spring6InstallStrategyTest.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ class Spring6InstallStrategyTest {
6868
verify(fixture.metadataDetails, never()).allVariants(any())
6969
}
7070

71+
@Test
72+
fun `when spring version is too high logs a message and does nothing`() {
73+
val sut = fixture.getSut(springVersion = "7.0.0")
74+
sut.execute(fixture.metadataContext)
75+
76+
assertTrue {
77+
fixture.logger.capturedMessage ==
78+
"[sentry] sentry-spring-jakarta won't be installed because the current " +
79+
"version (7.0.0) is higher than the maximum supported version (6.9999.9999)"
80+
}
81+
verify(fixture.metadataDetails, never()).allVariants(any())
82+
}
83+
7184
@Test
7285
fun `installs sentry-spring-jakarta with info message`() {
7386
val sut = fixture.getSut()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package io.sentry.android.gradle.autoinstall.spring
2+
3+
import com.nhaarman.mockitokotlin2.any
4+
import com.nhaarman.mockitokotlin2.doAnswer
5+
import com.nhaarman.mockitokotlin2.doReturn
6+
import com.nhaarman.mockitokotlin2.mock
7+
import com.nhaarman.mockitokotlin2.never
8+
import com.nhaarman.mockitokotlin2.verify
9+
import com.nhaarman.mockitokotlin2.whenever
10+
import io.sentry.android.gradle.autoinstall.AutoInstallState
11+
import io.sentry.android.gradle.instrumentation.fakes.CapturingTestLogger
12+
import kotlin.test.assertEquals
13+
import kotlin.test.assertTrue
14+
import org.gradle.api.Action
15+
import org.gradle.api.artifacts.ComponentMetadataContext
16+
import org.gradle.api.artifacts.ComponentMetadataDetails
17+
import org.gradle.api.artifacts.DirectDependenciesMetadata
18+
import org.gradle.api.artifacts.ModuleVersionIdentifier
19+
import org.gradle.api.artifacts.VariantMetadata
20+
import org.junit.Test
21+
import org.slf4j.Logger
22+
23+
class Spring7InstallStrategyTest {
24+
class Fixture {
25+
val logger = CapturingTestLogger()
26+
val dependencies = mock<DirectDependenciesMetadata>()
27+
val metadataDetails = mock<ComponentMetadataDetails>()
28+
val metadataContext =
29+
mock<ComponentMetadataContext> {
30+
whenever(it.details).thenReturn(metadataDetails)
31+
val metadata = mock<VariantMetadata>()
32+
doAnswer { (it.arguments[0] as Action<DirectDependenciesMetadata>).execute(dependencies) }
33+
.whenever(metadata)
34+
.withDependencies(any<Action<DirectDependenciesMetadata>>())
35+
36+
doAnswer {
37+
// trigger the callback registered in tests
38+
(it.arguments[0] as Action<VariantMetadata>).execute(metadata)
39+
}
40+
.whenever(metadataDetails)
41+
.allVariants(any<Action<VariantMetadata>>())
42+
}
43+
44+
fun getSut(springVersion: String = "7.0.0"): Spring7InstallStrategy {
45+
val id = mock<ModuleVersionIdentifier> { whenever(it.version).doReturn(springVersion) }
46+
whenever(metadataDetails.id).thenReturn(id)
47+
48+
with(AutoInstallState.getInstance()) {
49+
this.enabled = true
50+
this.sentryVersion = "8.21.0"
51+
}
52+
return Spring7InstallStrategyImpl(logger)
53+
}
54+
}
55+
56+
private val fixture = Fixture()
57+
58+
@Test
59+
fun `when spring version is too low logs a message and does nothing`() {
60+
val sut = fixture.getSut(springVersion = "6.7.4")
61+
sut.execute(fixture.metadataContext)
62+
63+
assertTrue {
64+
fixture.logger.capturedMessage ==
65+
"[sentry] sentry-spring-7 won't be installed because the current " +
66+
"version (6.7.4) is lower than the minimum supported version (7.0.0-M1)"
67+
}
68+
verify(fixture.metadataDetails, never()).allVariants(any())
69+
}
70+
71+
@Test
72+
fun `when spring version is too high logs a message and does nothing`() {
73+
val sut = fixture.getSut(springVersion = "8.0.0")
74+
sut.execute(fixture.metadataContext)
75+
76+
assertTrue {
77+
fixture.logger.capturedMessage ==
78+
"[sentry] sentry-spring-7 won't be installed because the current " +
79+
"version (8.0.0) is higher than the maximum supported version (7.9999.9999)"
80+
}
81+
verify(fixture.metadataDetails, never()).allVariants(any())
82+
}
83+
84+
@Test
85+
fun `installs sentry-spring-jakarta with info message`() {
86+
val sut = fixture.getSut()
87+
sut.execute(fixture.metadataContext)
88+
89+
assertTrue {
90+
fixture.logger.capturedMessage ==
91+
"[sentry] sentry-spring-7 was successfully installed with version: 8.21.0"
92+
}
93+
verify(fixture.dependencies)
94+
.add(
95+
com.nhaarman.mockitokotlin2.check<String> {
96+
assertEquals("io.sentry:sentry-spring-7:8.21.0", it)
97+
}
98+
)
99+
}
100+
101+
private class Spring7InstallStrategyImpl(logger: Logger) : Spring7InstallStrategy(logger)
102+
}

0 commit comments

Comments
 (0)