aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoogler <noreply@google.com>2024-05-25 13:14:02 -0700
committerCopybara-Service <copybara-worker@google.com>2024-05-25 13:14:46 -0700
commitf5ad890603f59fe74a5c7d6cdcaea7a81324bc5f (patch)
tree0431ff979060bc1430bd6850214d753957694e9d
parent400d755ccae63f80d8b64245d238252e8eae844b (diff)
downloadrobolectric-upstream-google.tar.gz
Don't throw exceptions in AndroidVersions when running in annotation processors.upstream-google
Android platform development has build configurations report being different android (pre-)releases. To prevent breaking the build, report all AndroidVersions errors as warnings in annotation-processors. PiperOrigin-RevId: 637260391
-rw-r--r--annotations/src/main/java/org/robolectric/versioning/AndroidVersions.java60
-rw-r--r--annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java44
2 files changed, 96 insertions, 8 deletions
diff --git a/annotations/src/main/java/org/robolectric/versioning/AndroidVersions.java b/annotations/src/main/java/org/robolectric/versioning/AndroidVersions.java
index 71cc48042..0b5f18ed7 100644
--- a/annotations/src/main/java/org/robolectric/versioning/AndroidVersions.java
+++ b/annotations/src/main/java/org/robolectric/versioning/AndroidVersions.java
@@ -53,6 +53,8 @@ import javax.annotation.Nullable;
*/
public final class AndroidVersions {
+ private static boolean warnOnly;
+
private AndroidVersions() {}
/** Representation of an android release, one that has occurred, or is expected. */
@@ -825,7 +827,7 @@ public final class AndroidVersions {
}
}
- private void throwStaticErrors() {
+ private void handleStaticErrors() {
StringBuilder errors = new StringBuilder();
if (!this.classesWithIllegalNames.isEmpty()) {
errors
@@ -858,14 +860,15 @@ public final class AndroidVersions {
}
}
if (errors.length() > 0) {
- throw new IllegalStateException(
+ errorMessage(
errors
.append("Please check the AndroidReleases defined ")
.append("in ")
.append(AndroidVersions.class.getName())
.append("and ensure they are aligned with the versions of")
.append(" Android.")
- .toString());
+ .toString(),
+ null);
}
}
@@ -877,14 +880,15 @@ public final class AndroidVersions {
// the first letter of the code name equal to the release number.
current = sdkIntToAllReleases.get(reportedVersion);
if (current != null && !current.isReleased()) {
- throw new IllegalStateException(
+ errorMessage(
"The current sdk "
+ current.getShortCode()
+ " has been released. Please update the contents of "
+ AndroidVersions.class.getName()
+ " to mark sdk "
+ current.getShortCode()
- + " as released.");
+ + " as released.",
+ null);
}
} else {
// Get known active code name letters
@@ -936,10 +940,31 @@ public final class AndroidVersions {
.append("contents of current sdk jar to the released version.\n");
}
if (detectedProblems.length() > 0) {
- throw new IllegalStateException(detectedProblems.toString());
+ errorMessage(detectedProblems.toString(), null);
+ }
+
+ if (current == null) { // only possible in warning mode
+ current =
+ new AndroidUnreleased() {
+ @Override
+ public int getSdkInt() {
+ return 10000; // the super large unknown sdk value.
+ }
+
+ @Override
+ public String getShortCode() {
+ return codename.toUpperCase(Locale.getDefault()).substring(0, 1);
+ }
+
+ @Override
+ public String getVersion() {
+ return "";
+ }
+ };
}
}
}
+
return current;
}
}
@@ -971,7 +996,7 @@ public final class AndroidVersions {
| IllegalArgumentException
| IllegalAccessException
| InvocationTargetException ex) {
- throw new IllegalStateException(
+ errorMessage(
"Classes "
+ clazz.getName()
+ "should be accessible via "
@@ -984,7 +1009,7 @@ public final class AndroidVersions {
Collections.sort(allReleases, AndroidRelease::compareTo);
SdkInformation sdkInformation = new SdkInformation(allReleases, classesWithIllegalNames);
- sdkInformation.throwStaticErrors();
+ sdkInformation.handleStaticErrors();
return sdkInformation;
}
@@ -1013,7 +1038,26 @@ public final class AndroidVersions {
private static final SdkInformation information;
+ private static final void errorMessage(String errorMessage, @Nullable Exception ex) {
+ if (warnOnly) {
+ System.err.println(errorMessage);
+ } else {
+ throw new IllegalStateException(errorMessage, ex);
+ }
+ }
+
static {
+ // We shouldn't break in annotation processors, only test runs.
+ String cmd = System.getProperty("sun.java.command");
+ // We appear to be in an annotation processor, so only warn users.
+ if (cmd.contains("-Aorg.robolectric.annotation.processing.")) {
+ System.err.println(
+ "Robolectric's AndroidVersions is running in warning mode,"
+ + " no errors will be thrown.");
+ warnOnly = true;
+ } else {
+ warnOnly = false;
+ }
AndroidRelease currentRelease = null;
information = gatherStaticSdkInformationFromThisClass();
try {
diff --git a/annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java b/annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java
index 95b2c4266..90870abef 100644
--- a/annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java
+++ b/annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java
@@ -2,6 +2,7 @@ package org.robolectric.versioning;
import static com.google.common.truth.Truth.assertThat;
+import java.lang.reflect.Field;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -13,6 +14,16 @@ import org.robolectric.versioning.AndroidVersions.SdkInformation;
@RunWith(JUnit4.class)
public final class AndroidVersionsEdgeCaseTest {
+ private void forceWarningMode(boolean warnMode) {
+ try {
+ Field field = AndroidVersions.class.getDeclaredField("warnOnly");
+ field.setAccessible(true);
+ field.set(null, warnMode);
+ } catch (NoSuchFieldException | IllegalAccessException ex) {
+ throw new RuntimeException("Could not update warnOnly field", ex);
+ }
+ }
+
/**
* sdkInt higher than any known release, claims it's released. Expects an error message to update
* to update the AndroidVersions.class
@@ -21,6 +32,7 @@ public final class AndroidVersionsEdgeCaseTest {
public void sdkIntHigherThanKnownReleasesClaimsIsReleased_throwsException() {
AndroidRelease earliestUnrelease = null;
try {
+ forceWarningMode(false);
SdkInformation information = AndroidVersions.gatherStaticSdkInformationFromThisClass();
earliestUnrelease = information.earliestUnreleased;
information.computeCurrentSdk(
@@ -49,6 +61,7 @@ public final class AndroidVersionsEdgeCaseTest {
public void sdkIntReleasedButStillReportsCodeName_throwsException() {
AndroidRelease latestRelease = null;
try {
+ forceWarningMode(false);
SdkInformation information = AndroidVersions.gatherStaticSdkInformationFromThisClass();
latestRelease = information.latestRelease;
information.computeCurrentSdk(
@@ -68,4 +81,35 @@ public final class AndroidVersionsEdgeCaseTest {
assertThat(e).isInstanceOf(RuntimeException.class);
}
}
+
+ @Test
+ public void sdkIntReleasedButStillReportsCodeName_warningMode() {
+ AndroidRelease latestRelease = null;
+ try {
+ forceWarningMode(true);
+ SdkInformation information = AndroidVersions.gatherStaticSdkInformationFromThisClass();
+ latestRelease = information.latestRelease;
+ information.computeCurrentSdk(
+ latestRelease.getSdkInt(),
+ null,
+ information.latestRelease.getShortCode(),
+ Arrays.asList(latestRelease.getShortCode()));
+ } catch (Throwable t) {
+ assertThat(t).isNull();
+ }
+ }
+
+ @Test
+ public void unknownSdkInt_warningMode() {
+ try {
+ forceWarningMode(true);
+ SdkInformation information = AndroidVersions.gatherStaticSdkInformationFromThisClass();
+ AndroidRelease found =
+ information.computeCurrentSdk(
+ 35, "zzzz", "Z", Arrays.asList("wwww", "xxxx", "yyyy", "zzzz"));
+ assertThat(found.getSdkInt()).isEqualTo(10000);
+ } catch (Throwable t) {
+ assertThat(t).isNull();
+ }
+ }
}