Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ plugins {

</details>

> [!TIP]
> Upgrading from 1.x? See the [2.0 Migration Guide](docs/migration-guide.md).

## Usage
Expand Down
11 changes: 1 addition & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mavenPublishing {
}

gradleTestKitSupport {
withSupportLibrary()
disablePublication()
}

Expand Down Expand Up @@ -56,11 +57,6 @@ java {
targetCompatibility = JavaVersion.VERSION_17
}

val fixtureClasspath = configurations.create("fixtureClasspath")
tasks.pluginUnderTestMetadata {
pluginClasspath.from(fixtureClasspath)
}

tasks.withType<Test>().configureEach {
testLogging {
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
Expand All @@ -87,11 +83,6 @@ dependencies {
functionalTestImplementation(kotlin("test-junit"))
functionalTestImplementation(libs.burst)
functionalTestImplementation(libs.agp.build.api)
fixtureClasspath(libs.agp.build.gradle.flatMap { dependency ->
fixtureAgpVersion.map { version ->
"${dependency.group}:${dependency.name}:$version"
}
})
detektPlugins(libs.plugin.detektKtlintWrapper)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ class AppVersioningPluginIntegrationTest(
initGitRepo(fixtureDir.root)

val extension = """
appVersioning {
releaseBuildOnly.set(true)
}
""".trimIndent()
|appVersioning {
| releaseBuildOnly.set(true)
|}
""".trimMargin()
withFixtureRunner(
fixtureDir = fixtureDir,
subprojects = listOf(
Expand Down Expand Up @@ -178,10 +178,10 @@ class AppVersioningPluginIntegrationTest(
initGitRepo(fixtureDir.root)

val extension = """
appVersioning {
enabled.set(false)
}
""".trimIndent()
|appVersioning {
| enabled.set(false)
|}
""".trimMargin()
withFixtureRunner(
fixtureDir = fixtureDir,
subprojects = listOf(
Expand Down Expand Up @@ -296,10 +296,10 @@ class AppVersioningPluginIntegrationTest(
}

val extension = """
appVersioning {
enabled.set(false)
}
""".trimIndent()
|appVersioning {
| enabled.set(false)
|}
""".trimMargin()
withFixtureRunner(
fixtureDir = fixtureDir,
subprojects = listOf(
Expand Down Expand Up @@ -347,35 +347,35 @@ class AppVersioningPluginIntegrationTest(

val extensionAppA = if (buildScriptLanguage == BuildScriptLanguage.Kts) {
$$"""
appVersioning {
tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appA")
versionCode.set {
tag.toSemVer().toVersionCode() + tag.commitsSinceLatestTag
}
versionName.set {
"appA-${tag.name}"
}
}
""".trimIndent()
|appVersioning {
| tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appA")
| versionCode.set {
| tag.toSemVer().toVersionCode() + tag.commitsSinceLatestTag
| }
| versionName.set {
| "appA-${tag.name}"
| }
|}
""".trimMargin()
} else {
$$"""
appVersioning {
tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appA")
versionCode {
tag.toSemVer().toVersionCode() + tag.commitsSinceLatestTag
}
versionName {
"appA-${tag.name}"
}
}
""".trimIndent()
|appVersioning {
| tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appA")
| versionCode {
| tag.toSemVer().toVersionCode() + tag.commitsSinceLatestTag
| }
| versionName {
| "appA-${tag.name}"
| }
|}
""".trimMargin()
}

val extensionAppB = """
appVersioning {
tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appB")
}
""".trimIndent()
|appVersioning {
| tagFilter.set("[0-9]*.[0-9]*.[0-9]*+appB")
|}
""".trimMargin()

val runner = withFixtureRunner(
fixtureDir = fixtureDir,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package io.github.reactivecircus.appversioning.fixtures

import com.autonomousapps.kit.AbstractGradleProject
import com.autonomousapps.kit.gradle.BuildScript
import com.autonomousapps.kit.gradle.Imports
import com.autonomousapps.kit.gradle.Plugin

sealed class AndroidProjectTemplate {
abstract val projectName: String
abstract val pluginExtension: String?
abstract val buildScriptLanguage: BuildScriptLanguage
abstract val flavors: List<String>
abstract val imports: List<String>

internal fun buildScript(fixtureAgpVersion: String): BuildScript {
val androidPluginId = if (this is AppProjectTemplate) "com.android.application" else "com.android.library"
return BuildScript.Builder().apply {
if (this@AndroidProjectTemplate.imports.isNotEmpty()) {
imports = Imports.of(this@AndroidProjectTemplate.imports)
}
plugins(
Plugin(androidPluginId, fixtureAgpVersion),
AppVersioningPlugin,
)
additions = androidBlock() + "\n\n" + pluginExtension.orEmpty()
}.build()
}

private fun androidBlock(): String = when (buildScriptLanguage) {
BuildScriptLanguage.Kts -> kotlinAndroidBlock()
BuildScriptLanguage.Groovy -> groovyAndroidBlock()
}

private fun kotlinAndroidBlock(): String {
val flavorConfigs = if (flavors.isNotEmpty()) {
"""
|flavorDimensions.add("environment")
|productFlavors {
| ${flavors.joinToString("\n") { "register(\"$it\") {}" }}
|}
""".trimMargin()
} else {
""
}
val abiConfigs = if (this is AppProjectTemplate && splitsApks) {
"""
|splits {
| abi {
| isEnable = true
| reset()
| include("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
| isUniversalApk = $universalApk
| }
|}
""".trimMargin()
} else {
""
}
return """
|android {
| namespace = "$DEFAULT_PACKAGE_NAME.${projectName.replace("-", ".")}"
| compileSdk = 36
| defaultConfig {
| minSdk = 21
| ${if (this is AppProjectTemplate) "targetSdk = 36" else ""}
| }
| lint.checkReleaseBuilds = false
|
| $flavorConfigs
|
| $abiConfigs
|}
""".trimMargin()
}

private fun groovyAndroidBlock(): String {
val flavorConfigs = if (flavors.isNotEmpty()) {
"""
|flavorDimensions "environment"
|productFlavors {
| ${flavors.joinToString("\n") { "$it {}" }}
|}
""".trimMargin()
} else {
""
}
val abiConfigs = if (this is AppProjectTemplate && splitsApks) {
"""
|splits {
| abi {
| enable true
| reset()
| include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
| universalApk $universalApk
| }
|}
""".trimMargin()
} else {
""
}
return """
|android {
| namespace '$DEFAULT_PACKAGE_NAME.${projectName.replace("-", ".")}'
| compileSdk 36
| defaultConfig {
| minSdk 21
| ${if (this is AppProjectTemplate) "targetSdk 36" else ""}
| }
| lint {
| checkReleaseBuilds false
| }
|
| $flavorConfigs
|
| $abiConfigs
|}
""".trimMargin()
}

val manifestFileContent: String
get() = """
|<?xml version="1.0" encoding="utf-8"?>
|<manifest />
""".trimMargin()

companion object {
private const val DEFAULT_PACKAGE_NAME = "io.github.reactivecircus.appversioning"
}
}

private val AppVersioningPlugin = Plugin(
id = "io.github.reactivecircus.app-versioning",
version = AbstractGradleProject.PLUGIN_UNDER_TEST_VERSION,
)

class AppProjectTemplate(
override val projectName: String = "app",
override val pluginExtension: String? = null,
override val buildScriptLanguage: BuildScriptLanguage = BuildScriptLanguage.Kts,
override val flavors: List<String> = emptyList(),
val splitsApks: Boolean = false,
val universalApk: Boolean = false,
override val imports: List<String> = emptyList(),
) : AndroidProjectTemplate()

class LibraryProjectTemplate(
override val projectName: String = "library",
override val pluginExtension: String? = null,
override val buildScriptLanguage: BuildScriptLanguage = BuildScriptLanguage.Kts,
override val flavors: List<String> = emptyList(),
override val imports: List<String> = emptyList(),
) : AndroidProjectTemplate()
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.github.reactivecircus.appversioning.fixtures

import com.autonomousapps.kit.GradleProject

enum class BuildScriptLanguage {
Kts,
Groovy;

internal val dslKind: GradleProject.DslKind
get() = if (this == Kts) GradleProject.DslKind.KOTLIN else GradleProject.DslKind.GROOVY
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.github.reactivecircus.appversioning.fixtures

import com.autonomousapps.kit.GradleProject
import com.autonomousapps.kit.gradle.GradleProperties
import java.io.File

internal fun createFixtureProject(
fixtureDir: File,
subprojects: List<AndroidProjectTemplate>,
parentDirectoryName: String?,
): GradleProject {
val buildScriptLanguage = subprojects.firstOrNull()?.buildScriptLanguage ?: BuildScriptLanguage.Kts
require(subprojects.all { it.buildScriptLanguage == buildScriptLanguage }) {
"All subprojects in a fixture must use the same build script language."
}
val gradleRoot = if (parentDirectoryName.isNullOrBlank()) {
fixtureDir
} else {
fixtureDir.resolve(parentDirectoryName)
}
val fixtureAgpVersion = checkNotNull(System.getProperty("fixtureAgpVersion"))
val localBuildCacheUri = fixtureDir.resolve("local-cache").apply { mkdirs() }.toURI().toString()
val enableConfigurationCache = currentAgpSupportsConfigurationCache()
return GradleProject.Builder(gradleRoot, buildScriptLanguage.dslKind).apply {
withRootProject {
gradleProperties = GradleProperties.of(
"org.gradle.parallel=true",
"org.gradle.configureondemand=true",
"org.gradle.caching=true",
"org.gradle.configuration-cache=$enableConfigurationCache",
"org.gradle.isolated-projects=$enableConfigurationCache",
)
withSettingsScript {
rootProjectName = "app-versioning-fixture"
additions = """
|buildCache {
| local {
| directory = "$localBuildCacheUri"
| }
|}
""".trimMargin()
}
}
subprojects.forEach { subproject ->
withSubproject(subproject.projectName) {
buildScript = subproject.buildScript(fixtureAgpVersion)
withFile("src/main/AndroidManifest.xml", subproject.manifestFileContent)
}
}
}.build()
}
Loading
Loading