diff --git a/README.md b/README.md index 1aac46d..6b3453a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![codecov](https://codecov.io/gh/gmazzo/gradle-buildconfig-plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/gmazzo/gradle-buildconfig-plugin) # gradle-buildconfig-plugin -A plugin for generating BuildConstants for any kind of Gradle projects: Java, Kotlin, Groovy, etc. +A plugin for generating BuildConstants for any kind of Gradle projects: Java, Kotlin, Android, Groovy, etc. Designed for KTS scripts, with *experimental* support for Kotlin's **multi-platform** plugin ## Usage in KTS @@ -207,20 +207,22 @@ myproject ``` If you add in your `build.gradle.kts`: ```kotlin -val generateBuildConfig by tasks - -task("generateResourcesConstants") { - val buildResources = buildConfig.forClass("BuildResources") - +val buildResources = buildConfig.forClass("BuildResources") +val generateResourcesConstants by tasks.regitering { + val resources = sourceSets["main"].resources.asFileTree + + inputs.files(resources) doFirst { - sourceSets["main"].resources.asFileTree.visit(Action { + resources.visit(Action { val name = path.toUpperCase().replace("\\W".toRegex(), "_") buildResources.buildConfigField("java.io.File", name, "File(\"$path\")") }) } +} - generateBuildConfig.dependsOn(this) +tasks.generateBuildConfig { + dependsOn(generateResourcesConstants) } ``` Will generate in `BuildResources.kt`: @@ -237,18 +239,22 @@ object BuildResources { ``` #### Or in Groovy: ```groovy -task("generateResourcesConstants") { - def buildResources = buildConfig.forClass("BuildResources") +def buildResources = buildConfig.forClass("BuildResources") +def generateResourcesConstants = tasks.register("generateResourcesConstants") { + def resources = sourceSets["main"].resources.asFileTree + inputs.files(resources) doFirst { - sourceSets["main"].resources.asFileTree.visit { file -> + resources.visit { file -> def name = file.path.toUpperCase().replaceAll("\\W", "_") buildResources.buildConfigField("java.io.File", name, "new File(\"$file.path\")") } } +} - generateBuildConfig.dependsOn(it) +tasks.generateBuildConfig { + dependsOn(generateResourcesConstants) } ``` Will generate in `BuildResources.java`: diff --git a/build.gradle.kts b/build.gradle.kts index 383f2ca..768da00 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ plugins { base alias(libs.plugins.kotlin) apply false + alias(libs.plugins.android) apply false `jacoco-report-aggregation` } diff --git a/demo-project/android/build.gradle.kts b/demo-project/android/build.gradle.kts new file mode 100644 index 0000000..77558aa --- /dev/null +++ b/demo-project/android/build.gradle.kts @@ -0,0 +1,41 @@ +import com.github.gmazzo.gradle.plugins.BuildConfigTask + +plugins { + alias(libs.plugins.android) + kotlin("android") + id("com.github.gmazzo.buildconfig") +} + +java.toolchain.languageVersion.set(JavaLanguageVersion.of(11)) + +android { + namespace = "com.github.gmazzo.buildconfig.demos.android" + compileSdkVersion = "android-30" + + buildFeatures.buildConfig = true + + compileOptions { + targetCompatibility(java.targetCompatibility) + sourceCompatibility(java.sourceCompatibility) + } +} + +dependencies { + testImplementation(libs.kotlin.test) +} + +buildConfig { + className("NonAndroidBuildConfig") + buildConfigField("String", "APP_NAME", "\"${project.name}\"") + buildConfigField("String", "APP_SECRET", "\"Z3JhZGxlLWphdmEtYnVpbGRjb25maWctcGx1Z2lu\"") + buildConfigField("long", "BUILD_TIME", "${System.currentTimeMillis()}L") + buildConfigField("boolean", "FEATURE_ENABLED", "${true}") + buildConfigField("kotlin.IntArray", "MAGIC_NUMBERS", "intArrayOf(1, 2, 3, 4)") +} + +// workaround of AGP issue failing to pick test sources correctly +afterEvaluate { + tasks.named("lintAnalyzeDebug") { + mustRunAfter(tasks.withType()) + } +} diff --git a/demo-project/android/src/main/AndroidManifest.xml b/demo-project/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..227314e --- /dev/null +++ b/demo-project/android/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/demo-project/android/src/test/kotlin/com/github/gmazzo/buildconfig/demos/android/BuildConfigTest.kt b/demo-project/android/src/test/kotlin/com/github/gmazzo/buildconfig/demos/android/BuildConfigTest.kt new file mode 100644 index 0000000..ed0dec6 --- /dev/null +++ b/demo-project/android/src/test/kotlin/com/github/gmazzo/buildconfig/demos/android/BuildConfigTest.kt @@ -0,0 +1,20 @@ +package com.github.gmazzo.buildconfig.demos.android + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class BuildConfigTest { + + @Test + fun testBuildConfigProperties() { + assertEquals("com.github.gmazzo.buildconfig.demos.android", BuildConfig.APPLICATION_ID) + + assertEquals("android", NonAndroidBuildConfig.APP_NAME) + assertEquals("Z3JhZGxlLWphdmEtYnVpbGRjb25maWctcGx1Z2lu", NonAndroidBuildConfig.APP_SECRET) + assertTrue(System.currentTimeMillis() >= NonAndroidBuildConfig.BUILD_TIME) + assertTrue(NonAndroidBuildConfig.FEATURE_ENABLED) + assertEquals(listOf(1, 2, 3, 4), NonAndroidBuildConfig.MAGIC_NUMBERS.toList()) + } + +} \ No newline at end of file diff --git a/demo-project/groovy/build.gradle b/demo-project/groovy/build.gradle index 04a9338..5fb2785 100644 --- a/demo-project/groovy/build.gradle +++ b/demo-project/groovy/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'java' + id 'groovy' id 'com.github.gmazzo.buildconfig' } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..1608900 --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ae908c..c16b096 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,6 +9,7 @@ kotlinpoet = { module = "com.squareup:kotlinpoet", version = "1.10.2" } mockk = { module = "io.mockk:mockk", version = "1.13.5" } [plugins] +android = { id = "com.android.application", version = "7.4.2" } gitVersioning = { id = "me.qoomon.git-versioning", version = "6.4.2" } gradle-pluginPublish = { id = "com.gradle.plugin-publish", version = "1.2.0" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/gradle/shared.settings.gradle.kts b/gradle/shared.settings.gradle.kts index 07d9dbd..4c13237 100644 --- a/gradle/shared.settings.gradle.kts +++ b/gradle/shared.settings.gradle.kts @@ -1,5 +1,13 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + } +} + dependencyResolutionManagement { repositories { mavenCentral() + google() } } diff --git a/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigPlugin.kt b/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigPlugin.kt index 054aaec..d2a67fa 100644 --- a/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigPlugin.kt +++ b/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigPlugin.kt @@ -39,14 +39,16 @@ class BuildConfigPlugin : Plugin { plugins.withId("java") { JavaHandler(project, extension).configure(sourceSets) } + plugins.withAnyId( "org.jetbrains.kotlin.android", "org.jetbrains.kotlin.jvm", "org.jetbrains.kotlin.js", "kotlin2js", - ) { + ) { KotlinHandler(project, extension).configure(sourceSets) } + plugins.withId("org.jetbrains.kotlin.multiplatform") { KotlinMultiplatformHandler(KotlinHandler(project, extension)).configure(sourceSets) } @@ -70,21 +72,24 @@ class BuildConfigPlugin : Plugin { private fun Project.configureSourceSet( sourceSet: BuildConfigSourceSetInternal, defaultSS: BuildConfigSourceSetInternal, - ) { - val prefix = when (sourceSet) { - defaultSS -> "" - else -> sourceSet.name.replaceFirstChar { it.titlecaseChar() } - } + ) { + val prefix = (if (plugins.hasPlugin("com.android.base")) "NonAndroid" else "") + + when (sourceSet) { + defaultSS -> "" + else -> sourceSet.name.replaceFirstChar { it.titlecaseChar() } + } sourceSet.className.convention("${prefix}BuildConfig") - sourceSet.packageName.convention(when(sourceSet) { + sourceSet.packageName.convention(when (sourceSet) { defaultSS -> defaultPackage.map { it.replace("[^a-zA-Z._$]".toRegex(), "_") } else -> defaultSS.packageName }) - sourceSet.generator.convention(when(sourceSet) { - defaultSS -> provider(::BuildConfigJavaGenerator) - else -> defaultSS.generator - }) + sourceSet.generator.convention( + when (sourceSet) { + defaultSS -> provider(::BuildConfigJavaGenerator) + else -> defaultSS.generator + } + ) sourceSet.generateTask = tasks.register("generate${prefix}BuildConfig") { group = "BuildConfig" description = "Generates the build constants class for '${sourceSet.name}' source" diff --git a/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigTask.kt b/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigTask.kt index 0db0bda..190c56f 100644 --- a/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigTask.kt +++ b/plugin/src/main/kotlin/com/github/gmazzo/gradle/plugins/BuildConfigTask.kt @@ -32,7 +32,7 @@ abstract class BuildConfigTask : DefaultTask() { val generator = generator.get() - specs.get().forEach { + specs.get().asSequence().filter { it.buildConfigFields.isNotEmpty() }.forEach { val rawClassName = it.className.get() val (packageName, className) = when (val rawPackage = it.packageName.orNull) { null -> when (val i = rawClassName.lastIndexOf('.')) { diff --git a/settings.gradle.kts b/settings.gradle.kts index e1139a2..5d8e06c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ rootProject.name = "gradle-buildconfig-plugin" includeBuild("plugin") include( + "demo-project:android", "demo-project:generic", "demo-project:groovy", "demo-project:kts",