diff options
author | Googler <noreply@google.com> | 2024-05-25 13:14:02 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-05-25 13:14:46 -0700 |
commit | f5ad890603f59fe74a5c7d6cdcaea7a81324bc5f (patch) | |
tree | 0431ff979060bc1430bd6850214d753957694e9d | |
parent | 400d755ccae63f80d8b64245d238252e8eae844b (diff) | |
download | robolectric-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.java | 60 | ||||
-rw-r--r-- | annotations/src/test/java/org/robolectric/versioning/AndroidVersionsEdgeCaseTest.java | 44 |
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(); + } + } } |