Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish merging latest round of support for declarativizing NiA #96

Merged
merged 9 commits into from
Jun 14, 2024
14 changes: 13 additions & 1 deletion unified-prototype/unified-plugin/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ ksp = "1.9.23-1.0.20"
# Find latest version at: https://developer.android.com/reference/tools/gradle-api
android = "8.3.0"
androidTools = "31.3.0"
baselineProfile = "1.2.2"
firebaseCrashlytics = "2.9.9"
firebasePerf = "1.4.2"
gms = "4.4.1"
hilt = "2.50"
room = "2.6.1"

Expand All @@ -16,6 +20,8 @@ apache-commons = "3.3.1"
dependency-guard = "0.4.3"
truth = "1.4.2"
protobuf = "0.9.4"
oss-licenses = "0.10.6"
roborazzi = "1.7.0"

[libraries]
# Kotlin Libs
Expand All @@ -28,6 +34,10 @@ kotlin-serialization-plugin = { module = "org.jetbrains.kotlin:kotlin-serializat
android-agp-application = { module = "com.android.application:com.android.application.gradle.plugin", version.ref = "android" }
android-kotlin-android = { module = "org.jetbrains.kotlin.android:org.jetbrains.kotlin.android.gradle.plugin", version.ref = "kotlin" }
android-tools-common = { module = "com.android.tools:common", version.ref = "androidTools" }
baseline-profile-plugin = { module = "androidx.baselineprofile:androidx.baselineprofile.gradle.plugin", version.ref = "baselineProfile"}
firebase-perf-plugin = { module = "com.google.firebase:perf-plugin", version.ref = "firebasePerf" }
firebase-crashlytics-plugin = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebaseCrashlytics" }
google-services-plugin = { module = "com.google.gms.google-services:com.google.gms.google-services.gradle.plugin", version.ref = "gms" }
hilt-android-plugin = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hilt" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt"}
hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
Expand All @@ -36,5 +46,7 @@ room-plugin = { module = "androidx.room:room-gradle-plugin", version.ref = "room
#Other Libs
apache-commons-lang = { module = "org.apache.commons:commons-lang3", version.ref = "apache-commons" }
dependency-guard-plugin = { module = "com.dropbox.dependency-guard:com.dropbox.dependency-guard.gradle.plugin", version.ref = "dependency-guard"}
truth = { module = "com.google.truth:truth", version.ref = "truth" }
oss-licenses-plugin = { group = "com.google.android.gms", name = "oss-licenses-plugin", version.ref = "oss-licenses" }
protobuf-plugin = { module = "com.google.protobuf:protobuf-gradle-plugin", version.ref = "protobuf" }
roborazzi-plugin = { module = "io.github.takahirom.roborazzi:roborazzi-gradle-plugin", version.ref = "roborazzi" }
truth = { module = "com.google.truth:truth", version.ref = "truth" }
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ dependencies {
api(libs.android.kotlin.android)

implementation(project(":plugin-jvm"))
implementation(libs.baseline.profile.plugin)
implementation(libs.dependency.guard.plugin)
implementation(libs.ksp.plugin)
implementation(libs.hilt.android.plugin)
implementation(libs.kotlin.serialization.plugin)
implementation(libs.room.plugin)
implementation(libs.protobuf.plugin)
implementation(libs.roborazzi.plugin)
implementation(libs.google.services.plugin)
implementation(libs.firebase.perf.plugin)
implementation(libs.firebase.crashlytics.plugin)
implementation(libs.oss.licenses.plugin)

implementation(libs.apache.commons.lang)
implementation(libs.android.tools.common)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package org.gradle.api.experimental.android;

import androidx.baselineprofile.gradle.consumer.BaselineProfileConsumerExtension;
import androidx.room.gradle.RoomExtension;
import com.android.build.api.dsl.BuildType;
import com.android.build.api.dsl.CommonExtension;
import com.android.build.api.dsl.UnitTestOptions;
import com.google.devtools.ksp.gradle.KspExtension;
import org.gradle.api.Action;
import org.gradle.api.JavaVersion;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.experimental.android.extensions.BaselineProfile;
import org.gradle.api.experimental.android.extensions.testing.AndroidTestDependencies;
import org.gradle.api.experimental.android.extensions.testing.TestOptions;
import org.gradle.api.experimental.android.extensions.testing.Testing;
import org.gradle.api.provider.Property;
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension;

import java.util.Objects;
import java.io.File;

import static org.gradle.api.experimental.android.AndroidSupport.ifPresent;
import static org.gradle.api.experimental.android.extensions.ComposeSupport.configureCompose;

public abstract class AbstractAndroidSoftwarePlugin implements Plugin<Project> {
Expand All @@ -32,10 +33,13 @@ public void apply(Project project) {

// Setup Android software conventions
dslModel.getMinSdk().convention(DEFAULT_MIN_ANDROID_SDK); // https://developer.android.com/build/multidex#mdex-gradle
dslModel.getVectorDrawablesUseSupportLibrary().convention(false);

// Setup minify conventions
dslModel.getBuildTypes().getDebug().getMinify().getEnabled().convention(false);
dslModel.getBuildTypes().getDebug().getBaselineProfile().getEnabled().convention(false);
dslModel.getBuildTypes().getRelease().getMinify().getEnabled().convention(false);
dslModel.getBuildTypes().getRelease().getBaselineProfile().getEnabled().convention(false);

// Setup desugaring conventions and desugar automatically when JDK > 8 is targeted
dslModel.getCoreLibraryDesugaring().getEnabled().convention(project.provider(() -> dslModel.getJdkVersion().get() > 8));
Expand All @@ -46,18 +50,26 @@ public void apply(Project project) {
dslModel.getKotlinSerialization().getVersion().convention("1.6.3");
dslModel.getKotlinSerialization().getJsonEnabled().convention(false);

// Setup Linting conventions
dslModel.getLint().getEnabled().convention(false);
dslModel.getLint().getXmlReport().convention(false);
dslModel.getLint().getCheckDependencies().convention(false);

// Setup other feature extension conventions
dslModel.getFeature().getEnabled().convention(false);
dslModel.getCompose().getEnabled().convention(false);
dslModel.getHilt().getEnabled().convention(false);
dslModel.getRoom().getEnabled().convention(false);
dslModel.getRoom().getVersion().convention("2.6.1");
dslModel.getLicenses().getEnabled().convention(false);
dslModel.getBaselineProfile().getEnabled().convention(false);

// Setup Test Options conventions
dslModel.getTesting().getTestOptions().getIncludeAndroidResources().convention(false);
dslModel.getTesting().getTestOptions().getReturnDefaultValues().convention(false);
dslModel.getTesting().getJacoco().getEnabled().convention(false);
dslModel.getTesting().getJacoco().getVersion().convention("0.8.7");
dslModel.getTesting().getRoborazzi().getEnabled().convention(false);
}

/**
Expand All @@ -75,13 +87,13 @@ protected void linkCommonDependencies(AndroidSoftwareDependencies dependencies,
*/
protected void linkDslModelToPlugin(Project project, AndroidSoftware dslModel, CommonExtension<?, ?, ?, ?, ?, ?> android) {
KotlinAndroidProjectExtension kotlin = project.getExtensions().getByType(KotlinAndroidProjectExtension.class);
ConfigurationContainer configurations = project.getConfigurations();

// Link common properties
ifPresent(dslModel.getNamespace(), android::setNamespace);
ifPresent(dslModel.getCompileSdk(), android::setCompileSdk);
android.defaultConfig(defaultConfig -> {
ifPresent(dslModel.getMinSdk(), defaultConfig::setMinSdk);
ifPresent(dslModel.getVectorDrawablesUseSupportLibrary(), defaultConfig.getVectorDrawables()::setUseSupportLibrary);
return null;
});
android.compileOptions(compileOptions -> {
Expand All @@ -100,19 +112,31 @@ protected void linkDslModelToPlugin(Project project, AndroidSoftware dslModel, C
// Link build types
AndroidSoftwareBuildTypes modelBuildType = dslModel.getBuildTypes();
NamedDomainObjectContainer<? extends BuildType> androidBuildTypes = android.getBuildTypes();
linkBuildType(androidBuildTypes.getByName("debug"), modelBuildType.getDebug(), configurations);
linkBuildType(androidBuildTypes.getByName("release"), modelBuildType.getRelease(), configurations);
linkBuildType(project, androidBuildTypes.getByName("debug"), modelBuildType.getDebug(), android);
linkBuildType(project, androidBuildTypes.getByName("release"), modelBuildType.getRelease(), android);

configureTesting(project, dslModel, android);

configureKotlinSerialization(project, dslModel);
configureDesugaring(project, dslModel, android);
configureHilt(project, dslModel, android);
configureHilt(project, dslModel);
configureCompose(project, dslModel, android);
configureRoom(project, dslModel, android);
configureRoom(project, dslModel);
configureLicenses(project, dslModel);

if (project.getExtensions().findByName("baselineProfile") != null) {
BaselineProfileConsumerExtension baselineProfileExtension = project.getExtensions().getByType(BaselineProfileConsumerExtension.class);
configureBaselineProfile(project, dslModel.getBaselineProfile(), baselineProfileExtension);
}
}

private static void configureLicenses(Project project, AndroidSoftware dslModel) {
if (dslModel.getLicenses().getEnabled().get()) {
project.getPlugins().apply("com.google.android.gms.oss-licenses-plugin");
}
}

protected void configureHilt(Project project, AndroidSoftware dslModel, CommonExtension<?, ?, ?, ?, ?, ?> android) {
protected void configureHilt(Project project, AndroidSoftware dslModel) {
if (dslModel.getHilt().getEnabled().get()) {
project.getLogger().info("Hilt is enabled in: " + project.getPath());

Expand All @@ -123,11 +147,13 @@ protected void configureHilt(Project project, AndroidSoftware dslModel, CommonEx
// Add support for Hilt
project.getPlugins().apply("dagger.hilt.android.plugin");
project.getDependencies().add("implementation", "com.google.dagger:hilt-android:2.50");

project.getDependencies().add("kspTest", "com.google.dagger:hilt-android-compiler:2.50");
}
}

@SuppressWarnings("UnstableApiUsage")
protected void configureRoom(Project project, AndroidSoftware dslModel, CommonExtension<?, ?, ?, ?, ?, ?> android) {
protected void configureRoom(Project project, AndroidSoftware dslModel) {
if (dslModel.getRoom().getEnabled().get()) {
project.getLogger().info("Room is enabled in: " + project.getPath());

Expand Down Expand Up @@ -178,6 +204,14 @@ protected void configureTesting(Project project, AndroidSoftware dslModel, Commo
ConfigurationContainer configurations = project.getConfigurations();
configurations.getByName("testImplementation").fromDependencyCollector(testDependencies.getImplementation());
configurations.getByName("androidTestImplementation").fromDependencyCollector(testDependencies.getAndroidImplementation());

configureRoborazzi(project, dslModel);
}

protected void configureRoborazzi(Project project, AndroidSoftware dslModel) {
if (dslModel.getTesting().getRoborazzi().getEnabled().get()) {
project.getPlugins().apply("io.github.takahirom.roborazzi");
}
}

@SuppressWarnings("UnstableApiUsage")
Expand All @@ -194,12 +228,36 @@ protected void configureKotlinSerialization(Project project, AndroidSoftware dsl
}
}

@SuppressWarnings("UnstableApiUsage")
private static void configureBaselineProfile(Project project, BaselineProfile baselineProfile, BaselineProfileConsumerExtension baselineProfileExtension) {
if (baselineProfile.getEnabled().get()) {
project.getPlugins().apply("androidx.baselineprofile");

baselineProfileExtension.setAutomaticGenerationDuringBuild(baselineProfile.getAutomaticGenerationDuringBuild().get());

project.getConfigurations().getByName("baselineProfile").fromDependencyCollector(baselineProfile.getDependencies().getProfile());
}
}

/**
* Links build types from the model to the android extension.
*/
protected void linkBuildType(BuildType buildType, AndroidSoftwareBuildType model, ConfigurationContainer configurations) {
protected void linkBuildType(Project project, BuildType buildType, AndroidSoftwareBuildType model, CommonExtension<?, ?, ?, ?, ?, ?> android) {
buildType.setMinifyEnabled(model.getMinify().getEnabled().get());
linkBuildTypeDependencies(buildType, model.getDependencies(), configurations);
linkBuildTypeDependencies(buildType, model.getDependencies(), project.getConfigurations());

model.getDefaultProguardFiles().get().forEach(proguardFile -> {
File defaultProguardFile = android.getDefaultProguardFile(proguardFile.getName().get());
buildType.proguardFile(defaultProguardFile);
});
model.getProguardFiles().get().forEach(proguardFile -> {
buildType.proguardFile(proguardFile.getName().get());
});

if (buildType.getExtensions().findByName("baselineProfile") != null) {
BaselineProfileConsumerExtension baselineProfileExtension = buildType.getExtensions().getByType(BaselineProfileConsumerExtension.class);
configureBaselineProfile(project, model.getBaselineProfile(), baselineProfileExtension);
}
}

@SuppressWarnings("UnstableApiUsage")
Expand All @@ -209,10 +267,4 @@ protected void linkBuildTypeDependencies(BuildType buildType, AndroidSoftwareDep
configurations.getByName(name + "CompileOnly").fromDependencyCollector(dependencies.getCompileOnly());
configurations.getByName(name + "RuntimeOnly").fromDependencyCollector(dependencies.getRuntimeOnly());
}

protected <T> void ifPresent(Property<T> property, Action<T> action) {
if (property.isPresent()) {
action.execute(property.get());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@
import com.android.build.api.dsl.BaseFlavor;
import com.android.build.api.dsl.CommonExtension;
import org.gradle.api.Action;
import org.gradle.api.experimental.android.extensions.BaselineProfile;
import org.gradle.api.experimental.android.extensions.Compose;
import org.gradle.api.experimental.android.extensions.CoreLibraryDesugaring;
import org.gradle.api.experimental.android.extensions.Hilt;
import org.gradle.api.experimental.android.extensions.KotlinSerialization;
import org.gradle.api.experimental.android.extensions.Room;
import org.gradle.api.experimental.android.extensions.testing.Testing;
import org.gradle.api.experimental.android.nia.Feature;
import org.gradle.api.experimental.android.extensions.Licenses;
import org.gradle.api.experimental.common.extensions.HasLinting;
import org.gradle.api.experimental.common.extensions.Lint;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Nested;
import org.gradle.declarative.dsl.model.annotations.Configuring;
import org.gradle.declarative.dsl.model.annotations.Restricted;

public interface AndroidSoftware {
public interface AndroidSoftware extends HasLinting {
/**
* @see CommonExtension#getCompileSdk()
*/
Expand All @@ -40,6 +44,9 @@ public interface AndroidSoftware {
@Restricted
Property<Integer> getJdkVersion();

@Restricted
Property<Boolean> getVectorDrawablesUseSupportLibrary();

AndroidSoftwareBuildTypes getBuildTypes();

AndroidSoftwareDependencies getDependencies();
Expand Down Expand Up @@ -108,7 +115,7 @@ default void testing(Action<? super Testing> action) {

/**
* Support for NiA convention projects defining features.
* TODO: This is a temporary solution until we have a proper feature model.
* TODO:DG This is a temporary solution until we have a proper feature model.
*/
@Nested
Feature getFeature();
Expand All @@ -119,4 +126,39 @@ default void feature(Action<? super Feature> action) {
feature.getEnabled().set(true);
action.execute(feature);
}

/**
* Support for NiA projects using the com.google.android.gms.oss-licenses-plugin
* TODO:DG This is a temporary solution until we have a better way of applying plugins
*/
@Nested
Licenses getLicenses();

@Configuring
default void licenses(Action<? super Licenses> action) {
Licenses licenses = getLicenses();
licenses.getEnabled().set(true);
action.execute(licenses);
}

@Nested
BaselineProfile getBaselineProfile();

@Configuring
default void baselineProfile(Action<? super BaselineProfile> action) {
BaselineProfile baselineProfile = getBaselineProfile();
baselineProfile.getEnabled().set(true);
action.execute(baselineProfile);
}

@Override
@Nested
Lint getLint();

@Configuring
default void lint(Action<? super Lint> action) {
Lint lint = getLint();
lint.getEnabled().set(true);
action.execute(lint);
}
}
Loading
Loading