Skip to content

Commit 9385b2a

Browse files
authored
Merge branch 'master' into ds-abt-variant-id
2 parents 3e7b35c + 9226348 commit 9385b2a

File tree

29 files changed

+772
-103
lines changed

29 files changed

+772
-103
lines changed

buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/PublishingPlugin.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
import com.google.firebase.gradle.plugins.FirebaseLibraryExtension;
1818
import java.io.File;
19-
import java.util.Arrays;
19+
import java.io.IOException;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
22+
import java.util.List;
2023
import java.util.Set;
2124
import java.util.stream.Collectors;
25+
import java.util.stream.Stream;
2226
import org.gradle.api.Plugin;
2327
import org.gradle.api.Project;
2428
import org.gradle.api.Task;
@@ -41,12 +45,33 @@
4145
* <p><strong>Prepare a release</strong>
4246
*
4347
* <pre>
48+
* ./gradlew -PpublishConfigFilePath=release.cfg
49+
* -PpublishMode=(RELEASE|SNAPSHOT) \
50+
* firebasePublish
51+
* </pre>
52+
*
53+
* <pre>
4454
* ./gradlew -PprojectsToPublish="firebase-inappmessaging,firebase-inappmessaging-display"\
4555
* -PpublishMode=(RELEASE|SNAPSHOT) \
4656
* firebasePublish
4757
* </pre>
4858
*
4959
* <ul>
60+
* <li>{@code publishConfigFilePath} is the path to the configuration file from which to read the
61+
* list of projects to release. The file format should be consistent with Python's
62+
* configparser, and the list of projects should be in a section called "modules". If both
63+
* this, and {@code projectsToPublish} are specified, this property takes precedence. <br>
64+
* <br>
65+
* Example config file content:
66+
* <pre>
67+
* [release]
68+
* name = M126
69+
* ...
70+
* [modules]
71+
* firebase-database
72+
* firebase-common
73+
* firebase-firestore
74+
* </pre>
5075
* <li>{@code projectsToPublish} is a list of projects to release separated by {@code
5176
* projectsToPublishSeparator}(default: ","), these projects will have their versions depend
5277
* on the {@code publishMode} parameter.
@@ -73,6 +98,7 @@ public PublishingPlugin() {}
7398
public void apply(Project project) {
7499
String projectNamesToPublish = getPropertyOr(project, "projectsToPublish", "");
75100
String projectsToPublishSeparator = getPropertyOr(project, "projectsToPublishSeparator", ",");
101+
String publishConfigFilePath = getPropertyOr(project, "publishConfigFilePath", "");
76102
Mode publishMode = Enum.valueOf(Mode.class, getPropertyOr(project, "publishMode", "SNAPSHOT"));
77103

78104
Task publishAllToLocal = project.task("publishAllToLocal");
@@ -83,8 +109,16 @@ public void apply(Project project) {
83109
.getGradle()
84110
.projectsEvaluated(
85111
gradle -> {
112+
List<String> projectsNames;
113+
if (!publishConfigFilePath.isEmpty()) {
114+
projectsNames = readReleaseConfigFile(publishConfigFilePath);
115+
} else {
116+
projectsNames =
117+
List.of(projectNamesToPublish.split(projectsToPublishSeparator, -1));
118+
}
119+
86120
Set<FirebaseLibraryExtension> projectsToPublish =
87-
Arrays.stream(projectNamesToPublish.split(projectsToPublishSeparator, -1))
121+
projectsNames.stream()
88122
.filter(name -> !name.isEmpty())
89123
.map(
90124
name ->
@@ -194,6 +228,19 @@ public void apply(Project project) {
194228
});
195229
}
196230

231+
private List<String> readReleaseConfigFile(String publishConfigurationFilePath) {
232+
try (Stream<String> stream = Files.lines(Path.of(publishConfigurationFilePath))) {
233+
return stream
234+
.dropWhile((line) -> !line.equals("[modules]"))
235+
// We need to skip the "[modules]" line since it's not dropped
236+
.skip(1)
237+
.collect(Collectors.toList());
238+
} catch (IOException e) {
239+
throw new IllegalArgumentException(
240+
"Error reading configuration file " + publishConfigurationFilePath, e);
241+
}
242+
}
243+
197244
private static String getPropertyOr(Project p, String property, String defaultValue) {
198245
Object value = p.findProperty(property);
199246
if (value != null) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"settings_version": 3,
3+
"cache_duration": 7200,
4+
"features": {
5+
"collect_logged_exceptions": true,
6+
"collect_reports": true,
7+
"collect_anrs": true,
8+
"collect_build_ids": true
9+
},
10+
"app": {
11+
"status": "activated",
12+
"update_required": true,
13+
"report_upload_variant": 2,
14+
"native_report_upload_variant": 2
15+
},
16+
"fabric": {
17+
"org_id": "6001bf51c0329dc5da694f7f",
18+
"bundle_id": "com.google.firebase.crashlytics.sdk.test"
19+
}
20+
}

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/CommonUtilsTest.java

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import android.util.Log;
2828
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
2929
import com.google.firebase.crashlytics.internal.Logger;
30+
import java.util.ArrayList;
31+
import java.util.Arrays;
3032
import java.util.HashMap;
33+
import java.util.List;
3134
import java.util.Map;
3235

3336
public class CommonUtilsTest extends CrashlyticsTestCase {
@@ -278,6 +281,82 @@ public void testResolveBuildId_bothIds() throws Exception {
278281
});
279282
}
280283

284+
public void testResolveNativeBuildIds_missing_returnsEmptyList() {
285+
assertNativeBuildIds(new ArrayList<BuildIdInfo>(), new HashMap<String, List<String>>());
286+
}
287+
288+
public void testResolveNativeBuildIds_missingResourceArray_returnsEmptyList() {
289+
assertNativeBuildIds(
290+
new ArrayList<BuildIdInfo>(),
291+
new HashMap<String, List<String>>() {
292+
{
293+
put(
294+
CommonUtils.BUILD_IDS_LIB_NAMES_RESOURCE_NAME,
295+
new ArrayList<String>(Arrays.asList("lib.so")));
296+
put(
297+
CommonUtils.BUILD_IDS_BUILD_ID_RESOURCE_NAME,
298+
new ArrayList<String>(Arrays.asList("aabb")));
299+
}
300+
});
301+
}
302+
303+
public void testResolveNativeBuildIds_returnsSingleLibrary() {
304+
assertNativeBuildIds(
305+
new ArrayList<BuildIdInfo>(Arrays.asList(new BuildIdInfo("lib.so", "x86", "aabb"))),
306+
new HashMap<String, List<String>>() {
307+
{
308+
put(
309+
CommonUtils.BUILD_IDS_LIB_NAMES_RESOURCE_NAME,
310+
new ArrayList<String>(Arrays.asList("lib.so")));
311+
put(
312+
CommonUtils.BUILD_IDS_ARCH_RESOURCE_NAME,
313+
new ArrayList<String>(Arrays.asList("x86")));
314+
put(
315+
CommonUtils.BUILD_IDS_BUILD_ID_RESOURCE_NAME,
316+
new ArrayList<String>(Arrays.asList("aabb")));
317+
}
318+
});
319+
}
320+
321+
public void testResolveNativeBuildIds_returnsMultipleLibrary() {
322+
assertNativeBuildIds(
323+
new ArrayList<BuildIdInfo>(
324+
Arrays.asList(
325+
new BuildIdInfo("lib.so", "x86", "aabb"),
326+
new BuildIdInfo("lib.so", "x86_64", "bbaa"))),
327+
new HashMap<String, List<String>>() {
328+
{
329+
put(
330+
CommonUtils.BUILD_IDS_LIB_NAMES_RESOURCE_NAME,
331+
new ArrayList<String>(Arrays.asList("lib.so", "lib.so")));
332+
put(
333+
CommonUtils.BUILD_IDS_ARCH_RESOURCE_NAME,
334+
new ArrayList<String>(Arrays.asList("x86", "x86_64")));
335+
put(
336+
CommonUtils.BUILD_IDS_BUILD_ID_RESOURCE_NAME,
337+
new ArrayList<String>(Arrays.asList("aabb", "bbaa")));
338+
}
339+
});
340+
}
341+
342+
public void testResolveNativeBuildIds_mismatchedArray_returnsEmptyList() {
343+
assertNativeBuildIds(
344+
new ArrayList<BuildIdInfo>(),
345+
new HashMap<String, List<String>>() {
346+
{
347+
put(
348+
CommonUtils.BUILD_IDS_LIB_NAMES_RESOURCE_NAME,
349+
new ArrayList<String>(Arrays.asList("lib.so", "lib.so")));
350+
put(
351+
CommonUtils.BUILD_IDS_ARCH_RESOURCE_NAME,
352+
new ArrayList<String>(Arrays.asList("x86")));
353+
put(
354+
CommonUtils.BUILD_IDS_BUILD_ID_RESOURCE_NAME,
355+
new ArrayList<String>(Arrays.asList("aabb", "baab")));
356+
}
357+
});
358+
}
359+
281360
private void assertBuildId(String expectedValue, Map<String, String> buildIds) {
282361
final Context mockContext = mock(Context.class);
283362
final Context mockAppContext = mock(Context.class);
@@ -303,6 +382,40 @@ private void assertBuildId(String expectedValue, Map<String, String> buildIds) {
303382
assertEquals(expectedValue, CommonUtils.getMappingFileId(mockContext));
304383
}
305384

385+
private void assertNativeBuildIds(
386+
ArrayList<BuildIdInfo> expected, Map<String, List<String>> nativeBuildIds) {
387+
final Context mockContext = mock(Context.class);
388+
final Context mockAppContext = mock(Context.class);
389+
final Resources mockResources = mock(Resources.class);
390+
391+
final String packageName = "package.name";
392+
final ApplicationInfo info = new ApplicationInfo();
393+
info.icon = 0;
394+
395+
when(mockContext.getResources()).thenReturn(mockResources);
396+
when(mockContext.getApplicationContext()).thenReturn(mockAppContext);
397+
398+
when(mockAppContext.getApplicationInfo()).thenReturn(info);
399+
when(mockContext.getPackageName()).thenReturn(packageName);
400+
401+
int id = -1;
402+
when(mockResources.getIdentifier(anyString(), anyString(), anyString())).thenReturn(++id);
403+
for (String buildIdKey : nativeBuildIds.keySet()) {
404+
when(mockResources.getIdentifier(buildIdKey, "array", packageName)).thenReturn(++id);
405+
when(mockResources.getStringArray(eq(id)))
406+
.thenReturn(nativeBuildIds.get(buildIdKey).toArray(new String[] {}));
407+
}
408+
List<BuildIdInfo> output = CommonUtils.getBuildIdInfo(mockContext);
409+
assertEquals(output.size(), expected.size());
410+
for (int i = 0; i < expected.size(); i++) {
411+
BuildIdInfo expectedBuildIdInfo = expected.get(i);
412+
BuildIdInfo outputBuildIdInfo = output.get(i);
413+
assertEquals(expectedBuildIdInfo.getLibraryName(), outputBuildIdInfo.getLibraryName());
414+
assertEquals(expectedBuildIdInfo.getArch(), outputBuildIdInfo.getArch());
415+
assertEquals(expectedBuildIdInfo.getBuildId(), outputBuildIdInfo.getBuildId());
416+
}
417+
}
418+
306419
private Context mockPermissionContext(boolean isGranted) {
307420
Context mockContext = mock(Context.class);
308421
when(mockContext.checkCallingOrSelfPermission(anyString()))

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/CrashlyticsControllerTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.google.firebase.crashlytics.internal.settings.TestSettings;
4545
import com.google.firebase.installations.FirebaseInstallationsApi;
4646
import java.io.File;
47+
import java.util.ArrayList;
4748
import java.util.Arrays;
4849
import java.util.Collections;
4950
import java.util.List;
@@ -135,10 +136,13 @@ public CrashlyticsController build() {
135136
CrashlyticsFileMarker crashMarker =
136137
new CrashlyticsFileMarker(CrashlyticsCore.CRASH_MARKER_FILE_NAME, testFileStore);
137138

139+
List<BuildIdInfo> buildIdInfoList = new ArrayList<>();
140+
buildIdInfoList.add(new BuildIdInfo("lib.so", "x86", "aabb"));
138141
AppData appData =
139142
new AppData(
140143
GOOGLE_APP_ID,
141144
"buildId",
145+
buildIdInfoList,
142146
"installerPackageName",
143147
"packageName",
144148
"versionCode",

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/CrashlyticsCoreInitializationTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import com.google.firebase.installations.FirebaseInstallationsApi;
4242
import java.io.File;
4343
import java.io.IOException;
44+
import java.util.ArrayList;
45+
import java.util.List;
4446
import java.util.concurrent.ExecutorService;
4547

4648
public class CrashlyticsCoreInitializationTest extends CrashlyticsTestCase {
@@ -256,10 +258,13 @@ private void setupBuildIdRequired(String booleanValue) {
256258
}
257259

258260
private void setupAppData(String buildId) {
261+
List<BuildIdInfo> buildIdInfoList = new ArrayList<>();
262+
buildIdInfoList.add(new BuildIdInfo("lib.so", "x86", "aabb"));
259263
appData =
260264
new AppData(
261265
GOOGLE_APP_ID,
262266
buildId,
267+
buildIdInfoList,
263268
"installerPackageName",
264269
"packageName",
265270
"versionCode",

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/CrashlyticsCoreTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
import com.google.firebase.crashlytics.internal.settings.TestSettings;
4545
import com.google.firebase.inject.Deferred;
4646
import com.google.firebase.installations.FirebaseInstallationsApi;
47+
import java.util.ArrayList;
4748
import java.util.HashMap;
49+
import java.util.List;
4850
import java.util.Map;
4951
import java.util.concurrent.TimeUnit;
5052
import org.mockito.Mockito;
@@ -343,10 +345,13 @@ private Task<CrashlyticsCore> startCoreAsync(CrashlyticsCore crashlyticsCore) {
343345
when(mockSettingsController.getSettingsSync()).thenReturn(settings);
344346
when(mockSettingsController.getSettingsAsync()).thenReturn(Tasks.forResult(settings));
345347

348+
List<BuildIdInfo> buildIdInfoList = new ArrayList<>();
349+
buildIdInfoList.add(new BuildIdInfo("lib.so", "x86", "aabb"));
346350
AppData appData =
347351
new AppData(
348352
GOOGLE_APP_ID,
349353
"buildId",
354+
buildIdInfoList,
350355
"installerPackageName",
351356
"packageName",
352357
"versionCode",

0 commit comments

Comments
 (0)