-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild.gradle.kts
More file actions
213 lines (190 loc) · 8.76 KB
/
Copy pathbuild.gradle.kts
File metadata and controls
213 lines (190 loc) · 8.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Plugin versions all come from gradle/libs.versions.toml — the single source of truth for every
// dependency/plugin version across modules. No buildscript{} classpath block is needed: applying
// plugins below via the version catalog is enough to put them on every subproject's classpath.
plugins {
id("weatherify.spotless")
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.android.kotlin.multiplatform.library) apply false
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.androidx.room) apply false
alias(libs.plugins.secrets.gradle.plugin) apply false
alias(libs.plugins.ktlint) apply false
// Declared here (not just via buildSrc) so it shares the same portal-resolved classloader as
// kotlin.multiplatform — detekt's KMP task registration needs KotlinMultiplatformExtension
// visible on its own classloader, which only holds if both plugins resolve from this one place.
alias(libs.plugins.detekt) apply false
alias(libs.plugins.ben.manes.versions)
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.compose.multiplatform) apply false
alias(libs.plugins.google.services) apply false
alias(libs.plugins.firebase.crashlytics) apply false
}
tasks.named<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask>("dependencyUpdates").configure {
checkForGradleUpdate = true
gradleReleaseChannel = com.github.benmanes.gradle.versions.updates.gradle.GradleReleaseChannel.RELEASE_CANDIDATE.id
revision = "integration"
outputFormatter = "plain"
outputDir = "build/dependencyUpdates"
reportfileName = "dependency_update_report"
}
// Deep clean task: runs all module clean tasks, then removes build artefacts and repo-local .gradle
tasks.register("deepClean") {
description = "Cleans every module and removes all build artefacts in this repo."
group = "build setup"
// Run each subproject's own clean task first (honors plugin-specific clean hooks)
dependsOn(subprojects.map { "${it.path}:clean" })
doLast {
val dirsToDelete =
mutableSetOf<File>().apply {
allprojects.forEach {
add(
it.layout.buildDirectory
.get()
.asFile,
)
}
add(
rootProject.layout.projectDirectory
.dir(".gradle")
.asFile,
)
}
delete(dirsToDelete)
}
}
// Quality checks configuration (spotless is a buildSrc convention plugin — see
// buildSrc/src/main/kotlin/weatherify.spotless.gradle.kts).
//
// Detekt stays configured here rather than as a convention plugin: its Kotlin-multiplatform task
// registration (DetektMultiplatform) references KotlinMultiplatformExtension directly, and that
// class is only visible on the classloader that resolved kotlin.multiplatform for this project —
// the one created by the `alias(libs.plugins.detekt) apply false` declaration above. Applying
// detekt from a buildSrc precompiled script instead loads it via buildSrc's own classloader, which
// can't see that per-project class and fails with NoClassDefFoundError.
allprojects {
apply(plugin = "weatherify.spotless")
}
subprojects {
// expect/actual classes are Beta in Kotlin; this repo relies on them across every KMP module
// (e.g. LocalAppLocale), so opt in globally instead of suppressing per-module.
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>().configureEach {
compilerOptions.freeCompilerArgs.add("-Xexpect-actual-classes")
}
apply(plugin = "io.gitlab.arturbosch.detekt")
// Per-module baselines (Detekt does not merge a single shared file across modules).
// Path uses the Gradle project path so :feature:home → feature-home.xml.
val detektBaselineFile =
file(
"${rootProject.projectDir}/config/detekt-baselines/${path.removePrefix(":").replace(':', '-')}.xml",
)
extensions.configure<io.gitlab.arturbosch.detekt.extensions.DetektExtension>("detekt") {
buildUponDefaultConfig = true
allRules = false
// Enforce new findings; existing debt is grandfathered per-module under config/detekt-baselines/
ignoreFailures = false
autoCorrect = false
parallel = true
config.setFrom(rootProject.layout.projectDirectory.file("config/detekt.yml"))
baseline = detektBaselineFile
}
// KMP registers source-set-specific Detekt tasks and leaves the plain :detekt /
// :detektBaseline tasks with empty inputs (NO-SOURCE). CI's detektAll / codeCheck depend
// on those plain tasks, so re-attach the module's hand-written sources here. Keep
// generated Compose/Room output out so baselines stay reviewable.
val detektSourceDirs =
listOf(
"src/main/java",
"src/main/kotlin",
"src/commonMain/kotlin",
"src/androidMain/kotlin",
"src/iosMain/kotlin",
"src/jvmMain/kotlin",
"src/commonTest/kotlin",
"src/androidUnitTest/kotlin",
"src/test/java",
"src/test/kotlin",
).map { file(it) }.filter { it.exists() }
tasks.named<io.gitlab.arturbosch.detekt.Detekt>("detekt").configure {
if (detektSourceDirs.isNotEmpty()) {
setSource(files(detektSourceDirs))
include("**/*.kt", "**/*.kts")
exclude("**/build/**", "**/generated/**", "**/res/**", "**/resources/**")
}
}
tasks.named<io.gitlab.arturbosch.detekt.DetektCreateBaselineTask>("detektBaseline").configure {
if (detektSourceDirs.isNotEmpty()) {
setSource(files(detektSourceDirs))
include("**/*.kt", "**/*.kts")
exclude("**/build/**", "**/generated/**", "**/res/**", "**/resources/**")
}
}
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
jvmTarget = "17"
exclude("**/build/**", "**/generated/**")
reports {
xml.required.set(false)
txt.required.set(false)
sarif.required.set(false)
md.required.set(false)
html.required.set(true)
}
}
tasks.register<io.gitlab.arturbosch.detekt.Detekt>("detektAutoCorrect") {
description = "Runs detekt with auto-correct enabled"
group = "verification"
autoCorrect = true
buildUponDefaultConfig = true
config.setFrom(rootProject.layout.projectDirectory.file("config/detekt.yml"))
baseline.set(detektBaselineFile)
// Auto-correct remains best-effort; enforcement happens on the regular detekt task
ignoreFailures = true
parallel = true
setSource(files("src"))
include("**/*.kt", "**/*.kts")
exclude("**/build/**", "**/generated/**")
}
tasks.named("detektAutoCorrect") { mustRunAfter("spotlessApply") }
}
// Aggregator tasks
tasks.register("spotlessCheckAll") {
group = "verification"
description = "Runs spotlessCheck in all subprojects"
dependsOn(subprojects.map { "${it.path}:spotlessCheck" })
}
tasks.register("spotlessApplyAll") {
group = "formatting"
description = "Runs spotlessApply in all subprojects"
dependsOn(subprojects.map { "${it.path}:spotlessApply" })
}
tasks.register("detektAll") {
group = "verification"
description = "Runs detekt in all subprojects"
dependsOn(subprojects.map { "${it.path}:detekt" })
}
tasks.register("detektBaselineAll") {
group = "verification"
description = "Regenerates per-module Detekt baselines under config/detekt-baselines/"
dependsOn(subprojects.map { "${it.path}:detektBaseline" })
}
tasks.register("detektAllAutoCorrect") {
group = "formatting"
description = "Runs detekt with auto-correct in all subprojects"
dependsOn(subprojects.map { "${it.path}:detektAutoCorrect" })
}
tasks.named("detektAllAutoCorrect") { mustRunAfter("spotlessApplyAll") }
// Single command: audit all style and lint issues without modifying files
tasks.register("codeCheck") {
group = "verification"
description = "Checks formatting (spotless) and runs detekt across all subprojects"
dependsOn("spotlessCheckAll", "detektAll")
}
// Single command: apply all auto-fixable formatting and lint corrections
tasks.register("codeFormat") {
group = "formatting"
description = "Applies spotless formatting and detekt auto-corrections across all subprojects"
dependsOn("spotlessApplyAll", "detektAllAutoCorrect")
}