Unverified Commit 3af7f9be authored by Felix Angelov's avatar Felix Angelov Committed by GitHub

fix(flutter_tools): `findBundleFile` w/multiple flavor dimensions (#127133)

Fixes the `findBundleFile` method in `gradle.dart` to correctly locate app bundles generated from multiple flavor dimensions.

- closes https://github.com/flutter/flutter/issues/92316
- closes https://github.com/flutter/flutter/issues/65264
parent 0d67c7e1
......@@ -983,6 +983,22 @@ File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger,
fileCandidates.add(getBundleDirectory(project)
.childDirectory('${buildInfo.uncapitalizedFlavor}${camelCase('_${buildInfo.modeName}')}')
.childFile('app-${buildInfo.uncapitalizedFlavor}-${buildInfo.modeName}.aab'));
// The Android Gradle plugin uses kebab-case and lowercases the first character of the flavor name
// when multiple flavor dimensions are used:
// e.g.
// flavorDimensions "dimension1","dimension2"
// productFlavors {
// foo {
// dimension "dimension1"
// }
// bar {
// dimension "dimension2"
// }
// }
fileCandidates.add(getBundleDirectory(project)
.childDirectory('${buildInfo.uncapitalizedFlavor}${camelCase('_${buildInfo.modeName}')}')
.childFile('app-${kebabCase(buildInfo.uncapitalizedFlavor!)}-${buildInfo.modeName}.aab'));
}
for (final File bundleFile in fileCandidates) {
if (bundleFile.existsSync()) {
......
......@@ -26,6 +26,11 @@ String camelCase(String str) {
return str;
}
/// Convert `fooBar` to `foo-bar`.
String kebabCase(String str) {
return snakeCase(str, '-');
}
final RegExp _upperRegex = RegExp(r'[A-Z]');
/// Convert `fooBar` to `foo_bar`.
......
......@@ -19,6 +19,19 @@ void main() {
fileSystem = MemoryFileSystem.test();
});
testWithoutContext('Finds app bundle when flavor contains multiple dimensions in release mode', () {
final FlutterProject project = generateFakeAppBundle('fooBarRelease', 'app-foo-bar-release.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'fooBar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, '/build/app/outputs/bundle/fooBarRelease/app-foo-bar-release.aab');
});
testWithoutContext('Finds app bundle when flavor contains underscores in release mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(
......@@ -84,6 +97,19 @@ void main() {
expect(bundle.path, '/build/app/outputs/bundle/release/app.aab');
});
testWithoutContext('Finds app bundle when flavor contains multiple dimensions in debug mode', () {
final FlutterProject project = generateFakeAppBundle('fooBarDebug', 'app-foo-bar-debug.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'fooBar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, '/build/app/outputs/bundle/fooBarDebug/app-foo-bar-debug.aab');
});
testWithoutContext('Finds app bundle when flavor contains underscores in debug mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(
......@@ -149,6 +175,19 @@ void main() {
expect(bundle.path, '/build/app/outputs/bundle/debug/app.aab');
});
testWithoutContext('Finds app bundle when flavor contains multiple dimensions in profile mode', () {
final FlutterProject project = generateFakeAppBundle('fooBarProfile', 'app-foo-bar-profile.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, 'fooBar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, '/build/app/outputs/bundle/fooBarProfile/app-foo-bar-profile.aab');
});
testWithoutContext('Finds app bundle when flavor contains underscores in profile mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(
......
......@@ -120,6 +120,17 @@ baz=qux
expect(snakeCase('ABC'), equals('a_b_c'));
});
testWithoutContext('kebabCase', () async {
expect(kebabCase('abc'), equals('abc'));
expect(kebabCase('abC'), equals('ab-c'));
expect(kebabCase('aBc'), equals('a-bc'));
expect(kebabCase('aBC'), equals('a-b-c'));
expect(kebabCase('Abc'), equals('abc'));
expect(kebabCase('AbC'), equals('ab-c'));
expect(kebabCase('ABc'), equals('a-bc'));
expect(kebabCase('ABC'), equals('a-b-c'));
});
testWithoutContext('sentenceCase', () async {
expect(sentenceCase('abc'), equals('Abc'));
expect(sentenceCase('ab_c'), equals('Ab_c'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment