Commit c50fa3d2 authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by Todd Volkert

Re-land config lib dependencies for flavors (#34668)

parent 4f5d9013
...@@ -7,19 +7,26 @@ import 'dart:async'; ...@@ -7,19 +7,26 @@ import 'dart:async';
import 'package:flutter_devicelab/framework/apk_utils.dart'; import 'package:flutter_devicelab/framework/apk_utils.dart';
import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart'; import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;
Future<void> main() async { Future<void> main() async {
await task(() async { await task(() async {
try { try {
await runPluginProjectTest((FlutterPluginProject pluginProject) async { await runProjectTest((FlutterProject project) async {
section('App bundle content for task bundleRelease without explicit target platform'); section('App bundle content for task bundleRelease without explicit target platform');
await pluginProject.runGradleTask('bundleRelease'); await project.runGradleTask('bundleRelease');
if (!pluginProject.hasReleaseBundle) final String releaseBundle = path.join(
throw TaskResult.failure( project.rootPath,
'Gradle did not produce a release aab file at: ${pluginProject.releaseBundlePath}'); 'build',
'app',
'outputs',
'bundle',
'release',
'app.aab',
);
final Iterable<String> bundleFiles = await pluginProject.getFilesInAppBundle(pluginProject.releaseBundlePath); final Iterable<String> bundleFiles = await getFilesInAppBundle(releaseBundle);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'base/manifest/AndroidManifest.xml', 'base/manifest/AndroidManifest.xml',
...@@ -31,16 +38,51 @@ Future<void> main() async { ...@@ -31,16 +38,51 @@ Future<void> main() async {
], bundleFiles); ], bundleFiles);
}); });
await runPluginProjectTest((FlutterPluginProject pluginProject) async { await runProjectTest((FlutterProject project) async {
section('App bundle content using flavors without explicit target platform');
// Add a few flavors.
await project.addProductFlavors(<String> ['production', 'staging', 'development']);
// Build the production flavor in release mode.
await project.runGradleTask('bundleProductionRelease');
final String bundlePath = path.join(
project.rootPath,
'build',
'app',
'outputs',
'bundle',
'productionRelease',
'app.aab',
);
final Iterable<String> bundleFiles = await getFilesInAppBundle(bundlePath);
checkItContains<String>(<String>[
'base/manifest/AndroidManifest.xml',
'base/dex/classes.dex',
'base/lib/arm64-v8a/libapp.so',
'base/lib/arm64-v8a/libflutter.so',
'base/lib/armeabi-v7a/libapp.so',
'base/lib/armeabi-v7a/libflutter.so',
], bundleFiles);
});
await runProjectTest((FlutterProject project) async {
section('App bundle content for task bundleRelease with target platform = android-arm'); section('App bundle content for task bundleRelease with target platform = android-arm');
await pluginProject.runGradleTask('bundleRelease', await project.runGradleTask('bundleRelease',
options: <String>['-Ptarget-platform=android-arm']); options: <String>['-Ptarget-platform=android-arm']);
if (!pluginProject.hasReleaseBundle) final String releaseBundle = path.join(
throw TaskResult.failure( project.rootPath,
'Gradle did not produce a release aab file at: ${pluginProject.releaseBundlePath}'); 'build',
'app',
'outputs',
'bundle',
'release',
'app.aab',
);
final Iterable<String> bundleFiles = await pluginProject.getFilesInAppBundle(pluginProject.releaseBundlePath); final Iterable<String> bundleFiles = await getFilesInAppBundle(releaseBundle);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'base/manifest/AndroidManifest.xml', 'base/manifest/AndroidManifest.xml',
......
...@@ -17,11 +17,7 @@ Future<void> main() async { ...@@ -17,11 +17,7 @@ Future<void> main() async {
section('APK content for task assembleDebug without explicit target platform'); section('APK content for task assembleDebug without explicit target platform');
await pluginProject.runGradleTask('assembleDebug'); await pluginProject.runGradleTask('assembleDebug');
if (!pluginProject.hasDebugApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
throw TaskResult.failure(
'Gradle did not produce a debug apk file at: ${pluginProject.debugApkPath}');
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -48,11 +44,7 @@ Future<void> main() async { ...@@ -48,11 +44,7 @@ Future<void> main() async {
section('APK content for task assembleRelease without explicit target platform'); section('APK content for task assembleRelease without explicit target platform');
await pluginProject.runGradleTask('assembleRelease'); await pluginProject.runGradleTask('assembleRelease');
if (!pluginProject.hasReleaseApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk file at: ${pluginProject.releaseApkPath}');
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -75,11 +67,7 @@ Future<void> main() async { ...@@ -75,11 +67,7 @@ Future<void> main() async {
await pluginProject.runGradleTask('assembleRelease', await pluginProject.runGradleTask('assembleRelease',
options: <String>['-Ptarget-platform=android-arm,android-arm64']); options: <String>['-Ptarget-platform=android-arm,android-arm64']);
if (!pluginProject.hasReleaseApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk at: ${pluginProject.releaseApkPath}');
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -103,11 +91,7 @@ Future<void> main() async { ...@@ -103,11 +91,7 @@ Future<void> main() async {
await pluginProject.runGradleTask('assembleRelease', await pluginProject.runGradleTask('assembleRelease',
options: <String>['-Ptarget-platform=android-arm,android-arm64', '-Psplit-per-abi=true']); options: <String>['-Ptarget-platform=android-arm,android-arm64', '-Psplit-per-abi=true']);
if (!pluginProject.hasReleaseArmApk) final Iterable<String> armApkFiles = await getFilesInApk(pluginProject.releaseArmApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk at: ${pluginProject.releaseArmApkPath}');
final Iterable<String> armApkFiles = await pluginProject.getFilesInApk(pluginProject.releaseArmApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -122,11 +106,7 @@ Future<void> main() async { ...@@ -122,11 +106,7 @@ Future<void> main() async {
'assets/flutter_assets/vm_snapshot_data', 'assets/flutter_assets/vm_snapshot_data',
], armApkFiles); ], armApkFiles);
if (!pluginProject.hasReleaseArm64Apk) final Iterable<String> arm64ApkFiles = await getFilesInApk(pluginProject.releaseArm64ApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk at: ${pluginProject.releaseArm64ApkPath}');
final Iterable<String> arm64ApkFiles = await pluginProject.getFilesInApk(pluginProject.releaseArm64ApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
......
...@@ -17,11 +17,61 @@ Future<void> main() async { ...@@ -17,11 +17,61 @@ Future<void> main() async {
await pluginProject.runGradleTask('assembleDebug', await pluginProject.runGradleTask('assembleDebug',
options: <String>['-Ptarget-platform=android-arm']); options: <String>['-Ptarget-platform=android-arm']);
if (!pluginProject.hasDebugApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
throw TaskResult.failure(
'Gradle did not produce a debug apk file at: ${pluginProject.debugApkPath}'); checkItContains<String>(<String>[
'AndroidManifest.xml',
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
'assets/flutter_assets/vm_snapshot_data',
'lib/armeabi-v7a/libflutter.so',
// Debug mode intentionally includes `x86` and `x86_64`.
'lib/x86/libflutter.so',
'lib/x86_64/libflutter.so',
], apkFiles);
checkItDoesNotContain<String>(<String>[
'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so',
'lib/x86_64/libapp.so',
], apkFiles);
});
await runPluginProjectTest((FlutterPluginProject pluginProject) async {
section('APK content for task assembleDebug with target platform = android-x86');
// This is used by `flutter run`
await pluginProject.runGradleTask('assembleDebug',
options: <String>['-Ptarget-platform=android-x86']);
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
'assets/flutter_assets/vm_snapshot_data',
'lib/armeabi-v7a/libflutter.so',
// Debug mode intentionally includes `x86` and `x86_64`.
'lib/x86/libflutter.so',
'lib/x86_64/libflutter.so',
], apkFiles);
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.debugApkPath); checkItDoesNotContain<String>(<String>[
'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so',
'lib/x86_64/libapp.so',
], apkFiles);
});
await runPluginProjectTest((FlutterPluginProject pluginProject) async {
section('APK content for task assembleDebug with target platform = android-x64');
// This is used by `flutter run`
await pluginProject.runGradleTask('assembleDebug',
options: <String>['-Ptarget-platform=android-x64']);
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -47,11 +97,7 @@ Future<void> main() async { ...@@ -47,11 +97,7 @@ Future<void> main() async {
await pluginProject.runGradleTask('assembleRelease', await pluginProject.runGradleTask('assembleRelease',
options: <String>['-Ptarget-platform=android-arm']); options: <String>['-Ptarget-platform=android-arm']);
if (!pluginProject.hasReleaseApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk file at: ${pluginProject.releaseApkPath}');
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -74,11 +120,7 @@ Future<void> main() async { ...@@ -74,11 +120,7 @@ Future<void> main() async {
await pluginProject.runGradleTask('assembleRelease', await pluginProject.runGradleTask('assembleRelease',
options: <String>['-Ptarget-platform=android-arm64']); options: <String>['-Ptarget-platform=android-arm64']);
if (!pluginProject.hasReleaseApk) final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
throw TaskResult.failure(
'Gradle did not produce a release apk file at: ${pluginProject.releaseApkPath}');
final Iterable<String> apkFiles = await pluginProject.getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkItContains<String>(<String>[
'AndroidManifest.xml', 'AndroidManifest.xml',
...@@ -124,7 +166,7 @@ Future<void> main() async { ...@@ -124,7 +166,7 @@ Future<void> main() async {
await runProjectTest((FlutterProject project) async { await runProjectTest((FlutterProject project) async {
section('gradlew assembleFreeDebug (product flavor)'); section('gradlew assembleFreeDebug (product flavor)');
await project.addProductFlavor('free'); await project.addProductFlavors(<String>['free']);
await project.runGradleTask('assembleFreeDebug'); await project.runGradleTask('assembleFreeDebug');
}); });
...@@ -169,7 +211,7 @@ Future<void> main() async { ...@@ -169,7 +211,7 @@ Future<void> main() async {
await runPluginProjectTest((FlutterPluginProject pluginProject) async { await runPluginProjectTest((FlutterPluginProject pluginProject) async {
section('gradlew assembleDebug on plugin example'); section('gradlew assembleDebug on plugin example');
await pluginProject.runGradleTask('assembleDebug'); await pluginProject.runGradleTask('assembleDebug');
if (!pluginProject.hasDebugApk) if (!File(pluginProject.debugApkPath).existsSync())
throw TaskResult.failure( throw TaskResult.failure(
'Gradle did not produce an apk file at the expected place'); 'Gradle did not produce an apk file at the expected place');
}); });
......
...@@ -34,6 +34,27 @@ Future<void> runPluginProjectTest(Future<void> testFunction(FlutterPluginProject ...@@ -34,6 +34,27 @@ Future<void> runPluginProjectTest(Future<void> testFunction(FlutterPluginProject
} }
} }
Future<Iterable<String>> getFilesInApk(String apk) async {
if (!File(apk).existsSync())
throw TaskResult.failure(
'Gradle did not produce an output artifact file at: $apk');
final Process unzip = await startProcess(
'unzip',
<String>['-v', apk],
isBot: false, // we just want to test the output, not have any debugging info
);
return unzip.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.map((String line) => line.split(' ').last)
.toList();
}
Future<Iterable<String>> getFilesInAppBundle(String bundle) {
return getFilesInApk(bundle);
}
void checkItContains<T>(Iterable<T> values, Iterable<T> collection) { void checkItContains<T>(Iterable<T> values, Iterable<T> collection) {
for (T value in values) { for (T value in values) {
if (!collection.contains(value)) { if (!collection.contains(value)) {
...@@ -95,20 +116,25 @@ android { ...@@ -95,20 +116,25 @@ android {
'''); ''');
} }
Future<void> addProductFlavor(String name) async { Future<void> addProductFlavors(Iterable<String> flavors) async {
final File buildScript = File( final File buildScript = File(
path.join(androidPath, 'app', 'build.gradle'), path.join(androidPath, 'app', 'build.gradle'),
); );
buildScript.openWrite(mode: FileMode.append).write(''' final String flavorConfig = flavors.map((String name) {
return '''
$name {
applicationIdSuffix ".$name"
versionNameSuffix "-$name"
}
''';
}).join('\n');
buildScript.openWrite(mode: FileMode.append).write('''
android { android {
flavorDimensions "mode" flavorDimensions "mode"
productFlavors { productFlavors {
$name { $flavorConfig
applicationIdSuffix ".$name"
versionNameSuffix "-$name"
}
} }
} }
'''); ''');
...@@ -160,32 +186,9 @@ class FlutterPluginProject { ...@@ -160,32 +186,9 @@ class FlutterPluginProject {
String get releaseArm64ApkPath => path.join(examplePath, 'build', 'app', 'outputs', 'apk', 'release', 'app-arm64-v8a-release.apk'); String get releaseArm64ApkPath => path.join(examplePath, 'build', 'app', 'outputs', 'apk', 'release', 'app-arm64-v8a-release.apk');
String get releaseBundlePath => path.join(examplePath, 'build', 'app', 'outputs', 'bundle', 'release', 'app.aab'); String get releaseBundlePath => path.join(examplePath, 'build', 'app', 'outputs', 'bundle', 'release', 'app.aab');
bool get hasDebugApk => File(debugApkPath).existsSync();
bool get hasReleaseApk => File(releaseApkPath).existsSync();
bool get hasReleaseArmApk => File(releaseArmApkPath).existsSync();
bool get hasReleaseArm64Apk => File(releaseArm64ApkPath).existsSync();
bool get hasReleaseBundle => File(releaseBundlePath).existsSync();
Future<void> runGradleTask(String task, {List<String> options}) async { Future<void> runGradleTask(String task, {List<String> options}) async {
return _runGradleTask(workingDirectory: exampleAndroidPath, task: task, options: options); return _runGradleTask(workingDirectory: exampleAndroidPath, task: task, options: options);
} }
Future<Iterable<String>> getFilesInApk(String apk) async {
final Process unzip = await startProcess(
'unzip',
<String>['-v', apk],
isBot: false, // we just want to test the output, not have any debugging info
);
return unzip.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.map((String line) => line.split(' ').last)
.toList();
}
Future<Iterable<String>> getFilesInAppBundle(String bundle) {
return getFilesInApk(bundle);
}
} }
Future<void> _runGradleTask({String workingDirectory, String task, List<String> options}) async { Future<void> _runGradleTask({String workingDirectory, String task, List<String> options}) async {
......
...@@ -114,7 +114,6 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -114,7 +114,6 @@ class FlutterPlugin implements Plugin<Project> {
String abiValue = PLATFORM_ARCH_MAP[targetArch] String abiValue = PLATFORM_ARCH_MAP[targetArch]
project.android { project.android {
packagingOptions { packagingOptions {
pickFirst "lib/${abiValue}/libflutter.so"
// Prevent the ELF library from getting corrupted. // Prevent the ELF library from getting corrupted.
doNotStrip "*/${abiValue}/libapp.so" doNotStrip "*/${abiValue}/libapp.so"
} }
...@@ -166,28 +165,16 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -166,28 +165,16 @@ class FlutterPlugin implements Plugin<Project> {
// The local engine is built for one of the build type. // The local engine is built for one of the build type.
// However, we use the same engine for each of the build types. // However, we use the same engine for each of the build types.
project.android.buildTypes.each { project.android.buildTypes.each {
addApiDependencies(project, it, project.files { addApiDependencies(project, it.name, project.files {
flutterJar flutterJar
}) })
} }
} else { } else {
// x86/x86_64 native library used for debugging only, for now.
File flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
Task debugX86JarTask = project.tasks.create("${FLUTTER_BUILD_PREFIX}X86Jar", Jar) {
destinationDir flutterX86Jar.parentFile
archiveName flutterX86Jar.name
from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libflutter.so") {
into 'lib/x86'
}
from("${flutterRoot}/bin/cache/artifacts/engine/android-x64/libflutter.so") {
into 'lib/x86_64'
}
}
String basePlatformArch = getBasePlatform(project) String basePlatformArch = getBasePlatform(project)
// This is meant to include the compiled classes only, however it will include `libflutter.so` as well. // This is meant to include the compiled classes only, however it will include `libflutter.so` as well.
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine") Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile() File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile()
baseJar["debug"] = [debugX86JarTask, debugJar] baseJar["debug"] = debugJar
if (!debugJar.isFile()) { if (!debugJar.isFile()) {
project.exec { project.exec {
executable flutterExecutable.absolutePath executable flutterExecutable.absolutePath
...@@ -205,13 +192,13 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -205,13 +192,13 @@ class FlutterPlugin implements Plugin<Project> {
// added after applying the Flutter plugin. // added after applying the Flutter plugin.
project.android.buildTypes.each { project.android.buildTypes.each {
def buildMode = buildModeFor(it) def buildMode = buildModeFor(it)
addApiDependencies(project, it, project.files { addApiDependencies(project, it.name, project.files {
baseJar[buildMode] baseJar[buildMode]
}) })
} }
project.android.buildTypes.whenObjectAdded { project.android.buildTypes.whenObjectAdded {
def buildMode = buildModeFor(it) def buildMode = buildModeFor(it)
addApiDependencies(project, it, project.files { addApiDependencies(project, it.name, project.files {
baseJar[buildMode] baseJar[buildMode]
}) })
} }
...@@ -325,7 +312,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -325,7 +312,7 @@ class FlutterPlugin implements Plugin<Project> {
provided project.files(flutterJar) provided project.files(flutterJar)
} }
} else { } else {
assert baseJar["debug"].last().isFile() assert baseJar["debug"].isFile()
assert baseJar["profile"].isFile() assert baseJar["profile"].isFile()
assert baseJar["release"].isFile() assert baseJar["release"].isFile()
...@@ -342,14 +329,14 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -342,14 +329,14 @@ class FlutterPlugin implements Plugin<Project> {
} }
} }
private static void addApiDependencies(Project project, buildType, FileCollection files) { private static void addApiDependencies(Project project, String variantName, FileCollection files) {
project.dependencies { project.dependencies {
String configuration; String configuration;
// `compile` dependencies are now `api` dependencies. // `compile` dependencies are now `api` dependencies.
if (project.getConfigurations().findByName("api")) { if (project.getConfigurations().findByName("api")) {
configuration = buildType.name + "Api"; configuration = "${variantName}Api";
} else { } else {
configuration = buildType.name + "Compile"; configuration = "${variantName}Compile";
} }
add(configuration, files) add(configuration, files)
} }
...@@ -494,10 +481,16 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -494,10 +481,16 @@ class FlutterPlugin implements Plugin<Project> {
flutterTasks.add(compileTask) flutterTasks.add(compileTask)
} }
def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar") def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
def libFlutterPlatforms = targetPlatforms.collect()
// x86/x86_64 native library used for debugging only, for now.
if (flutterBuildMode == 'debug') {
libFlutterPlatforms.add('android-x86')
libFlutterPlatforms.add('android-x64')
}
Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) { Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
destinationDir libJar.parentFile destinationDir libJar.parentFile
archiveName libJar.name archiveName libJar.name
targetPlatforms.each { targetArch -> libFlutterPlatforms.each { targetArch ->
// This check prevents including `libflutter.so` twice, since it's included in the base platform jar. // This check prevents including `libflutter.so` twice, since it's included in the base platform jar.
// Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter` // Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter`
// is included as an implementation dependency, which causes duplicated `libflutter.so`. // is included as an implementation dependency, which causes duplicated `libflutter.so`.
...@@ -527,7 +520,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -527,7 +520,7 @@ class FlutterPlugin implements Plugin<Project> {
} }
} }
// Include the snapshots and libflutter.so in `lib/`. // Include the snapshots and libflutter.so in `lib/`.
addApiDependencies(project, buildType, project.files { addApiDependencies(project, variant.name, project.files {
packFlutterSnapshotsAndLibsTask packFlutterSnapshotsAndLibsTask
}) })
......
...@@ -585,8 +585,12 @@ File _findBundleFile(GradleProject project, BuildInfo buildInfo) { ...@@ -585,8 +585,12 @@ File _findBundleFile(GradleProject project, BuildInfo buildInfo) {
if (bundleFile.existsSync()) if (bundleFile.existsSync())
return bundleFile; return bundleFile;
if (buildInfo.flavor != null) { if (buildInfo.flavor != null) {
// Android Studio Gradle plugin v3 adds the flavor to the path. For the bundle the folder name is the flavor plus the mode name. // Android Studio Gradle plugin v3 adds the flavor to the path. For the bundle the folder name is the flavor plus the mode name.
bundleFile = project.bundleDirectory.childDirectory(buildInfo.flavor + modeName).childFile(bundleFileName); // On linux, filenames are case sensitive.
bundleFile = project.bundleDirectory
.childDirectory(camelCase('${buildInfo.flavor}_$modeName'))
.childFile(bundleFileName);
if (bundleFile.existsSync()) if (bundleFile.existsSync())
return bundleFile; return bundleFile;
} }
......
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