Skip to content

Commit a82a21f

Browse files
committed
move common configuration from buildSrc to root build.gradle.kts
This repairs incremental build when the common configuration is changed. Changes in buildSrc always trigger a full rebuild.
1 parent 45b4ce1 commit a82a21f

File tree

5 files changed

+268
-316
lines changed

5 files changed

+268
-316
lines changed

build.gradle.kts

Lines changed: 268 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,232 @@
1+
@file:Suppress("UnstableApiUsage")
2+
3+
import java.io.FileInputStream
14
import java.util.*
5+
import com.android.build.api.dsl.ApplicationExtension
6+
import com.android.build.api.dsl.LibraryExtension
7+
import com.android.build.gradle.BaseExtension
8+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
9+
import org.kohsuke.github.GHReleaseBuilder
210
import org.kohsuke.github.GitHub
311

4-
plugins {
5-
idea
6-
}
7-
8-
idea {
9-
module {
10-
isDownloadSources = true
11-
isDownloadJavadoc = true
12+
buildscript {
13+
dependencies {
14+
classpath("com.android.tools.build:gradle:8.2.0")
15+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
16+
classpath("org.kohsuke:github-api:1.316")
17+
}
18+
19+
repositories {
20+
gradlePluginPortal()
21+
google()
22+
mavenCentral()
1223
}
1324
}
1425

1526
allprojects {
16-
apply {
17-
plugin("idea")
18-
}
19-
20-
idea {
21-
module {
22-
isDownloadSources = true
23-
isDownloadJavadoc = true
24-
}
25-
}
26-
27-
// apply common in afterEvaluate because other plugins need to be loaded first
27+
// apply in afterEvaluate because other plugins need to be loaded first
2828
afterEvaluate {
29-
apply {
30-
plugin("common")
29+
30+
val isAndroid = plugins.hasPlugin("com.android.application")
31+
val isAndroidLib = plugins.hasPlugin("com.android.library")
32+
// val isJavaLib = plugins.hasPlugin("java-library")
33+
val isKotlinLib = plugins.hasPlugin("org.jetbrains.kotlin.jvm")
34+
val isKotlinAndroid = plugins.hasPlugin("org.jetbrains.kotlin.android")
35+
36+
// if (isAndroid) println("android")
37+
// if (isAndroidLib) println("android lib")
38+
// if (isJavaLib) println("java lib")
39+
// if (isKotlinLib) println("kotlin lib")
40+
// if (isKotlinAndroid) println("kotlin android")
41+
42+
val javaVersion = JavaVersion.VERSION_17
43+
44+
val commitCount = getCommitCount()
45+
val commitHash = getCommitHash()
46+
val workingTreeClean = getWorkingTreeClean()
47+
val allCommitsPushed = getAllCommitsPushed()
48+
49+
if (isAndroid || isAndroidLib) {
50+
val android = extensions.getByType<BaseExtension>()
51+
with(android) {
52+
val propsFile = rootProject.file("keystore.properties")
53+
if (propsFile.exists()) {
54+
val props = Properties()
55+
props.load(FileInputStream(propsFile))
56+
57+
signingConfigs {
58+
maybeCreate("release").apply {
59+
storeFile = storeFile ?: rootProject.file(props["storeFile"].toString())
60+
61+
check(storeFile != null && storeFile!!.exists()) { "keystore does not exist" }
62+
63+
storePassword = storePassword ?: props["storePassword"].toString()
64+
keyAlias = keyAlias ?: props["keyAlias"].toString()
65+
keyPassword = keyPassword ?: props["keyPassword"].toString()
66+
67+
maybeCreate("debug").let { debug ->
68+
debug.storeFile = storeFile
69+
debug.storePassword = storePassword
70+
debug.keyAlias = keyAlias
71+
debug.keyPassword = keyPassword
72+
}
73+
}
74+
}
75+
defaultConfig {
76+
signingConfig = signingConfigs.getByName("release")
77+
}
78+
} else {
79+
defaultConfig {
80+
signingConfig = signingConfigs.getByName("debug")
81+
}
82+
}
83+
84+
defaultConfig {
85+
versionCode = commitCount
86+
versionName = "$commitCount${if (workingTreeClean) "-" else "+"}$commitHash"
87+
88+
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "../proguard-rules.pro")
89+
if (isAndroidLib) {
90+
consumerProguardFiles("consumer-rules.pro")
91+
}
92+
}
93+
94+
buildTypes {
95+
getByName("release") {
96+
isMinifyEnabled = true
97+
multiDexEnabled = false
98+
99+
if (isAndroid) {
100+
isShrinkResources = true
101+
}
102+
}
103+
getByName("debug") {
104+
isMinifyEnabled = false
105+
isShrinkResources = false
106+
multiDexEnabled = false
107+
versionNameSuffix = "-dev"
108+
}
109+
}
110+
111+
compileOptions {
112+
sourceCompatibility = javaVersion
113+
targetCompatibility = javaVersion
114+
}
115+
}
116+
}
117+
118+
if (isAndroid) {
119+
val common = extensions.getByType<ApplicationExtension>()
120+
with(common) {
121+
compileSdk = 34
122+
123+
dependenciesInfo {
124+
includeInApk = false
125+
includeInBundle = false
126+
}
127+
128+
buildFeatures {
129+
buildConfig = true
130+
}
131+
132+
lint {
133+
disable += "DiscouragedApi"
134+
disable += "ExpiredTargedSdkVersion"
135+
disable += "OldTargetApi"
136+
disable += "MissingApplicationIcon"
137+
disable += "UnusedAttribute"
138+
}
139+
}
140+
}
141+
142+
if (isAndroidLib) {
143+
val common = extensions.getByType<LibraryExtension>()
144+
with(common) {
145+
compileSdk = 34
146+
}
147+
}
148+
149+
if (isAndroid) {
150+
val android = extensions.getByType<BaseExtension>()
151+
152+
tasks.register("createGithubRelease") {
153+
check(workingTreeClean) { "Commit all changes before creating release" }
154+
check(allCommitsPushed) { "Push to remote before creating release" }
155+
156+
dependsOn("assembleRelease")
157+
158+
val properties = Properties()
159+
val file = rootProject.file("local.properties")
160+
if (file.exists()) {
161+
properties.load(file.inputStream())
162+
}
163+
164+
val repo = properties["github_repo"]
165+
val token = properties["github_api_key"]
166+
167+
check(repo != null && repo is String) { "github_repo not provided in local.properties" }
168+
check(token != null && token is String) { "github_api_key not provided in local.properties" }
169+
170+
doFirst {
171+
val packageRelease = project.tasks.getByName<DefaultTask>("packageRelease")
172+
173+
val outputs = packageRelease.outputs.files
174+
val apks = outputs.filter { it.isDirectory }.flatMap { it.listFiles { file -> file.extension == "apk" }!!.toList() }
175+
176+
val github = GitHub.connectUsingOAuth(token)
177+
val repository = github.getRepository(repo)
178+
179+
val tagName = "${android.namespace}-v$commitCount"
180+
val name = "${project.name}-v$commitCount"
181+
182+
if (repository.getReleaseByTagName(tagName) != null) {
183+
doLast {
184+
println("Release $name already exists")
185+
}
186+
return@doFirst
187+
}
188+
189+
val release = repository.createRelease(tagName).name(name).draft(true).makeLatest(GHReleaseBuilder.MakeLatest.FALSE).create()
190+
191+
apks.forEach {
192+
release.uploadAsset("${project.name}-v$commitCount.apk", it.inputStream(), "application/vnd.android.package-archive")
193+
}
194+
195+
doLast {
196+
println("Created release ${release.name}: ${release.htmlUrl}")
197+
}
198+
}
199+
}
200+
201+
android.packagingOptions {
202+
resources.excludes += listOf(
203+
"**/*.kotlin_builtins",
204+
"**/*.kotlin_metadata",
205+
"**/*.kotlin_module",
206+
"kotlin-tooling-metadata.json",
207+
)
208+
}
209+
}
210+
211+
tasks.withType<KotlinCompile> {
212+
kotlinOptions.jvmTarget = javaVersion.toString()
213+
}
214+
215+
tasks.withType<JavaCompile> {
216+
sourceCompatibility = javaVersion.toString()
217+
targetCompatibility = javaVersion.toString()
218+
}
219+
220+
if (isAndroid || isAndroidLib) {
221+
dependencies {
222+
add("compileOnly", "de.robv.android.xposed:api:82")
223+
}
224+
}
225+
226+
if (isKotlinLib || isKotlinAndroid) {
227+
dependencies {
228+
add("implementation", "org.jetbrains:annotations:24.1.0")
229+
}
31230
}
32231
}
33232
}
@@ -53,3 +252,50 @@ tasks.create("clearAllDraftReleases") {
53252
}
54253
}
55254
}
255+
256+
//<editor-fold desc="Git">
257+
fun Project.getCommitCountExec() = providers.exec {
258+
executable("git")
259+
args("rev-list", "--count", "HEAD", projectDir.absolutePath)
260+
261+
extensions.findByType<BaseExtension>()?.let {
262+
val metadata = rootProject.file("metadata").resolve(it.namespace!!)
263+
if (metadata.exists()) {
264+
args(metadata)
265+
}
266+
}
267+
}
268+
269+
fun Project.getCommitHashExec() = providers.exec {
270+
executable("git")
271+
args("rev-parse", "--short", "HEAD")
272+
}
273+
274+
fun Project.getWorkingTreeCleanExec() = providers.exec {
275+
executable("git")
276+
args("diff", "--quiet", "--exit-code", rootDir.absolutePath)
277+
isIgnoreExitValue = true
278+
}
279+
280+
fun Project.getAllCommitsPushedExec(): ExecOutput {
281+
providers.exec {
282+
executable("git")
283+
args("fetch")
284+
isIgnoreExitValue = true
285+
}
286+
287+
return providers.exec {
288+
executable("git")
289+
args("diff", "--quiet", "--exit-code", "origin/main..main")
290+
isIgnoreExitValue = true
291+
}
292+
}
293+
294+
fun Project.getCommitCount() = getCommitCountExec().standardOutput.asText.get().trim().toInt()
295+
296+
fun Project.getCommitHash() = getCommitHashExec().standardOutput.asText.get().trim()
297+
298+
fun Project.getWorkingTreeClean() = getWorkingTreeCleanExec().result.orNull?.exitValue == 0
299+
300+
fun Project.getAllCommitsPushed() = getAllCommitsPushedExec().result.orNull?.exitValue == 0
301+
//</editor-fold>

buildSrc/build.gradle.kts

Lines changed: 0 additions & 11 deletions
This file was deleted.

buildSrc/settings.gradle.kts

Lines changed: 0 additions & 20 deletions
This file was deleted.

buildSrc/src/main/kotlin/Git.kt

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)