Skip to content

Commit

Permalink
build: Add AarDepsPlugin and replace the project config to kotlin jvm…
Browse files Browse the repository at this point in the history
… from kotlin android (#6)
  • Loading branch information
warnyul authored Mar 11, 2024
1 parent 8e1b646 commit 91069a1
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 18 deletions.
12 changes: 12 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -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)
}
7 changes: 7 additions & 0 deletions buildSrc/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../gradle/libs.versions.toml"))
}
}
}
116 changes: 116 additions & 0 deletions buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
}
7 changes: 5 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -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" }
Expand All @@ -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 = [
Expand Down
28 changes: 13 additions & 15 deletions robolectric-extension/build.gradle
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -38,3 +32,7 @@ dependencies {
kotlin {
jvmToolchain(libs.versions.jvmToolchain.get().toInteger())
}

test {
useJUnitPlatform()
}

0 comments on commit 91069a1

Please sign in to comment.