-
Notifications
You must be signed in to change notification settings - Fork 7
/
build.gradle
155 lines (124 loc) · 5.56 KB
/
build.gradle
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
import io.gitlab.arturbosch.detekt.Detekt
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
dependencies {
// Since version catalog is not available in buildscript, hardcode these dependencies
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.5"
classpath "org.jacoco:org.jacoco.core:0.8.11"
}
}
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.ben.manes.versions)
alias(libs.plugins.version.catalog.update)
alias(libs.plugins.google.services) apply false
alias(libs.plugins.firebase.crashlytics) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.ksp) apply false
}
ext {
minSdk = 27
compileSdk = 34
targetSdk = 34
internalVersionName = "babylon"
kotlinCompilerExtensionVersion = "1.5.8" // Get version from catalog
}
allprojects {
apply from: "$rootDir/config/detekt.gradle"
// Enable dependency locking for all configurations in all projects
dependencyLocking {
lockAllConfigurations()
}
tasks.withType(Detekt).configureEach {
exclude("**/test/**")
exclude("**/generated/**")
exclude("**/coreapi/**")
exclude("**/androidTest/**")
}
}
def isNonStable = { String version ->
def nonStable = ['ALPHA', 'BETA'].any { it -> version.toUpperCase().contains(it) }
return nonStable
}
tasks.named("dependencyUpdates").configure {
rejectVersionIf {
isNonStable(it.candidate.version)
}
}
/**
* Compares the current project dependencies with the ones stored in the dependencies.lock file
* Fails if the dependencies do no match and outputs the difference
*/
task compareDependencies {
dependsOn "generateCurrentDependencies"
def lockFile = new File(rootProject.rootDir, "dependencies.lock")
doFirst {
if (!lockFile.exists()) throw new IllegalStateException("${lockFile.path} file is missing. You may want to execute the 'generateDependenciesLockFile' task")
}
doLast {
println "Comparing current project dependencies with the one locked in the ${lockFile.path} file..."
def tmpLockFile = generateCurrentDependencies.outputs.getFiles().getSingleFile()
if (lockFile.text != tmpLockFile.text) {
println "diff ${lockFile.path} ${tmpLockFile.path}".execute().text
throw new IllegalStateException("""Project dependencies and lock dependencies are different. You may want to :
|- check why there is a difference
|- or execute the 'generateDependenciesLockFile' task to overwrite the current file""".stripMargin())
}
println "Dependencies match, all good !"
}
}
/**
* Generates a temporary file in the [buildDirectory] folder containing the tree structure of the app:dependencies command
* @returns tmpLockFile a RegularFileProperty
*/
abstract class GenerateCurrentDependencies extends DefaultTask {
@OutputFile
final abstract RegularFileProperty tmpLockFile = project.objects.fileProperty().convention(project.layout.buildDirectory.file('dependencies.lock.tmp'))
GenerateCurrentDependencies() {
outputs.upToDateWhen { false }
}
@TaskAction
void generateLockfile() {
println "Fetching project dependencies"
// Fetching the dependencies output for releaseRuntimeClasspath
def output = "./gradlew app:dependencies --configuration releaseRuntimeClasspath".execute().text
def startIndex = output.indexOf("releaseRuntimeClasspath")
def endIndex = output.indexOf("BUILD SUCCESSFUL")
def tmpFile = tmpLockFile.get().asFile
tmpFile.delete()
// Extracting and processing the dependency tree
def dependencies = output.substring(startIndex, endIndex).split("\n").findAll { it.contains("\\---") || it.contains("+---") }
dependencies.each { line ->
// Clean the line by removing any '|' characters, tabulation, version conflict markers '->', and symbols like (*) (c) FAILED
def cleanLine = line.replaceAll("[|\\t]", "").replaceAll("->.*", "").replaceAll("\\(\\*\\)", "").replaceAll("\\(c\\)", "").replaceAll("FAILED", "").trim()
// Process the remaining dependency info (group:artifact:version)
def parts = cleanLine.replaceFirst("(\\+---|\\|---|\\\\---)", "").split(":")
if (parts.size() == 3) {
def group = parts[0].trim()
def artifact = parts[1].trim()
def version = parts[2].trim()
// Write the formatted entry to the lockfile
tmpFile << "${group}:${artifact}:${version}=releaseRuntimeClasspath\n"
}
}
}
}
tasks.register('generateCurrentDependencies', GenerateCurrentDependencies)
/**
* Generates a dependencies.lock file containing the tree structure of the app:dependencies command
*/
task generateDependenciesLockFile {
dependsOn "generateCurrentDependencies"
def lockFile = new File(rootProject.rootDir, "dependencies.lock")
doLast {
println "Locking project dependencies..."
def tmpLockFile = generateCurrentDependencies.outputs.getFiles().getSingleFile()
lockFile.delete()
lockFile << tmpLockFile.text
println "Dependencies written down to ${lockFile.path}"
}
}