Repo created
This commit is contained in:
parent
a629de6271
commit
3cef7c5092
2161 changed files with 246605 additions and 2 deletions
72
build-plugin/README.md
Normal file
72
build-plugin/README.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Build plugins
|
||||
|
||||
The `build-plugin` folder defines Gradle build plugins, used as single source of truth for the project configuration.
|
||||
This helps to avoid duplicated build script setups and provides a central location for all common build logic.
|
||||
|
||||
## Background
|
||||
|
||||
We use Gradle's
|
||||
[sharing build logic in a multi-repo setup](https://docs.gradle.org/current/samples/sample_publishing_convention_plugins.html)
|
||||
to create common configuration. It allows usage of `xyz.gradle.kts` files, that are then automatically converted to
|
||||
Gradle Plugins.
|
||||
|
||||
The `build-plugin` is used as included build in the root `settings.gradle.kts` and provides all
|
||||
included `xyz.gradle.kts` as plugins under their `xyz` name to the whole project.
|
||||
|
||||
The plugins should try to accomplish single responsibility and leave one-off configuration to the module's `build.gradle.kts`.
|
||||
|
||||
## Convention plugins
|
||||
|
||||
- `thunderbird.app.android` - Configures common options for Android apps
|
||||
- `thunderbird.app.android.compose` - Configures common options for Jetpack Compose, based
|
||||
on `thunderbird.app.android`
|
||||
- `thunderbird.library.android` - Configures common options for Android libraries
|
||||
- `thunderbird.library.android.compose` - Configures common options for Jetpack Compose, based
|
||||
on `thunderbird.library.android`
|
||||
- `thunderbird.library.jvm` - Configures common options for JVM libraries
|
||||
|
||||
## Supportive plugins
|
||||
|
||||
- `thunderbird.dependency.check` - [Gradle Versions: Gradle plugin to discover dependency updates](https://github.com/ben-manes/gradle-versions-plugin)
|
||||
- Use `./gradlew dependencyUpdates` to generate a dependency update report
|
||||
- `thunderbird.quality.detekt` - [Detekt - Static code analysis for Kotlin ](https://detekt.dev/)
|
||||
- Use `./gradlew detekt` to check for any issue and `./gradlew detektBaseline` in case you can't fix the reported
|
||||
issue.
|
||||
- `thunderbird.quality.spotless` - [Spotless - Code formatter](https://github.com/diffplug/spotless)
|
||||
with [Ktlint - Kotlin linter and formatter](https://pinterest.github.io/ktlint/)
|
||||
- Use `./gradlew spotlessCheck` to check for any issue and `./gradlew spotlessApply` to format your code
|
||||
|
||||
## Add new build plugin
|
||||
|
||||
Create a `thunderbird.xyz.gradle.kts` file, while `xyz` describes the new plugin.
|
||||
|
||||
If you need to access dependencies that are not yet defined in `build-plugin/build.gradle.kts` you have to:
|
||||
|
||||
1. Add the dependency to the version catalog `gradle/libs.versions.toml`
|
||||
2. Then add it to `build-plugin/build.gradle.kts`.
|
||||
1. In case of a plugin dependency use `implementation(plugin(libs.plugins.YOUR_PLUGIN_DEPENDENCY))`.
|
||||
1. Otherwise `implementation(libs.YOUR_DEPENDENCY))`.
|
||||
|
||||
When done, add the plugin to `build-plugin/src/main/kotlin/ThunderbirdPlugins.kt`
|
||||
|
||||
Then apply the plugin to any subproject it should be used with:
|
||||
|
||||
```
|
||||
plugins {
|
||||
id(ThunderbirdPlugins.xyz)
|
||||
}
|
||||
```
|
||||
|
||||
If the plugin is meant for the root `build.gradle.kts`, you can't use `ThunderbirdPlugins`, as it's not available to
|
||||
the `plugins` block. Instead use:
|
||||
|
||||
```
|
||||
plugins {
|
||||
id("thunderbird.xyz")
|
||||
}
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- [Herding Elephants | Square Corner Blog](https://developer.squareup.com/blog/herding-elephants/)
|
||||
- [Idiomatic Gradle: How do I idiomatically structure a large build with Gradle](https://github.com/jjohannes/idiomatic-gradle#idiomatic-build-logic-structure)
|
||||
21
build-plugin/build.gradle.kts
Normal file
21
build-plugin/build.gradle.kts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||
|
||||
implementation(plugin(libs.plugins.kotlin.jvm))
|
||||
implementation(plugin(libs.plugins.kotlin.android))
|
||||
|
||||
implementation(plugin(libs.plugins.android.application))
|
||||
implementation(plugin(libs.plugins.android.library))
|
||||
|
||||
implementation(plugin(libs.plugins.spotless))
|
||||
implementation(plugin(libs.plugins.detekt))
|
||||
implementation(plugin(libs.plugins.dependency.check))
|
||||
}
|
||||
|
||||
fun plugin(provider: Provider<PluginDependency>) = with(provider.get()) {
|
||||
"$pluginId:$pluginId.gradle.plugin:$version"
|
||||
}
|
||||
21
build-plugin/settings.gradle.kts
Normal file
21
build-plugin/settings.gradle.kts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
versionCatalogs.create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "build-plugin"
|
||||
69
build-plugin/src/main/kotlin/AndroidExtension.kt
Normal file
69
build-plugin/src/main/kotlin/AndroidExtension.kt
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import com.android.build.api.dsl.CommonExtension
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||
|
||||
internal fun CommonExtension<*, *, *, *>.configureSharedConfig() {
|
||||
compileSdk = ThunderbirdProjectConfig.androidSdkCompile
|
||||
|
||||
defaultConfig {
|
||||
compileSdk = ThunderbirdProjectConfig.androidSdkCompile
|
||||
minSdk = ThunderbirdProjectConfig.androidSdkMin
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = ThunderbirdProjectConfig.javaVersion
|
||||
targetCompatibility = ThunderbirdProjectConfig.javaVersion
|
||||
}
|
||||
|
||||
lint {
|
||||
abortOnError = false
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
isIncludeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun CommonExtension<*, *, *, *>.configureSharedComposeConfig(
|
||||
libs: LibrariesForLibs,
|
||||
) {
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = libs.versions.androidxComposeCompiler.get()
|
||||
}
|
||||
|
||||
lint {
|
||||
warningsAsErrors = true
|
||||
abortOnError = true
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun DependencyHandler.configureSharedComposeDependencies(
|
||||
libs: LibrariesForLibs,
|
||||
) {
|
||||
val composeBom = platform(libs.androidx.compose.bom)
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
|
||||
implementation(libs.bundles.shared.jvm.android.compose)
|
||||
|
||||
debugImplementation(libs.bundles.shared.jvm.android.compose.debug)
|
||||
|
||||
testImplementation(libs.bundles.shared.jvm.test.compose)
|
||||
|
||||
androidTestImplementation(libs.bundles.shared.jvm.androidtest.compose)
|
||||
}
|
||||
14
build-plugin/src/main/kotlin/DependencyHandlerExtension.kt
Normal file
14
build-plugin/src/main/kotlin/DependencyHandlerExtension.kt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||
|
||||
internal fun DependencyHandler.implementation(dependencyNotation: Any): Dependency? =
|
||||
add("implementation", dependencyNotation)
|
||||
|
||||
internal fun DependencyHandler.debugImplementation(dependencyNotation: Any): Dependency? =
|
||||
add("debugImplementation", dependencyNotation)
|
||||
|
||||
internal fun DependencyHandler.testImplementation(dependencyNotation: Any): Dependency? =
|
||||
add("testImplementation", dependencyNotation)
|
||||
|
||||
internal fun DependencyHandler.androidTestImplementation(dependencyNotation: Any): Dependency? =
|
||||
add("androidTestImplementation", dependencyNotation)
|
||||
10
build-plugin/src/main/kotlin/ProjectExtension.kt
Normal file
10
build-plugin/src/main/kotlin/ProjectExtension.kt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.DependencyHandlerScope
|
||||
import org.gradle.kotlin.dsl.getByName
|
||||
|
||||
internal val Project.libs: LibrariesForLibs
|
||||
get() = extensions.getByName<LibrariesForLibs>("libs")
|
||||
|
||||
internal fun Project.dependencies(configuration: DependencyHandlerScope.() -> Unit) =
|
||||
DependencyHandlerScope.of(dependencies).configuration()
|
||||
12
build-plugin/src/main/kotlin/ThunderbirdPlugins.kt
Normal file
12
build-plugin/src/main/kotlin/ThunderbirdPlugins.kt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
object ThunderbirdPlugins {
|
||||
|
||||
object App {
|
||||
const val android = "thunderbird.app.android"
|
||||
const val androidCompose = "thunderbird.app.android.compose"
|
||||
}
|
||||
object Library {
|
||||
const val jvm = "thunderbird.library.jvm"
|
||||
const val android = "thunderbird.library.android"
|
||||
const val androidCompose = "thunderbird.library.android.compose"
|
||||
}
|
||||
}
|
||||
10
build-plugin/src/main/kotlin/ThunderbirdProjectConfig.kt
Normal file
10
build-plugin/src/main/kotlin/ThunderbirdProjectConfig.kt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import org.gradle.api.JavaVersion
|
||||
|
||||
object ThunderbirdProjectConfig {
|
||||
|
||||
val javaVersion = JavaVersion.VERSION_11
|
||||
|
||||
const val androidSdkMin = 21
|
||||
const val androidSdkTarget = 31
|
||||
const val androidSdkCompile = 33
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import com.diffplug.gradle.spotless.SpotlessExtension
|
||||
|
||||
@Suppress("DSL_SCOPE_VIOLATION")
|
||||
plugins {
|
||||
id("com.diffplug.spotless")
|
||||
}
|
||||
|
||||
configure<SpotlessExtension> {
|
||||
kotlin {
|
||||
ktlint(libs.versions.ktlint.get())
|
||||
target("**/*.kt")
|
||||
targetExclude("**/build/", "**/resources/", "plugins/openpgp-api-lib/")
|
||||
}
|
||||
kotlinGradle {
|
||||
ktlint(libs.versions.ktlint.get())
|
||||
target("**/*.gradle.kts")
|
||||
targetExclude("**/build/")
|
||||
}
|
||||
format("markdown") {
|
||||
prettier()
|
||||
target("**/*.md")
|
||||
targetExclude("plugins/openpgp-api-lib/")
|
||||
}
|
||||
format("misc") {
|
||||
target("**/*.gradle", "**/.gitignore")
|
||||
trimTrailingWhitespace()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
plugins {
|
||||
id("thunderbird.app.android")
|
||||
}
|
||||
|
||||
android {
|
||||
configureSharedComposeConfig(libs)
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
configureSharedComposeDependencies(libs)
|
||||
|
||||
implementation(libs.androidx.compose.activity)
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
}
|
||||
|
||||
android {
|
||||
configureSharedConfig()
|
||||
|
||||
defaultConfig {
|
||||
targetSdk = ThunderbirdProjectConfig.androidSdkTarget
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = ThunderbirdProjectConfig.javaVersion.toString()
|
||||
}
|
||||
|
||||
lint {
|
||||
lintConfig = file("${rootProject.projectDir}/config/lint/lint.xml")
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
includeInBundle = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring(libs.desugar)
|
||||
|
||||
testImplementation(libs.bundles.shared.jvm.test)
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
}
|
||||
|
||||
android {
|
||||
configureSharedConfig()
|
||||
|
||||
defaultConfig {
|
||||
targetSdk = ThunderbirdProjectConfig.androidSdkTarget
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = ThunderbirdProjectConfig.javaVersion.toString()
|
||||
}
|
||||
|
||||
lint {
|
||||
checkDependencies = true
|
||||
lintConfig = file("${rootProject.projectDir}/config/lint/lint.xml")
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
includeInBundle = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring(libs.desugar)
|
||||
|
||||
testImplementation(libs.bundles.shared.jvm.test)
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
|
||||
|
||||
plugins {
|
||||
id("com.github.ben-manes.versions")
|
||||
}
|
||||
|
||||
tasks.withType<DependencyUpdatesTask> {
|
||||
rejectVersionIf {
|
||||
isNonStable(candidate.version) && !isNonStable(currentVersion)
|
||||
}
|
||||
}
|
||||
|
||||
fun isNonStable(version: String): Boolean {
|
||||
val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.toUpperCase().contains(it) }
|
||||
val regex = "^[\\d,.v-]+(-r)?$".toRegex()
|
||||
val isStable = stableKeyword || regex.matches(version)
|
||||
return isStable.not()
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
plugins {
|
||||
id("thunderbird.library.android")
|
||||
}
|
||||
|
||||
android {
|
||||
configureSharedComposeConfig(libs)
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
beforeVariants(selector().withBuildType("release")) { variantBuilder ->
|
||||
variantBuilder.enableUnitTest = false
|
||||
variantBuilder.enableAndroidTest = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
configureSharedComposeDependencies(libs)
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
plugins {
|
||||
id("com.android.library")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
}
|
||||
|
||||
android {
|
||||
configureSharedConfig()
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = false
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = ThunderbirdProjectConfig.javaVersion.toString()
|
||||
}
|
||||
|
||||
lint {
|
||||
lintConfig = file("${rootProject.projectDir}/config/lint/lint.xml")
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
isIncludeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.bundles.shared.jvm.main)
|
||||
implementation(libs.bundles.shared.jvm.android)
|
||||
testImplementation(libs.bundles.shared.jvm.test)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
plugins {
|
||||
`java-library`
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = ThunderbirdProjectConfig.javaVersion
|
||||
targetCompatibility = ThunderbirdProjectConfig.javaVersion
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.bundles.shared.jvm.main)
|
||||
testImplementation(libs.bundles.shared.jvm.test)
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import io.gitlab.arturbosch.detekt.Detekt
|
||||
import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
|
||||
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
|
||||
|
||||
plugins {
|
||||
id("io.gitlab.arturbosch.detekt")
|
||||
}
|
||||
|
||||
configure<DetektExtension> {
|
||||
source = project.files(
|
||||
project.file(project.rootDir),
|
||||
)
|
||||
|
||||
config = project.rootProject.files("config/detekt/detekt.yml")
|
||||
baseline = project.rootProject.file("config/detekt/baseline.xml")
|
||||
}
|
||||
|
||||
tasks.withType<Detekt>().configureEach {
|
||||
jvmTarget = ThunderbirdProjectConfig.javaVersion.toString()
|
||||
|
||||
exclude(
|
||||
"**/.gradle/**",
|
||||
"**/.idea/**",
|
||||
"**/build/**",
|
||||
".github/**",
|
||||
"gradle/**",
|
||||
)
|
||||
|
||||
reports {
|
||||
html.required.set(true)
|
||||
sarif.required.set(true)
|
||||
xml.required.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<DetektCreateBaselineTask>().configureEach {
|
||||
exclude(
|
||||
"**/.gradle/**",
|
||||
"**/.idea/**",
|
||||
"**/build/**",
|
||||
".github/**",
|
||||
"gradle/**",
|
||||
)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
detektPlugins(libs.detekt.plugin.compose)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import com.diffplug.gradle.spotless.SpotlessExtension
|
||||
|
||||
plugins {
|
||||
id("com.diffplug.spotless")
|
||||
}
|
||||
|
||||
configure<SpotlessExtension> {
|
||||
kotlin {
|
||||
ktlint(libs.versions.ktlint.get())
|
||||
target("**/*.kt")
|
||||
targetExclude("**/build/", "**/resources/", "plugins/openpgp-api-lib/")
|
||||
}
|
||||
kotlinGradle {
|
||||
ktlint(libs.versions.ktlint.get())
|
||||
target("**/*.gradle.kts")
|
||||
targetExclude("**/build/")
|
||||
}
|
||||
format("markdown") {
|
||||
prettier()
|
||||
target("**/*.md")
|
||||
targetExclude("plugins/openpgp-api-lib/")
|
||||
}
|
||||
format("misc") {
|
||||
target("**/*.gradle", "**/.gitignore")
|
||||
trimTrailingWhitespace()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue