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

chore(deps): update all non-major dependencies #75

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ jobs:
contents: read

steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
with:
java-version-file: '.java-version'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2
uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 # v3.5.0
- name: Bump version
if: github.event_name == 'workflow_dispatch' && github.event.inputs.releaseVersion != ''
run: |
Expand Down Expand Up @@ -58,7 +58,7 @@ jobs:
JUNIT5_ROBOLECTRIC_EXTENSION_GPG_SIGNING_KEY: '${{ secrets.JUNIT5_ROBOLECTRIC_EXTENSION_GPG_SIGNING_KEY }}'
JUNIT5_ROBOLECTRIC_EXTENSION_GPG_SIGNING_PASSWORD: '${{ secrets.JUNIT5_ROBOLECTRIC_EXTENSION_GPG_SIGNING_PASSWORD }}'
- name: Upload coverage report
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
if: ${{ hashFiles('build/reports/kover/report.xml') != '' }}
with:
name: kover-report
Expand All @@ -72,7 +72,7 @@ jobs:
- build
if: github.ref_name == github.event.repository.default_branch && github.event_name == 'workflow_dispatch' && github.event.inputs.releaseVersion != '' && !endsWith(github.event.inputs.releaseVersion, 'SNAPSHOT')
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ github.head_ref }}
- name: Create release
Expand All @@ -97,7 +97,7 @@ jobs:
if: github.repository == 'apter-tech/junit5-robolectric-extension' && github.event_name == 'pull_request'
steps:
- name: Download coverage report
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: kover-report
- name: Comment branch coverage report to PR
Expand Down
1 change: 1 addition & 0 deletions .idea/.gitignore

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

3 changes: 1 addition & 2 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 build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ subprojects {

dependencies {
kover(project(':integration-tests:agp-groovy-dsl'))
kover(project(':integration-tests:agp-kotlin-dsl'))
// kover(project(':integration-tests:agp-kotlin-dsl'))
kover(project(':robolectric-extension'))
kover(project(':robolectric-extension-gradle-plugin'))
}
32 changes: 24 additions & 8 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ dependencies {
compileOnly(gradleApi())
compileOnly(localGroovy())
implementation(libs.guava)
implementation(libs.androidGradle)
implementation(libs.androidGradleApi)
implementation(libs.androidToolsCommon)
}

java {
Expand All @@ -22,18 +23,33 @@ java {
}

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 baseUrl = "https://raw.githubusercontent.com/robolectric/robolectric/robolectric-${libs.versions.robolectric.get()}/"
final from = [
"${baseUrl}buildSrc/src/main/groovy/org/robolectric/gradle/AarDepsPlugin.java",
"${baseUrl}buildSrc/src/main/groovy/org/robolectric/gradle/agp/ExtractAarTransform.java",
"${baseUrl}buildSrc/src/main/groovy/org/robolectric/gradle/agp/GenericTransformParameters.java",

]
final groovySourceSet = sourceSets.named('main').get().allSource.sourceDirectories.find { it.name == 'groovy' } as File
final to = new File(groovySourceSet, '/org/robolectric/gradle/AarDepsPlugin.java')
final to = [
new File(groovySourceSet, '/org/robolectric/gradle/AarDepsPlugin.java'),
new File(groovySourceSet, '/org/robolectric/gradle/agp/ExtractAarTransform.java'),
new File(groovySourceSet, '/org/robolectric/gradle/agp/GenericTransformParameters.java'),
]


inputs.property("from", from)
outputs.file(to)
outputs.files(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")
from.indices.forEach { i ->
final url = from[i]
final targetFile = to[i]
try {
new URL(url).withInputStream { inputStream -> targetFile.withOutputStream { it << inputStream } }
} catch (IOException e) {
logger.debug("Error during downloading ${url.name}. Keep the stored version.\n$e")
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

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.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
Expand All @@ -17,6 +17,7 @@
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.compile.JavaCompile;
import org.jetbrains.annotations.NotNull;
import org.robolectric.gradle.agp.ExtractAarTransform;

/** Resolve aar dependencies into jars for non-Android projects. */
public class AarDepsPlugin implements Plugin<Project> {
Expand Down Expand Up @@ -63,7 +64,11 @@ public void execute(@NotNull Task task) {
List<File> aarFiles = AarDepsPlugin.this.findAarFiles(t.getClasspath());
if (!aarFiles.isEmpty()) {
throw new IllegalStateException(
"AARs on classpath: " + Joiner.on("\n ").join(aarFiles));
"AARs on classpath: "
+ aarFiles.stream()
.filter(Objects::nonNull)
.map(File::toString)
.collect(Collectors.joining("\n ")));
}
}
}));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* This class comes from AGP internals:
* https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/ExtractAarTransform.kt;bpv=0
*/

package org.robolectric.gradle.agp;

import com.android.SdkConstants;
import com.android.utils.FileUtils;
import com.google.common.io.Files;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.gradle.api.artifacts.transform.InputArtifact;
import org.gradle.api.artifacts.transform.TransformAction;
import org.gradle.api.artifacts.transform.TransformOutputs;
import org.gradle.api.file.FileSystemLocation;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Classpath;
import org.gradle.work.DisableCachingByDefault;
import org.jetbrains.annotations.NotNull;

// TODO Keep the original Kotlin implementation when `buildSrc` is migrated to Kotlin.
@DisableCachingByDefault(because = "Copy task")
public abstract class ExtractAarTransform implements TransformAction<GenericTransformParameters> {
@Classpath
@InputArtifact
public abstract Provider<FileSystemLocation> getAarFile();

@Override
public void transform(@NotNull TransformOutputs outputs) {
// TODO(b/162813654) record transform execution span
File inputFile = getAarFile().get().getAsFile();
String inputFileNameWithoutExtension = Files.getNameWithoutExtension(inputFile.getName());
File outputDir = outputs.dir(inputFileNameWithoutExtension);
FileUtils.mkdirs(outputDir);
new AarExtractor().extract(inputFile, outputDir);
}
}

class AarExtractor {
private static final String LIBS_PREFIX = SdkConstants.LIBS_FOLDER + '/';
private static final int LIBS_PREFIX_LENGTH = LIBS_PREFIX.length();
private static final int JARS_PREFIX_LENGTH = SdkConstants.FD_JARS.length() + 1;

// Note:
// - A jar doesn't need a manifest entry, but if we ever want to create a manifest entry, be
// sure to set a fixed timestamp for it so that the jar is deterministic (see b/315336689).
// - This empty jar takes up only ~22 bytes, so we don't need to GC it at the end of the build.
private static final byte[] emptyJar;

/**
* {@link StringBuilder} used to construct all paths. It gets truncated back to {@link
* JARS_PREFIX_LENGTH} on every calculation.
*/
private final StringBuilder stringBuilder = new StringBuilder(60);

static {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//noinspection EmptyTryBlock
try (JarOutputStream outputStream = new JarOutputStream(byteArrayOutputStream)) {
} catch (IOException e) {
throw new RuntimeException(e);
}

emptyJar = byteArrayOutputStream.toByteArray();
}

AarExtractor() {
stringBuilder.append(SdkConstants.FD_JARS);
stringBuilder.append(File.separatorChar);
}

private String choosePathInOutput(@NotNull String entryName) {
stringBuilder.setLength(JARS_PREFIX_LENGTH);

if (entryName.equals(SdkConstants.FN_CLASSES_JAR)
|| entryName.equals(SdkConstants.FN_LINT_JAR)) {
stringBuilder.append(entryName);

return stringBuilder.toString();
} else if (entryName.startsWith(LIBS_PREFIX)) {
// In case we have libs/classes.jar we are going to rename them, due an issue in
// Gradle.
// TODO: stop doing this once this is fixed in gradle. b/65298222
String pathWithinLibs = entryName.substring(LIBS_PREFIX_LENGTH);

if (pathWithinLibs.equals(SdkConstants.FN_CLASSES_JAR)) {
stringBuilder.append(LIBS_PREFIX).append("classes-2" + SdkConstants.DOT_JAR);
} else if (pathWithinLibs.equals(SdkConstants.FN_LINT_JAR)) {
stringBuilder.append(LIBS_PREFIX).append("lint-2" + SdkConstants.DOT_JAR);
} else {
stringBuilder.append(LIBS_PREFIX).append(pathWithinLibs);
}

return stringBuilder.toString();
} else {
return entryName;
}
}

/**
* Extracts an AAR file into a directory.
*
* <p>Note: There are small adjustments made to the extracted contents. For example, classes.jar
* inside the AAR will be extracted to jars/classes.jar, and if the jar does not exist, we will
* create an empty classes.jar.
*/
void extract(@NotNull File aar, @NotNull File outputDir) {
try (ZipInputStream zipInputStream =
new ZipInputStream(java.nio.file.Files.newInputStream(aar.toPath()))) {
while (true) {
ZipEntry entry = zipInputStream.getNextEntry();
if (entry == null) {
break;
}

if (entry.isDirectory() || entry.getName().contains("../") || entry.getName().isEmpty()) {
continue;
}

String path = FileUtils.toSystemDependentPath(choosePathInOutput(entry.getName()));
File outputFile = new File(outputDir, path);
Files.createParentDirs(outputFile);
Files.asByteSink(outputFile).writeFrom(zipInputStream);
}
} catch (IOException e) {
throw new RuntimeException(e);
}

// If classes.jar does not exist, create an empty one
File classesJar = resolve(outputDir, SdkConstants.FD_JARS + "/" + SdkConstants.FN_CLASSES_JAR);
if (!classesJar.exists()) {
try {
Files.createParentDirs(classesJar);
Files.write(emptyJar, classesJar);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

@NotNull
private File resolve(@NotNull File source, @NotNull String relative) {
Path baseDir = source.toPath();
Path relativeFile = Paths.get(relative);
Path resolvedFile = baseDir.resolve(relativeFile);

return resolvedFile.toFile();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* This class comes from AGP internals:
* https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dependency/GenericTransformParameters.kt;bpv=0
*/

package org.robolectric.gradle.agp;

import org.gradle.api.artifacts.transform.TransformParameters;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Internal;

/** Generic {@link TransformParameters} for all of our Artifact Transforms. */
// TODO Keep the original Kotlin implementation when `buildSrc` is migrated to Kotlin.
public interface GenericTransformParameters extends TransformParameters {
@Internal
Property<String> getProjectName();
}
Loading