aboutsummaryrefslogtreecommitdiff
path: root/buildSrc/src/main/java
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-11-29 02:38:06 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2021-12-03 12:59:58 +0530
commit81e9926b723e6f1214bae43cf0d177e81b4e821e (patch)
tree4c54972fe1688ff8853f70537fe6c98fac1d545d /buildSrc/src/main/java
parenta80020477f4717f04d39593dd0c558182ec369a4 (diff)
buildSrc: remove
Diffstat (limited to 'buildSrc/src/main/java')
-rw-r--r--buildSrc/src/main/java/BaseProjectConfig.kt97
-rw-r--r--buildSrc/src/main/java/CrowdinDownloadPlugin.kt121
-rw-r--r--buildSrc/src/main/java/CrowdinExtension.kt17
-rw-r--r--buildSrc/src/main/java/KaptConfigs.kt34
-rw-r--r--buildSrc/src/main/java/PasswordStorePlugin.kt73
-rw-r--r--buildSrc/src/main/java/ProductFlavors.kt13
-rw-r--r--buildSrc/src/main/java/PublicSuffixListPlugin.kt120
-rw-r--r--buildSrc/src/main/java/SigningConfig.kt40
-rw-r--r--buildSrc/src/main/java/SlimTests.kt42
-rw-r--r--buildSrc/src/main/java/VersioningPlugin.kt106
10 files changed, 0 insertions, 663 deletions
diff --git a/buildSrc/src/main/java/BaseProjectConfig.kt b/buildSrc/src/main/java/BaseProjectConfig.kt
deleted file mode 100644
index f11b9dec..00000000
--- a/buildSrc/src/main/java/BaseProjectConfig.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import com.android.build.gradle.TestedExtension
-import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
-import org.gradle.api.JavaVersion
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.register
-import org.gradle.language.nativeplatform.internal.BuildType
-
-/** Checks if we're building a snapshot */
-@Suppress("UnstableApiUsage")
-fun Project.isSnapshot(): Boolean {
- with(project.providers) {
- val workflow = environmentVariable("GITHUB_WORKFLOW").forUseAtConfigurationTime()
- val snapshot = environmentVariable("SNAPSHOT").forUseAtConfigurationTime()
- return workflow.isPresent && snapshot.isPresent
- }
-}
-
-/** Apply configurations for app module */
-@Suppress("UnstableApiUsage")
-internal fun BaseAppModuleExtension.configureAndroidApplicationOptions(project: Project) {
- val minifySwitch =
- project.providers.environmentVariable("DISABLE_MINIFY").forUseAtConfigurationTime()
-
- adbOptions.installOptions("--user 0")
-
- buildFeatures {
- viewBinding = true
- buildConfig = true
- }
-
- flavorDimensions.add(FlavorDimensions.FREE)
- productFlavors {
- register(ProductFlavors.FREE) {}
- register(ProductFlavors.NON_FREE) {}
- }
-
- buildTypes {
- named(BuildType.RELEASE.name) {
- isMinifyEnabled = !minifySwitch.isPresent
- setProguardFiles(
- listOf(
- "proguard-android-optimize.txt",
- "proguard-rules.pro",
- "proguard-rules-missing-classes.pro",
- )
- )
- buildConfigField("boolean", "ENABLE_DEBUG_FEATURES", "${project.isSnapshot()}")
- }
- named(BuildType.DEBUG.name) {
- applicationIdSuffix = ".debug"
- versionNameSuffix = "-debug"
- isMinifyEnabled = false
- buildConfigField("boolean", "ENABLE_DEBUG_FEATURES", "true")
- }
- }
-}
-
-/** Apply baseline configurations for all Android projects (Application and Library). */
-@Suppress("UnstableApiUsage")
-internal fun TestedExtension.configureCommonAndroidOptions() {
- setCompileSdkVersion(31)
-
- defaultConfig {
- minSdk = 23
- targetSdk = 29
- }
-
- sourceSets {
- named("main") { java.srcDirs("src/main/kotlin") }
- named("test") { java.srcDirs("src/test/kotlin") }
- named("androidTest") { java.srcDirs("src/androidTest/kotlin") }
- }
-
- packagingOptions {
- resources.excludes.add("**/*.version")
- resources.excludes.add("**/*.txt")
- resources.excludes.add("**/*.kotlin_module")
- resources.excludes.add("**/plugin.properties")
- resources.excludes.add("**/META-INF/AL2.0")
- resources.excludes.add("**/META-INF/LGPL2.1")
- }
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
-
- testOptions {
- animationsDisabled = true
- unitTests.isReturnDefaultValues = true
- }
-}
diff --git a/buildSrc/src/main/java/CrowdinDownloadPlugin.kt b/buildSrc/src/main/java/CrowdinDownloadPlugin.kt
deleted file mode 100644
index 4be93885..00000000
--- a/buildSrc/src/main/java/CrowdinDownloadPlugin.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import de.undercouch.gradle.tasks.download.Download
-import java.io.File
-import javax.xml.parsers.DocumentBuilderFactory
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import org.gradle.api.GradleException
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.tasks.Copy
-import org.gradle.kotlin.dsl.create
-import org.gradle.kotlin.dsl.register
-import org.w3c.dom.Document
-
-private const val EXCEPTION_MESSAGE =
- """Applying `crowdin-plugin` requires a projectName to be configured via the "crowdin" extension."""
-private const val CROWDIN_BUILD_API_URL =
- "https://api.crowdin.com/api/project/%s/export?login=%s&account-key=%s"
-
-class CrowdinDownloadPlugin : Plugin<Project> {
-
- override fun apply(project: Project) {
- with(project) {
- val extension = extensions.create<CrowdinExtension>("crowdin")
- afterEvaluate {
- val projectName = extension.projectName
- if (projectName.isEmpty()) {
- throw GradleException(EXCEPTION_MESSAGE)
- }
- tasks.register("buildOnApi") {
- doLast {
- val login = providers.environmentVariable("CROWDIN_LOGIN").forUseAtConfigurationTime()
- val key =
- providers.environmentVariable("CROWDIN_PROJECT_KEY").forUseAtConfigurationTime()
- if (!login.isPresent) {
- throw GradleException("CROWDIN_LOGIN environment variable must be set")
- }
- if (!key.isPresent) {
- throw GradleException("CROWDIN_PROJECT_KEY environment variable must be set")
- }
- val client = OkHttpClient()
- val url = CROWDIN_BUILD_API_URL.format(projectName, login.get(), key.get())
- val request = Request.Builder().url(url).get().build()
- client.newCall(request).execute()
- }
- }
- tasks.register<Download>("downloadCrowdin") {
- dependsOn("buildOnApi")
- src("https://crowdin.com/backend/download/project/$projectName.zip")
- dest("$buildDir/translations.zip")
- overwrite(true)
- }
- tasks.register<Copy>("extractCrowdin") {
- dependsOn("downloadCrowdin")
- doFirst { File(buildDir, "translations").deleteRecursively() }
- from(zipTree("$buildDir/translations.zip"))
- into("$buildDir/translations")
- }
- tasks.register<Copy>("extractStrings") {
- dependsOn("extractCrowdin")
- from("$buildDir/translations/")
- into("${projectDir}/src/")
- setFinalizedBy(setOf("removeIncompleteStrings"))
- }
- tasks.register("removeIncompleteStrings") {
- doLast {
- val sourceSets = arrayOf("main", "nonFree")
- for (sourceSet in sourceSets) {
- val stringFiles =
- File("${projectDir}/src/$sourceSet").walkTopDown().filter {
- it.name == "strings.xml"
- }
- val sourceFile =
- stringFiles.firstOrNull { it.path.endsWith("values/strings.xml") }
- ?: throw GradleException("No root strings.xml found in '$sourceSet' sourceSet")
- val sourceDoc = parseDocument(sourceFile)
- val baselineStringCount = countStrings(sourceDoc)
- val threshold = 0.80 * baselineStringCount
- stringFiles.forEach { file ->
- if (file != sourceFile) {
- val doc = parseDocument(file)
- val stringCount = countStrings(doc)
- if (stringCount < threshold) {
- file.delete()
- }
- }
- }
- }
- }
- }
- tasks.register("crowdin") {
- dependsOn("extractStrings")
- if (!extension.skipCleanup) {
- doLast {
- File("$buildDir/translations").deleteRecursively()
- File("$buildDir/nonFree-translations").deleteRecursively()
- File("$buildDir/translations.zip").delete()
- }
- }
- }
- }
- }
- }
-
- private fun parseDocument(file: File): Document {
- val dbFactory = DocumentBuilderFactory.newInstance()
- val documentBuilder = dbFactory.newDocumentBuilder()
- return documentBuilder.parse(file)
- }
-
- private fun countStrings(document: Document): Int {
- // Normalization is beneficial for us
- // https://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
- document.documentElement.normalize()
- return document.getElementsByTagName("string").length
- }
-}
diff --git a/buildSrc/src/main/java/CrowdinExtension.kt b/buildSrc/src/main/java/CrowdinExtension.kt
deleted file mode 100644
index e50d8e5c..00000000
--- a/buildSrc/src/main/java/CrowdinExtension.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-open class CrowdinExtension {
-
- /** Configure the project name on Crowdin */
- open var projectName = ""
-
- /**
- * Don't delete downloaded and extracted translation archives from build directory.
- *
- * Useful for debugging.
- */
- open var skipCleanup = false
-}
diff --git a/buildSrc/src/main/java/KaptConfigs.kt b/buildSrc/src/main/java/KaptConfigs.kt
deleted file mode 100644
index db1c6d5a..00000000
--- a/buildSrc/src/main/java/KaptConfigs.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.configure
-import org.jetbrains.kotlin.gradle.plugin.KaptExtension
-
-/** Apply default kapt configs to the [Project]. */
-internal fun Project.configureKapt() {
- extensions.configure<KaptExtension> {
- javacOptions {
- if (hasDaggerCompilerDependency) {
- // https://dagger.dev/dev-guide/compiler-options#fastinit-mode
- option("-Adagger.fastInit=enabled")
- // Enable the better, experimental error messages
- // https://github.com/google/dagger/commit/0d2505a727b54f47b8677f42dd4fc5c1924e37f5
- option("-Adagger.experimentalDaggerErrorMessages=enabled")
- // Share test components for when we start leveraging Hilt for tests
- // https://github.com/google/dagger/releases/tag/dagger-2.34
- option("-Adagger.hilt.shareTestComponents=true")
- // KAPT nests errors causing real issues to be suppressed in CI logs
- option("-Xmaxerrs", 500)
- // Enables per-module validation for faster error detection
- // https://github.com/google/dagger/commit/325b516ac6a53d3fc973d247b5231fafda9870a2
- option("-Adagger.moduleBindingValidation=ERROR")
- }
- }
- }
- // disable kapt tasks for unit tests
- tasks
- .matching { it.name.startsWith("kapt") && it.name.endsWith("UnitTestKotlin") }
- .configureEach { enabled = false }
-}
-
-private val Project.hasDaggerCompilerDependency: Boolean
- get() =
- configurations.any { it.dependencies.any { dependency -> dependency.name == "hilt-compiler" } }
diff --git a/buildSrc/src/main/java/PasswordStorePlugin.kt b/buildSrc/src/main/java/PasswordStorePlugin.kt
deleted file mode 100644
index 926cddbb..00000000
--- a/buildSrc/src/main/java/PasswordStorePlugin.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import com.android.build.gradle.TestedExtension
-import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
-import com.android.build.gradle.internal.plugins.AppPlugin
-import com.android.build.gradle.internal.plugins.LibraryPlugin
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.plugins.JavaLibraryPlugin
-import org.gradle.api.plugins.JavaPlugin
-import org.gradle.api.tasks.compile.JavaCompile
-import org.gradle.kotlin.dsl.configure
-import org.gradle.kotlin.dsl.getByType
-import org.gradle.kotlin.dsl.withType
-import org.gradle.plugins.signing.SigningExtension
-import org.gradle.plugins.signing.SigningPlugin
-import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
-import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
-import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-class PasswordStorePlugin : Plugin<Project> {
-
- override fun apply(project: Project) {
- project.plugins.all {
- when (this) {
- is JavaPlugin, is JavaLibraryPlugin -> {
- project.tasks.withType<JavaCompile> {
- options.compilerArgs.add("-Xlint:unchecked")
- options.isDeprecation = true
- options.isWarnings = true
- }
- }
- is LibraryPlugin -> {
- project.extensions.getByType<TestedExtension>().configureCommonAndroidOptions()
- project.configureExplicitApi()
- project.configureSlimTests()
- }
- is AppPlugin -> {
- project
- .extensions
- .getByType<BaseAppModuleExtension>()
- .configureAndroidApplicationOptions(project)
- project.extensions.getByType<BaseAppModuleExtension>().configureBuildSigning(project)
- project.extensions.getByType<TestedExtension>().configureCommonAndroidOptions()
- project.configureSlimTests()
- }
- is SigningPlugin -> {
- project.extensions.getByType<SigningExtension>().configureBuildSigning()
- }
- is KotlinPluginWrapper -> {
- project.configureExplicitApi()
- }
- is Kapt3GradleSubplugin -> {
- project.configureKapt()
- }
- }
- }
- }
-
- private fun Project.configureExplicitApi() {
- val project = this
- tasks.withType<KotlinCompile> {
- if (!name.contains("test", ignoreCase = true)) {
- project.configure<KotlinProjectExtension> { explicitApi() }
- kotlinOptions { freeCompilerArgs += listOf("-Xexplicit-api=strict") }
- }
- }
- }
-}
diff --git a/buildSrc/src/main/java/ProductFlavors.kt b/buildSrc/src/main/java/ProductFlavors.kt
deleted file mode 100644
index 5b722a37..00000000
--- a/buildSrc/src/main/java/ProductFlavors.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-object FlavorDimensions {
- const val FREE = "free"
-}
-
-object ProductFlavors {
- const val FREE = "free"
- const val NON_FREE = "nonFree"
-}
diff --git a/buildSrc/src/main/java/PublicSuffixListPlugin.kt b/buildSrc/src/main/java/PublicSuffixListPlugin.kt
deleted file mode 100644
index df50f2b4..00000000
--- a/buildSrc/src/main/java/PublicSuffixListPlugin.kt
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-import java.io.File
-import java.util.TreeSet
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okio.ByteString
-import okio.ByteString.Companion.encodeUtf8
-import okio.buffer
-import okio.sink
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-
-/**
- * Gradle plugin to update the public suffix list used by the `lib-publicsuffixlist` component.
- *
- * Base on PublicSuffixListGenerator from OkHttp:
- * https://github.com/square/okhttp/blob/master/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.java
- */
-class PublicSuffixListPlugin : Plugin<Project> {
- override fun apply(project: Project) {
- project.tasks.register("updatePSL") {
- doLast {
- val filename = project.projectDir.absolutePath + "/src/main/assets/publicsuffixes"
- updatePublicSuffixList(filename)
- }
- }
- }
-
- private fun updatePublicSuffixList(destination: String) {
- val list = fetchPublicSuffixList()
- writeListToDisk(destination, list)
- }
-
- private fun writeListToDisk(destination: String, data: PublicSuffixListData) {
- val fileSink = File(destination).sink()
-
- fileSink.buffer().use { sink ->
- sink.writeInt(data.totalRuleBytes)
-
- for (domain in data.sortedRules) {
- sink.write(domain).writeByte('\n'.toInt())
- }
-
- sink.writeInt(data.totalExceptionRuleBytes)
-
- for (domain in data.sortedExceptionRules) {
- sink.write(domain).writeByte('\n'.toInt())
- }
- }
- }
-
- private fun fetchPublicSuffixList(): PublicSuffixListData {
- val client = OkHttpClient.Builder().build()
-
- val request =
- Request.Builder().url("https://publicsuffix.org/list/public_suffix_list.dat").build()
-
- client.newCall(request).execute().use { response ->
- val source = requireNotNull(response.body).source()
-
- val data = PublicSuffixListData()
-
- while (!source.exhausted()) {
- val line = source.readUtf8LineStrict()
-
- if (line.trim { it <= ' ' }.isEmpty() || line.startsWith("//")) {
- continue
- }
-
- if (line.contains(WILDCARD_CHAR)) {
- assertWildcardRule(line)
- }
-
- var rule = line.encodeUtf8()
-
- if (rule.startsWith(EXCEPTION_RULE_MARKER)) {
- rule = rule.substring(1)
- // We use '\n' for end of value.
- data.totalExceptionRuleBytes += rule.size + 1
- data.sortedExceptionRules.add(rule)
- } else {
- data.totalRuleBytes += rule.size + 1 // We use '\n' for end of value.
- data.sortedRules.add(rule)
- }
- }
-
- return data
- }
- }
-
- @Suppress("TooGenericExceptionThrown", "ThrowsCount")
- private fun assertWildcardRule(rule: String) {
- if (rule.indexOf(WILDCARD_CHAR) != 0) {
- throw RuntimeException("Wildcard is not not in leftmost position")
- }
-
- if (rule.indexOf(WILDCARD_CHAR, 1) != -1) {
- throw RuntimeException("Rule contains multiple wildcards")
- }
-
- if (rule.length == 1) {
- throw RuntimeException("Rule wildcards the first level")
- }
- }
-
- companion object {
- private const val WILDCARD_CHAR = "*"
- private val EXCEPTION_RULE_MARKER = "!".encodeUtf8()
- }
-}
-
-data class PublicSuffixListData(
- var totalRuleBytes: Int = 0,
- var totalExceptionRuleBytes: Int = 0,
- val sortedRules: TreeSet<ByteString> = TreeSet(),
- val sortedExceptionRules: TreeSet<ByteString> = TreeSet()
-)
diff --git a/buildSrc/src/main/java/SigningConfig.kt b/buildSrc/src/main/java/SigningConfig.kt
deleted file mode 100644
index aa612b35..00000000
--- a/buildSrc/src/main/java/SigningConfig.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
-import java.util.Properties
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.provideDelegate
-import org.gradle.plugins.signing.SigningExtension
-
-private const val KEYSTORE_CONFIG_PATH = "keystore.properties"
-
-/** Configure signing for all build types. */
-@Suppress("UnstableApiUsage")
-internal fun BaseAppModuleExtension.configureBuildSigning(project: Project) {
- with(project) {
- val keystoreConfigFile = rootProject.layout.projectDirectory.file(KEYSTORE_CONFIG_PATH)
- if (!keystoreConfigFile.asFile.exists()) return
- val contents = providers.fileContents(keystoreConfigFile).asText.forUseAtConfigurationTime()
- val keystoreProperties = Properties()
- keystoreProperties.load(contents.get().byteInputStream())
- signingConfigs {
- register("release") {
- keyAlias = keystoreProperties["keyAlias"] as String
- keyPassword = keystoreProperties["keyPassword"] as String
- storeFile = rootProject.file(keystoreProperties["storeFile"] as String)
- storePassword = keystoreProperties["storePassword"] as String
- }
- }
- val signingConfig = signingConfigs.getByName("release")
- buildTypes.all { setSigningConfig(signingConfig) }
- }
-}
-
-internal fun SigningExtension.configureBuildSigning() {
- val signingKey: String? by project
- val signingPassword: String? by project
- useInMemoryPgpKeys(signingKey, signingPassword)
-}
diff --git a/buildSrc/src/main/java/SlimTests.kt b/buildSrc/src/main/java/SlimTests.kt
deleted file mode 100644
index 4057032b..00000000
--- a/buildSrc/src/main/java/SlimTests.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import com.android.build.api.variant.ApplicationAndroidComponentsExtension
-import com.android.build.api.variant.LibraryAndroidComponentsExtension
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.findByType
-import org.gradle.language.nativeplatform.internal.BuildType
-
-/**
- * When the "slimTests" project property is provided, disable the unit test tasks on `release` build
- * type and `nonFree` product flavor to avoid running the same tests repeatedly in different build
- * variants.
- *
- * Examples: `./gradlew test -PslimTests` will run unit tests for `nonFreeDebug` and `debug` build
- * variants in Android App and Library projects, and all tests in JVM projects.
- */
-internal fun Project.configureSlimTests() {
- if (providers.gradleProperty(SLIM_TESTS_PROPERTY).forUseAtConfigurationTime().isPresent) {
- // disable unit test tasks on the release build type for Android Library projects
- extensions.findByType<LibraryAndroidComponentsExtension>()?.run {
- beforeVariants(selector().withBuildType(BuildType.RELEASE.name)) {
- it.enableUnitTest = false
- it.enableAndroidTest = false
- }
- }
-
- // disable unit test tasks on the release build type and free flavor for Android Application
- // projects.
- extensions.findByType<ApplicationAndroidComponentsExtension>()?.run {
- beforeVariants(selector().withBuildType(BuildType.RELEASE.name)) { it.enableUnitTest = false }
- beforeVariants(selector().withFlavor(FlavorDimensions.FREE to ProductFlavors.NON_FREE)) {
- it.enableUnitTest = false
- it.enableAndroidTest = false
- }
- }
- }
-}
-
-private const val SLIM_TESTS_PROPERTY = "slimTests"
diff --git a/buildSrc/src/main/java/VersioningPlugin.kt b/buildSrc/src/main/java/VersioningPlugin.kt
deleted file mode 100644
index 1ebbd9b8..00000000
--- a/buildSrc/src/main/java/VersioningPlugin.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-import com.android.build.gradle.internal.plugins.AppPlugin
-import com.vdurmont.semver4j.Semver
-import java.io.OutputStream
-import java.util.Properties
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-
-private const val VERSIONING_PROP_FILE = "version.properties"
-private const val VERSIONING_PROP_VERSION_NAME = "versioning-plugin.versionName"
-private const val VERSIONING_PROP_VERSION_CODE = "versioning-plugin.versionCode"
-private const val VERSIONING_PROP_COMMENT =
- """
-This file was automatically generated by 'versioning-plugin'. DO NOT EDIT MANUALLY.
-"""
-
-/**
- * A Gradle [Plugin] that takes a [Project] with the [AppPlugin] applied and dynamically sets the
- * versionCode and versionName properties based on values read from a [VERSIONING_PROP_FILE] file in
- * the [Project.getBuildDir] directory. It also adds Gradle tasks to bump the major, minor, and
- * patch versions along with one to prepare the next snapshot.
- */
-@Suppress("UnstableApiUsage", "NAME_SHADOWING")
-class VersioningPlugin : Plugin<Project> {
-
- /** Generate the Android 'versionCode' property */
- private fun Semver.androidCode(): Int {
- return major * 1_00_00 + minor * 1_00 + patch
- }
-
- /** Write an Android-specific variant of [this] to [stream] */
- private fun Semver.writeForAndroid(stream: OutputStream) {
- val newVersionCode = androidCode()
- val props = Properties()
- props.setProperty(VERSIONING_PROP_VERSION_CODE, "$newVersionCode")
- props.setProperty(VERSIONING_PROP_VERSION_NAME, toString())
- props.store(stream, VERSIONING_PROP_COMMENT)
- }
-
- override fun apply(project: Project) {
- with(project) {
- val appPlugin =
- requireNotNull(plugins.findPlugin(AppPlugin::class.java)) {
- "Plugin 'com.android.application' must be applied to use this plugin"
- }
- val propFile = layout.projectDirectory.file(VERSIONING_PROP_FILE)
- require(propFile.asFile.exists()) {
- "A 'version.properties' file must exist in the project subdirectory to use this plugin"
- }
- val contents = providers.fileContents(propFile).asText.forUseAtConfigurationTime()
- val versionProps = Properties().also { it.load(contents.get().byteInputStream()) }
- val versionName =
- requireNotNull(versionProps.getProperty(VERSIONING_PROP_VERSION_NAME)) {
- "version.properties must contain a '$VERSIONING_PROP_VERSION_NAME' property"
- }
- val versionCode =
- requireNotNull(versionProps.getProperty(VERSIONING_PROP_VERSION_CODE).toInt()) {
- "version.properties must contain a '$VERSIONING_PROP_VERSION_CODE' property"
- }
- appPlugin.extension.defaultConfig.versionName = versionName
- appPlugin.extension.defaultConfig.versionCode = versionCode
- afterEvaluate {
- val version = Semver(versionName)
- tasks.register("clearPreRelease") {
- doLast { version.withClearedSuffix().writeForAndroid(propFile.asFile.outputStream()) }
- }
- tasks.register("bumpMajor") {
- doLast {
- version
- .withIncMajor()
- .withClearedSuffix()
- .writeForAndroid(propFile.asFile.outputStream())
- }
- }
- tasks.register("bumpMinor") {
- doLast {
- version
- .withIncMinor()
- .withClearedSuffix()
- .writeForAndroid(propFile.asFile.outputStream())
- }
- }
- tasks.register("bumpPatch") {
- doLast {
- version
- .withIncPatch()
- .withClearedSuffix()
- .writeForAndroid(propFile.asFile.outputStream())
- }
- }
- tasks.register("bumpSnapshot") {
- doLast {
- version
- .withIncMinor()
- .withSuffix("SNAPSHOT")
- .writeForAndroid(propFile.asFile.outputStream())
- }
- }
- }
- }
- }
-}