Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build: Add AarDepsPlugin and replace the project config to kotlin jvm…
… from kotlin android diff --git a/.idea/gradle.xml b/.idea/gradle.xml index e76e4f9..cdc4970 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,12 +4,24 @@ <component name="GradleSettings"> <option name="linkedExternalProjectsSettings"> <GradleProjectSettings> + <compositeConfiguration> + <compositeBuild compositeDefinitionSource="SCRIPT"> + <builds> + <build path="$PROJECT_DIR$/buildSrc" name="buildSrc"> + <projects> + <project path="$PROJECT_DIR$/buildSrc" /> + </projects> + </build> + </builds> + </compositeBuild> + </compositeConfiguration> <option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="gradleHome" value="" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> <option name="modules"> <set> <option value="$PROJECT_DIR$" /> + <option value="$PROJECT_DIR$/buildSrc" /> <option value="$PROJECT_DIR$/robolectric-extension" /> </set> </option> diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 8d81632..fe63bb6 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="KotlinJpsPluginSettings"> - <option name="version" value="1.9.22" /> + <option name="version" value="1.9.23" /> </component> </project> \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..748e06b --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'java-library' + id 'groovy' +} + +repositories { + google() + mavenCentral() + gradlePluginPortal() +} + +dependencies { + compileOnly gradleApi() + compileOnly localGroovy() + implementation libs.guava + implementation libs.androidBuildTools +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(libs.versions.jvmToolchain.get())) + } +} + +task downloadAarDepsPlugin { + final from = "https://raw.githubusercontent.com/robolectric/robolectric/robolectric-${libs.versions.robolectric.get()}/buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java" + final groovySourceSet = new File(sourceSets.findByName('main').allSource.sourceDirectories.find { it.name == 'groovy' }.path) + final to = new File(groovySourceSet, '/org/robolectric/gradle/AarDepsPlugin.java') + + inputs.property("from", from) + outputs.file(to) + + doLast { + try { + new URL(from).withInputStream { i -> to.withOutputStream { it << i } } + } catch (IOException e) { + logger.debug("Error during downloading AarDepsPlugin. Keep the stored version.\n$e") + } + } +} + +tasks { + compileJava.dependsOn(downloadAarDepsPlugin) + compileGroovy.dependsOn(downloadAarDepsPlugin) +} diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle new file mode 100644 index 0000000..6f31e6e --- /dev/null +++ b/buildSrc/settings.gradle @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + libs { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java b/buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java new file mode 100644 index 0000000..0432cea --- /dev/null +++ b/buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java @@ -0,0 +1,116 @@ +package org.robolectric.gradle; + +import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE; + +import com.android.build.gradle.internal.dependency.ExtractAarTransform; +import com.google.common.base.Joiner; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import javax.inject.Inject; +import org.gradle.api.Action; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.artifacts.transform.TransformOutputs; +import org.gradle.api.file.FileCollection; +import org.gradle.api.tasks.compile.JavaCompile; +import org.jetbrains.annotations.NotNull; + +/** + * Resolve aar dependencies into jars for non-Android projects. + */ +public class AarDepsPlugin implements Plugin<Project> { + @OverRide + public void apply(Project project) { + project + .getDependencies() + .registerTransform( + ClassesJarExtractor.class, + reg -> { + reg.getParameters().getProjectName().set(project.getName()); + reg.getFrom().attribute(ARTIFACT_TYPE_ATTRIBUTE, "aar"); + reg.getTo().attribute(ARTIFACT_TYPE_ATTRIBUTE, "jar"); + }); + + project.afterEvaluate( + p -> + project + .getConfigurations() + .forEach( + c -> { + // I suspect we're meant to use the org.gradle.usage attribute, but this + // works. + if (c.getName().endsWith("Classpath")) { + c.attributes( + cfgAttrs -> cfgAttrs.attribute(ARTIFACT_TYPE_ATTRIBUTE, "jar")); + } + })); + + // warn if any AARs do make it through somehow; there must be a gradle configuration + // that isn't matched above. + //noinspection Convert2Lambda + project + .getTasks() + .withType(JavaCompile.class) + .all( + // the following Action<Task needs to remain an anonymous subclass or gradle's + // incremental compile breaks (run `gradlew -i classes` twice to see impact): + t -> t.doFirst(new Action<Task>() { + @OverRide + public void execute(Task task) { + List<File> aarFiles = AarDepsPlugin.this.findAarFiles(t.getClasspath()); + if (!aarFiles.isEmpty()) { + throw new IllegalStateException( + "AARs on classpath: " + Joiner.on("\n ").join(aarFiles)); + } + } + })); + } + + private List<File> findAarFiles(FileCollection files) { + List<File> bad = new ArrayList<>(); + for (File file : files.getFiles()) { + if (file.getName().toLowerCase().endsWith(".aar")) { + bad.add(file); + } + } + return bad; + } + + public static abstract class ClassesJarExtractor extends ExtractAarTransform { + @Inject + public ClassesJarExtractor() { + } + + @OverRide + public void transform(@NotNull TransformOutputs outputs) { + AtomicReference<File> classesJarFile = new AtomicReference<>(); + AtomicReference<File> outJarFile = new AtomicReference<>(); + super.transform(new TransformOutputs() { + // This is the one that ExtractAarTransform calls. + @OverRide + public File dir(Object o) { + // ExtractAarTransform needs a place to extract the AAR. We don't really need to + // register this as an output, but it'd be tricky to avoid it. + File dir = outputs.dir(o); + + // Also, register our jar file. Its name needs to be quasi-unique or + // IntelliJ Gradle/Android plugins get confused. + classesJarFile.set(new File(new File(dir, "jars"), "classes.jar")); + outJarFile.set(new File(new File(dir, "jars"), o + ".jar")); + outputs.file(o + "/jars/" + o + ".jar"); + return outputs.dir(o); + } + + @OverRide + public File file(Object o) { + throw new IllegalStateException("shouldn't be called"); + } + }); + + classesJarFile.get().renameTo(outJarFile.get()); + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bca64aa..4676734 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,21 @@ [versions] androidBuildTools = "8.3.0" -androidCompileSdk = "34" androidJUnit5 = "1.10.0.0" androidxTestExtJunit = "1.1.5" +guava = "33.0.0-jre" junit4 = "4.13.2" junit5 = "5.10.2" jvmToolchain = "17" -kotlin = "1.9.22" +kotlin = "1.9.23" robolectric = "4.11.1" robolectricAndroidAll = "14-robolectric-10818077" # Use when bom also added to the dependencies sources = "sources" [libraries] +androidBuildTools = { module = "com.android.tools.build:gradle", version.ref = "androidBuildTools" } androidxTestExtJunit = { module = "androidx.test.ext:junit", version.ref = "androidxTestExtJunit" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } guavaConstraint = { module = "com.google.guava:guava", version = { require = "[32.0.1-jre,]" } } junit4 = { module = "junit:junit", version.ref = "junit4" } junit5Bom = { module = "org.junit:junit-bom", version.ref = "junit5" } @@ -29,6 +31,7 @@ robolectricAndroidAll = { module = "org.robolectric:android-all", version.ref = androidJUnit5 = { id = "de.mannodermaus.android-junit5", version.ref = "androidJUnit5" } androidLibrary = { id = "com.android.library", version.ref = "androidBuildTools" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } [bundles] junit5 = [ diff --git a/robolectric-extension/build.gradle b/robolectric-extension/build.gradle index 4376dbe..e594b51 100644 --- a/robolectric-extension/build.gradle +++ b/robolectric-extension/build.gradle @@ -1,21 +1,15 @@ +import org.robolectric.gradle.AarDepsPlugin + plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlinAndroid) - alias(libs.plugins.androidJUnit5) + alias(libs.plugins.kotlinJvm) + } -android { - defaultConfig { - namespace = "$group.$name" - compileOptions { - compileSdk libs.versions.androidCompileSdk.get().toInteger() - } - } - testOptions { - unitTests.all { - useJUnitPlatform() - } - } +apply plugin: AarDepsPlugin + +configurations.configureEach { configuration -> + configuration.exclude(group: 'androidx.tracing', module: 'tracing') + configuration.exclude(group: 'androidx.annotation', module: 'annotation-experimental') } dependencies { @@ -38,3 +32,7 @@ dependencies { kotlin { jvmToolchain(libs.versions.jvmToolchain.get().toInteger()) } + +test { + useJUnitPlatform() +}
- Loading branch information