buildSrc: remove
This commit is contained in:
parent
a80020477f
commit
81e9926b72
13 changed files with 7 additions and 708 deletions
1
buildSrc/.gitignore
vendored
1
buildSrc/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/build
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
plugins { `kotlin-dsl` }
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
register("aps") {
|
||||
id = "aps-plugin"
|
||||
implementationClass = "PasswordStorePlugin"
|
||||
}
|
||||
register("crowdin") {
|
||||
id = "crowdin-plugin"
|
||||
implementationClass = "CrowdinDownloadPlugin"
|
||||
}
|
||||
register("versioning") {
|
||||
id = "versioning-plugin"
|
||||
implementationClass = "VersioningPlugin"
|
||||
}
|
||||
register("psl") {
|
||||
id = "psl-plugin"
|
||||
implementationClass = "PublicSuffixListPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.android.tools.build:gradle:7.0.3")
|
||||
implementation("com.google.dagger:hilt-android-gradle-plugin:2.40.3")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.9.0")
|
||||
implementation("com.vanniktech:gradle-maven-publish-plugin:0.18.0")
|
||||
implementation("com.vdurmont:semver4j:3.1.0")
|
||||
implementation("de.undercouch:gradle-download-task:4.1.2")
|
||||
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.6.0")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0")
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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" } }
|
|
@ -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") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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()
|
||||
)
|
|
@ -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)
|
||||
}
|
|
@ -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"
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,13 @@ pluginManagement {
|
|||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
if (requested.id.id == "dagger.hilt.android.plugin") {
|
||||
useModule("com.google.dagger:hilt-android-gradle-plugin:2.40.3")
|
||||
}
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("com.vanniktech.maven.publish") version "0.18.0" apply false
|
||||
id("org.jetbrains.dokka") version "1.6.0" apply false
|
||||
|
|
Loading…
Reference in a new issue