diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aea1857..0ce5dbf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Build Example on: [ push, workflow_dispatch ] jobs: - build: + build_app: runs-on: ubuntu-latest steps: # Checkout repository @@ -20,3 +20,21 @@ jobs: # Run the Gradle Build task - name: Build Example App run: ./gradlew clean :appexample:assemble + + build_lib: + runs-on: ubuntu-latest + steps: + # Checkout repository + - name: Checkout + uses: actions/checkout@v4.1.1 + + # Setup JDK environment + - name: Set up JDK + uses: actions/setup-java@v4.3.0 + with: + distribution: 'zulu' + java-version: '17' + + # Run the Gradle Build task + - name: Build Example Lib + run: ./gradlew clean :libexample:assemble \ No newline at end of file diff --git a/appexample/build.gradle.kts b/appexample/build.gradle.kts index 484871b..9bba94a 100644 --- a/appexample/build.gradle.kts +++ b/appexample/build.gradle.kts @@ -2,8 +2,8 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - alias(libs.plugins.androidApplication) - alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) id("ch.ubique.gradle.preset") } diff --git a/build.gradle.kts b/build.gradle.kts index 366506a..266f426 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,8 @@ plugins { alias(libs.plugins.kotlin) apply false - alias(libs.plugins.androidApplication) apply false - alias(libs.plugins.kotlinAndroid) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false } tasks.register("clean", Delete::class.java) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4cced69..2b54861 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,9 +9,10 @@ androidx-lifecycle = "2.8.6" [plugins] kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin"} +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } pluginPublish = { id = "com.gradle.plugin-publish", version.ref = "pluginPublish"} -androidApplication = { id = "com.android.application", version.ref = "agp" } -kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +android-application = { id = "com.android.application", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } vanniktech = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech" } [libraries] diff --git a/libexample/.gitignore b/libexample/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/libexample/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/libexample/build.gradle.kts b/libexample/build.gradle.kts new file mode 100644 index 0000000..b4eadcf --- /dev/null +++ b/libexample/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + id("ch.ubique.gradle.preset") +} + +android { + namespace = "ch.ubique.preset.example" + compileSdk = 34 + + defaultConfig { + minSdk = 26 + targetSdk = 34 + + testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} + +dependencies { + implementation(libs.androidx.appcompat) + implementation(libs.androidx.lifecycle.viewmodelKtx) +} diff --git a/libexample/src/main/kotlin/ch/ubique/preset/example/ExampleLibrary.kt b/libexample/src/main/kotlin/ch/ubique/preset/example/ExampleLibrary.kt new file mode 100644 index 0000000..c98991f --- /dev/null +++ b/libexample/src/main/kotlin/ch/ubique/preset/example/ExampleLibrary.kt @@ -0,0 +1,5 @@ +package ch.ubique.preset.example + +object ExampleLibrary { + +} \ No newline at end of file diff --git a/preset/plugin/src/main/kotlin/ch/ubique/gradle/preset/PresetPlugin.kt b/preset/plugin/src/main/kotlin/ch/ubique/gradle/preset/PresetPlugin.kt index d4fcd03..95e0575 100644 --- a/preset/plugin/src/main/kotlin/ch/ubique/gradle/preset/PresetPlugin.kt +++ b/preset/plugin/src/main/kotlin/ch/ubique/gradle/preset/PresetPlugin.kt @@ -1,8 +1,10 @@ package ch.ubique.gradle.preset import ch.ubique.gradle.preset.config.PresetPluginConfig +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.LibraryExtension import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.gradle.AppExtension +import com.android.build.gradle.BaseExtension import com.android.build.gradle.ProguardFiles.getDefaultProguardFile import org.gradle.api.GradleException import org.gradle.api.JavaVersion @@ -19,39 +21,12 @@ abstract class PresetPlugin : Plugin { val androidExtension = getAndroidExtension(project) val androidComponentExtension = getAndroidComponentsExtension(project) + // Apply presets specific to applications + (androidExtension as? ApplicationExtension)?.applyAppPreset(project) + // Enable BuildConfig androidExtension.buildFeatures.buildConfig = true - // Default dimension - androidExtension.flavorDimensions("default") - - // Add flavor boolean fields to BuildConfig - androidExtension.productFlavors.configureEach { flavor -> - val sanitizedFlavorName = flavor.name.replace("[^a-zA-Z0-9_]", "_") - - // default flavor dimension - flavor.dimension = "default" - - // default application id suffix - flavor.applicationIdSuffix = when (flavor.name) { - "prod", "production" -> null - else -> ".$sanitizedFlavorName" - } - - // flavor BuildConfig flag - val flavorFieldName = "IS_FLAVOR_${sanitizedFlavorName.uppercase()}" - // true for this flavor ... - flavor.buildConfigField("boolean", flavorFieldName, "true") - // ... false for all others - androidExtension.defaultConfig.buildConfigField("boolean", flavorFieldName, "false") - } - - // Release build config - androidExtension.buildTypes.maybeCreate("release").apply { - isMinifyEnabled = true - proguardFiles(getDefaultProguardFile("proguard-android.txt", project.layout.buildDirectory), "proguard-rules.pro") - } - // R8 full mode check if (project.findProperty("android.enableR8.fullMode") != "false" && project.findProperty("android.enableR8.fullModeAllowed") != "true") { throw IllegalArgumentException("R8 full mode is enabled. Disable it with android.enableR8.fullMode=false or allow it by setting android.enableR8.fullModeAllowed=true") @@ -81,9 +56,10 @@ abstract class PresetPlugin : Plugin { androidExtension.lintOptions.isAbortOnError = false } - private fun getAndroidExtension(project: Project): AppExtension { - val ext = project.extensions.findByType(AppExtension::class.java) - ?: throw GradleException("Android gradle plugin extension has not been applied before") + private fun getAndroidExtension(project: Project): BaseExtension { + val ext = project.extensions.findByType(BaseExtension::class.java) + ?.takeIf { it is ApplicationExtension || it is LibraryExtension } + ?: throw GradleException("Android gradle plugin (application or library) extension has not been applied before") return ext } @@ -93,4 +69,36 @@ abstract class PresetPlugin : Plugin { return ext } + private fun ApplicationExtension.applyAppPreset(project: Project) { + // Default dimension + flavorDimensions += "default" + + // Add flavor boolean fields to BuildConfig + productFlavors.configureEach { flavor -> + val sanitizedFlavorName = flavor.name.replace("[^a-zA-Z0-9_]", "_") + + // default flavor dimension + flavor.dimension = "default" + + // default application id suffix + flavor.applicationIdSuffix = when (flavor.name) { + "prod", "production" -> null + else -> ".$sanitizedFlavorName" + } + + // flavor BuildConfig flag + val flavorFieldName = "IS_FLAVOR_${sanitizedFlavorName.uppercase()}" + // true for this flavor ... + flavor.buildConfigField("boolean", flavorFieldName, "true") + // ... false for all others + defaultConfig.buildConfigField("boolean", flavorFieldName, "false") + } + + // Release build config + buildTypes.maybeCreate("release").apply { + isMinifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android.txt", project.layout.buildDirectory), "proguard-rules.pro") + } + } + } diff --git a/settings.gradle.kts b/settings.gradle.kts index 6e6f1f0..f358ec0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,4 +19,5 @@ dependencyResolutionManagement { rootProject.name = "gradle-plugin-preset-android" include("appexample") +include("libexample") includeBuild("preset")