-
Notifications
You must be signed in to change notification settings - Fork 3
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
build: Add AarDepsPlugin and replace the project config to kotlin jvm from kotlin android #6
Conversation
WalkthroughThe changes encompass setting up a composite build for Changes
Poem
Note Pull Request Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://coderabbit.ai TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
… 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() +}
39691ae
to
7f3ce50
Compare
Summary by CodeRabbit
New Features
AarDepsPlugin
) to resolve AAR dependencies into JAR files for non-Android projects.Bug Fixes
Refactor
buildSrc/build.gradle
file.robolectric-extension/build.gradle
file.