Fix three ways the floating versions could have gone wrong quietly
All three shared a failure mode: the build stays green while doing something other than what the config says. composeBom was "2026.+". The Compose BOM numbers as YYYY.MM.PP, so the year is the major -- that float stops finding releases on 1 January 2027 and keeps building happily against a frozen BOM, with nothing in CI or the diff to say so. Bare "+" now, which is safe only because the prerelease guard is there. smart-exception was floating on "0.+". Under semver a 0.x minor may break, and this library is load-bearing precisely where breakage hides: the ffmpeg-kit wrapper reaches for smartexception.java.Exceptions only when a call FAILS, so a moved class shows up as an R8 missing-class error at release, or as a crash on the error path -- the least-exercised code in the app, by its own comment. Pinned, with that written down. It was noticed while the float was being written and shipped anyway, which is the actual mistake here. The prerelease guard permitted detekt's alpha by accident. The pattern wanted digits straight after the marker word, and detekt reads "2.0.0-alpha.6" with a dot -- so it passed on punctuation. Had it read "alpha6" the build would have broken with no way to see why from the config. There is now an explicit prereleasePermitted set, and the pattern tolerates both spellings, so the exemption is a decision instead of a coincidence. Also corrects a comment that was confidently wrong: componentSelection rejects STATIC prerelease versions too, not only floating ones. Naming "2.12.0-alpha01" in the catalog does not get you that alpha, it fails to resolve -- verified, not assumed, because the obvious guess is the opposite. Prereleases are taken by adding the group to prereleasePermitted. Two stale references to Gradle 9.5 updated to 9.7.1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-4
@@ -123,15 +123,31 @@ kotlin {
|
||||
// unreleased code on the next build, with nothing in the diff to say so.
|
||||
//
|
||||
// Rejecting them here means "+" reads as "the newest RELEASED version", which is what
|
||||
// floating was meant to buy. Trying an alpha stays possible -- name the exact version in
|
||||
// the catalog, and it is pinned rather than floating, which is the right way round.
|
||||
val prereleaseMarker = Regex("""[-.](alpha|beta|rc|eap|dev|snapshot|pre|m)\d*$""", RegexOption.IGNORE_CASE)
|
||||
// floating was meant to buy.
|
||||
//
|
||||
// Note that this applies to STATIC versions too, not only floating ones: naming
|
||||
// "2.12.0-alpha01" in the catalog does not get you that alpha, it fails to resolve. Verified,
|
||||
// because the obvious assumption is the opposite. The way to take a prerelease is to add its
|
||||
// group to prereleasePermitted below.
|
||||
// Groups allowed to be prereleases anyway. Membership is a deliberate, reviewable act --
|
||||
// which is the point, because the alternative is what was here first: detekt's alpha slipped
|
||||
// through only because its version reads "alpha.6" and the pattern below wanted digits
|
||||
// straight after the word. "alpha6" would have been rejected and the build would have broken
|
||||
// for a reason nobody could see. An accident that happens to work is not an exemption.
|
||||
val prereleasePermitted = setOf(
|
||||
// detekt 2.0 has not left alpha, and it is the only line with Gradle 9 support.
|
||||
"dev.detekt",
|
||||
)
|
||||
|
||||
val prereleaseMarker = Regex("""[-.](alpha|beta|rc|eap|dev|snapshot|pre|m)[-.]?\d*$""", RegexOption.IGNORE_CASE)
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy {
|
||||
componentSelection {
|
||||
all {
|
||||
if (prereleaseMarker.containsMatchIn(candidate.version)) {
|
||||
if (candidate.group !in prereleasePermitted &&
|
||||
prereleaseMarker.containsMatchIn(candidate.version)
|
||||
) {
|
||||
reject("prerelease; floating versions take released builds only")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@ ksp = "2.3.11"
|
||||
# app/build.gradle.kts is what keeps `+` from selecting an alpha: several of these
|
||||
# (lifecycle, navigation, work, datastore, annotation) publish alphas and RCs with
|
||||
# version numbers ABOVE their newest stable, and Gradle's `+` would take them.
|
||||
composeBom = "2026.+"
|
||||
# Bare `+`, not "2026.+": the year is the major in this scheme (YYYY.MM.PP), so a
|
||||
# 2026-prefixed float would quietly stop finding releases on 1 January and keep
|
||||
# building green against a frozen BOM.
|
||||
composeBom = "+"
|
||||
coreKtx = "1.+"
|
||||
activityCompose = "1.+"
|
||||
lifecycle = "2.+"
|
||||
@@ -31,7 +34,12 @@ annotation = "1.+"
|
||||
junit = "4.+"
|
||||
androidxJunit = "1.+"
|
||||
espressoCore = "3.+"
|
||||
smartException = "0.+"
|
||||
# PINNED, unlike its neighbours. Under semver a 0.x minor is allowed to break, and
|
||||
# this library is load-bearing exactly where breakage is hardest to see: the wrapper
|
||||
# reaches for smartexception.java.Exceptions only when an FFmpeg call FAILS, so a
|
||||
# moved class surfaces as an R8 missing-class error at release time, or as a crash on
|
||||
# the error path -- the least-exercised code in the app. Bump it deliberately.
|
||||
smartException = "0.2.1"
|
||||
|
||||
# Lint/format. PINNED, deliberately, while the libraries above float.
|
||||
#
|
||||
@@ -44,10 +52,10 @@ smartException = "0.+"
|
||||
# ktlint owns formatting; detekt owns static analysis (its formatting ruleset stays
|
||||
# off, so the two can never disagree about the same line).
|
||||
# detekt 2.0 is the only line with Gradle 9 support -- stable 1.23.x tops out at
|
||||
# Gradle 8.12, and this project is on 9.5.
|
||||
# Gradle 8.12, and this project is on 9.7.1.
|
||||
ktlint = "14.2.0"
|
||||
detekt = "2.0.0-alpha.6"
|
||||
# JaCoCo coverage agent. Pinned rather than inheriting whatever Gradle 9.5 bundles,
|
||||
# JaCoCo coverage agent. Pinned rather than inheriting whatever Gradle 9.7.1 bundles,
|
||||
# so the agent version that reads Kotlin 2.2.10 bytecode is stated, not implied.
|
||||
jacoco = "0.8.15"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user