[flutter_tools] remove global usage of flutterUsage from gradle (#76330)

This commit is contained in:
Jonah Williams 2021-02-18 15:52:00 -08:00 committed by GitHub
parent 050d49ae42
commit 6b14558a68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 425 additions and 262 deletions

View file

@ -22,7 +22,7 @@ import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../flutter_manifest.dart';
import '../globals.dart' as globals hide logger, printStatus, printTrace, printError, processManager, processUtils, fs, artifacts;
import '../globals.dart' as globals hide logger, printStatus, printTrace, printError, processManager, processUtils, fs, artifacts, flutterUsage;
import '../project.dart';
import '../reporting/reporting.dart';
import 'android_builder.dart';
@ -129,14 +129,6 @@ bool _isSupportedVersion(AndroidProject project) {
return false;
}
/// Returns the apk file created by [buildGradleProject]
Future<File> getGradleAppOut(AndroidProject androidProject) async {
if (!_isSupportedVersion(androidProject)) {
_exitWithUnsupportedProjectMessage();
}
return getApkDirectory(androidProject.parent).childFile('app.apk');
}
/// Runs `gradlew dependencies`, ensuring that dependencies are resolved and
/// potentially downloaded.
Future<void> checkGradleDependencies(Logger logger, ProcessUtils processUtils) async {
@ -217,15 +209,18 @@ class AndroidGradleBuilder implements AndroidBuilder {
@required ProcessManager processManager,
@required FileSystem fileSystem,
@required Artifacts artifacts,
@required Usage usage,
}) : _logger = logger,
_fileSystem = fileSystem,
_artifacts = artifacts,
_usage = usage,
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
final Logger _logger;
final ProcessUtils _processUtils;
final FileSystem _fileSystem;
final Artifacts _artifacts;
final Usage _usage;
/// Builds the AAR and POM files for the current Flutter module or plugin.
@override
@ -336,18 +331,18 @@ class AndroidGradleBuilder implements AndroidBuilder {
assert(globals.androidSdk != null);
if (!project.android.isUsingGradle) {
_exitWithProjectNotUsingGradleMessage();
_exitWithProjectNotUsingGradleMessage(_usage);
}
if (!_isSupportedVersion(project.android)) {
_exitWithUnsupportedProjectMessage();
_exitWithUnsupportedProjectMessage(_usage);
}
final Directory buildDirectory = project.android.buildDirectory;
final bool usesAndroidX = isAppUsingAndroidX(project.android.hostAppGradleRoot);
if (usesAndroidX) {
BuildEvent('app-using-android-x', flutterUsage: globals.flutterUsage).send();
BuildEvent('app-using-android-x', flutterUsage: _usage).send();
} else if (!usesAndroidX) {
BuildEvent('app-not-using-android-x', flutterUsage: globals.flutterUsage).send();
BuildEvent('app-not-using-android-x', flutterUsage: _usage).send();
_logger.printStatus("$warningMark Your app isn't using AndroidX.", emphasis: true);
_logger.printStatus(
'To avoid potential build failures, you can quickly migrate your app '
@ -488,11 +483,11 @@ class AndroidGradleBuilder implements AndroidBuilder {
status.stop();
}
globals.flutterUsage.sendTiming('build', 'gradle', sw.elapsed);
_usage.sendTiming('build', 'gradle', sw.elapsed);
if (exitCode != 0) {
if (detectedGradleError == null) {
BuildEvent('gradle-unknown-failure', flutterUsage: globals.flutterUsage).send();
BuildEvent('gradle-unknown-failure', flutterUsage: _usage).send();
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
@ -518,7 +513,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
shouldBuildPluginAsAar: shouldBuildPluginAsAar,
retries: retries - 1,
);
BuildEvent(successEventLabel, flutterUsage: globals.flutterUsage).send();
BuildEvent(successEventLabel, flutterUsage: _usage).send();
return;
case GradleBuildStatus.retryWithAarPlugins:
await buildGradleApp(
@ -530,13 +525,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
shouldBuildPluginAsAar: true,
retries: retries - 1,
);
BuildEvent(successEventLabel, flutterUsage: globals.flutterUsage).send();
BuildEvent(successEventLabel, flutterUsage: _usage).send();
return;
case GradleBuildStatus.exit:
// noop.
}
}
BuildEvent('gradle-${detectedGradleError.eventLabel}-failure', flutterUsage: globals.flutterUsage).send();
BuildEvent('gradle-${detectedGradleError.eventLabel}-failure', flutterUsage: _usage).send();
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
@ -545,7 +540,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
}
if (isBuildingBundle) {
final File bundleFile = findBundleFile(project, buildInfo, _logger);
final File bundleFile = findBundleFile(project, buildInfo, _logger, _usage);
final String appSize = (buildInfo.mode == BuildMode.debug)
? '' // Don't display the size when building a debug variant.
: ' (${getSizeAsMB(bundleFile.lengthSync())})';
@ -562,7 +557,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
}
// Gradle produced an APK.
final Iterable<String> apkFilesPaths = project.isModule
? findApkFilesModule(project, androidBuildInfo, _logger)
? findApkFilesModule(project, androidBuildInfo, _logger, _usage)
: listApkPaths(androidBuildInfo);
final Directory apkDirectory = getApkDirectory(project);
final File apkFile = apkDirectory.childFile(apkFilesPaths.first);
@ -571,6 +566,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
project: project,
fileExtension: '.apk',
logger: _logger,
usage: _usage,
);
}
@ -603,7 +599,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
final SizeAnalyzer sizeAnalyzer = SizeAnalyzer(
fileSystem: _fileSystem,
logger: _logger,
flutterUsage: globals.flutterUsage,
flutterUsage: _usage,
);
final String archName = getNameForAndroidArch(androidBuildInfo.targetArchs.single);
final BuildInfo buildInfo = androidBuildInfo.buildInfo;
@ -760,7 +756,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
} finally {
status.stop();
}
globals.flutterUsage.sendTiming('build', 'gradle-aar', sw.elapsed);
_usage.sendTiming('build', 'gradle-aar', sw.elapsed);
if (result.exitCode != 0) {
_logger.printStatus(result.stdout, wrap: false);
@ -830,12 +826,11 @@ class AndroidGradleBuilder implements AndroidBuilder {
} on ToolExit {
// Log the entire plugin entry in `.flutter-plugins` since it
// includes the plugin name and the version.
BuildEvent('gradle-plugin-aar-failure', eventError: plugin, flutterUsage: globals.flutterUsage).send();
BuildEvent('gradle-plugin-aar-failure', eventError: plugin, flutterUsage: _usage).send();
throwToolExit('The plugin $pluginName could not be built due to the issue above.');
}
}
}
}
/// Prints how to consume the AAR from a host app.
@ -911,8 +906,8 @@ String _calculateSha(File file) {
return _hex(sha1.convert(bytes).bytes);
}
void _exitWithUnsupportedProjectMessage() {
BuildEvent('unsupported-project', eventError: 'gradle-plugin', flutterUsage: globals.flutterUsage).send();
void _exitWithUnsupportedProjectMessage(Usage usage) {
BuildEvent('unsupported-project', eventError: 'gradle-plugin', flutterUsage: usage).send();
throwToolExit(
'$warningMark Your app is using an unsupported Gradle project. '
'To fix this problem, create a new project by running `flutter create -t app <app-directory>` '
@ -920,8 +915,8 @@ void _exitWithUnsupportedProjectMessage() {
);
}
void _exitWithProjectNotUsingGradleMessage() {
BuildEvent('unsupported-project', eventError: 'app-not-using-gradle', flutterUsage: globals.flutterUsage).send();
void _exitWithProjectNotUsingGradleMessage(Usage usage) {
BuildEvent('unsupported-project', eventError: 'app-not-using-gradle', flutterUsage: usage).send();
throwToolExit(
'$warningMark The build process for Android has changed, and the '
'current project configuration is no longer valid. Please consult\n\n'
@ -930,6 +925,14 @@ void _exitWithProjectNotUsingGradleMessage() {
);
}
/// Returns the apk file created by [buildGradleProject]
Future<File> getGradleAppOut(AndroidProject androidProject, Usage usage) async {
if (!_isSupportedVersion(androidProject)) {
_exitWithUnsupportedProjectMessage(usage);
}
return getApkDirectory(androidProject.parent).childFile('app.apk');
}
/// Returns [true] if the current app uses AndroidX.
// TODO(egarciad): https://github.com/flutter/flutter/issues/40800
// Remove `FlutterManifest.usesAndroidX` and provide a unified `AndroidProject.usesAndroidX`.
@ -947,6 +950,7 @@ Iterable<String> findApkFilesModule(
FlutterProject project,
AndroidBuildInfo androidBuildInfo,
Logger logger,
Usage usage,
) {
final Iterable<String> apkFileNames = _apkFilesFor(androidBuildInfo);
final Directory apkDirectory = getApkDirectory(project);
@ -980,6 +984,7 @@ Iterable<String> findApkFilesModule(
project: project,
fileExtension: '.apk',
logger: logger,
usage: usage,
);
}
return apks.map((File file) => file.path);
@ -1018,7 +1023,7 @@ Iterable<String> listApkPaths(
}
@visibleForTesting
File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger) {
File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger, Usage usage) {
final List<File> fileCandidates = <File>[
getBundleDirectory(project)
.childDirectory(camelCase(buildInfo.modeName))
@ -1053,6 +1058,7 @@ File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger)
project: project,
fileExtension: '.aab',
logger: logger,
usage: usage,
);
return null;
}
@ -1062,6 +1068,7 @@ void _exitWithExpectedFileNotFound({
@required FlutterProject project,
@required String fileExtension,
@required Logger logger,
@required Usage usage,
}) {
assert(project != null);
assert(fileExtension != null);
@ -1072,7 +1079,7 @@ void _exitWithExpectedFileNotFound({
settings:
'androidGradlePluginVersion: $androidGradlePluginVersion, '
'fileExtension: $fileExtension',
flutterUsage: globals.flutterUsage,
flutterUsage: usage,
).send();
throwToolExit(
'Gradle build failed to produce an $fileExtension file. '

View file

@ -221,7 +221,7 @@ class AndroidApk extends ApplicationPackage {
File apkFile;
if (androidProject.isUsingGradle) {
apkFile = await getGradleAppOut(androidProject);
apkFile = await getGradleAppOut(androidProject, globals.flutterUsage);
if (apkFile.existsSync()) {
// Grab information from the .apk. The gradle build script might alter
// the application Id, so we need to look at what was actually built.

View file

@ -84,6 +84,7 @@ Future<T> runInContext<T>(
processManager: globals.processManager,
fileSystem: globals.fs,
artifacts: globals.artifacts,
usage: globals.flutterUsage,
),
AndroidLicenseValidator: () => AndroidLicenseValidator(
operatingSystemUtils: globals.os,

View file

@ -81,6 +81,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -172,6 +173,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -278,6 +280,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -369,6 +372,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(FakeCommand(
command: const <String>[
@ -432,6 +436,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -534,6 +539,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -631,6 +637,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -746,6 +753,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -813,6 +821,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -880,6 +889,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -940,6 +950,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_arm'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1018,6 +1029,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_arm64'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1096,6 +1108,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_x86'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1174,6 +1187,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_x64'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1252,6 +1266,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(),
usage: testUsage,
);
processManager.addCommand(
const FakeCommand(command: <String>[
@ -1311,6 +1326,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_arm'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1400,6 +1416,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_arm64'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1489,6 +1506,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_x86'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[
@ -1578,6 +1596,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
artifacts: Artifacts.test(localEngine: 'out/android_x64'),
usage: testUsage,
);
processManager.addCommand(const FakeCommand(
command: <String>[

View file

@ -0,0 +1,366 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/gradle.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/context.dart';
void main() {
FileSystem fileSystem;
setUp(() {
fileSystem = MemoryFileSystem.test();
});
testWithoutContext('Finds app bundle when flavor contains underscores in release mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in release mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in release mode", () {
final FlutterProject project = generateFakeAppBundle('fooRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'foo', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooRelease', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in release mode", () {
final FlutterProject project = generateFakeAppBundle('fooaRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'fooA', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaRelease', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in release mode', () {
final FlutterProject project = generateFakeAppBundle('release', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, null, treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'release', 'app.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(
project,
const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barDebug', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in debug mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barDebug', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in debug mode", () {
final FlutterProject project = generateFakeAppBundle('fooDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'foo', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooDebug', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in debug mode", () {
final FlutterProject project = generateFakeAppBundle('fooaDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'fooA', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaDebug', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in debug mode', () {
final FlutterProject project = generateFakeAppBundle('debug', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
BuildInfo.debug,
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'debug', 'app.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(
project,
const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in profile mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, 'foo_Bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in profile mode", () {
final FlutterProject project = generateFakeAppBundle('fooProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, 'foo', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooProfile', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in profile mode", () {
final FlutterProject project = generateFakeAppBundle('fooaProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, 'fooA', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaProfile', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in profile mode', () {
final FlutterProject project = generateFakeAppBundle('profile', 'app.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, null, treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'profile', 'app.aab'));
});
testWithoutContext('Finds app bundle in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('release', 'app-release.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, null, treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'release', 'app-release.aab'));
});
testWithoutContext('Finds app bundle in profile mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('profile', 'app-profile.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, null, treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'profile', 'app-profile.aab'));
});
testWithoutContext('Finds app bundle in debug mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('debug', 'app-debug.aab', fileSystem);
final File bundle = findBundleFile(
project,
BuildInfo.debug,
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'debug', 'app-debug.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app-foo_bar-release.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app-foo_bar-release.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app-foo_bar-release.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app-foo_bar-release.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores in profile mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barProfile', 'app-foo_bar-profile.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app-foo_bar-profile.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in debug mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barDebug', 'app-foo_bar-debug.aab', fileSystem);
final File bundle = findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false),
BufferLogger.test(),
TestUsage(),
);
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant','app', 'outputs', 'bundle', 'foo_barDebug', 'app-foo_bar-debug.aab'));
});
// Context is required due to build failure analytics event grabbing FlutterCommand.current.
testUsingContext('AAB not found', () {
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
final TestUsage testUsage = TestUsage();
expect(
() {
findBundleFile(
project,
const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false),
BufferLogger.test(),
testUsage,
);
},
throwsToolExit(
message:
"Gradle build failed to produce an .aab file. It's likely that this file "
"was generated under ${project.android.buildDirectory.path}, but the tool couldn't find it."
)
);
expect(testUsage.events, contains(
const TestUsageEvent(
'build',
'unspecified',
label: 'gradle-expected-file-not-found',
parameters: <String, String> {
'cd37': 'androidGradlePluginVersion: 6.7, fileExtension: .aab',
},
),
));
});
}
/// Generates a fake app bundle at the location [directoryName]/[fileName].
FlutterProject generateFakeAppBundle(String directoryName, String fileName, FileSystem fileSystem) {
final FlutterProject project = MockFlutterProject();
final AndroidProject androidProject = MockAndroidProject();
when(project.isModule).thenReturn(false);
when(project.android).thenReturn(androidProject);
when(androidProject.buildDirectory).thenReturn(fileSystem.directory('irrelevant'));
final Directory bundleDirectory = getBundleDirectory(project);
bundleDirectory
.childDirectory(directoryName)
.createSync(recursive: true);
bundleDirectory
.childDirectory(directoryName)
.childFile(fileName)
.createSync();
return project;
}
class MockAndroidProject extends Mock implements AndroidProject {}
class MockFlutterProject extends Mock implements FlutterProject {}

View file

@ -132,216 +132,6 @@ void main() {
});
});
group('findBundleFile', () {
FileSystem fileSystem;
TestUsage testUsage;
setUp(() {
fileSystem = MemoryFileSystem.test();
testUsage = TestUsage();
});
testWithoutContext('Finds app bundle when flavor contains underscores in release mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in release mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in release mode", () {
final FlutterProject project = generateFakeAppBundle('fooRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'foo', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooRelease', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in release mode", () {
final FlutterProject project = generateFakeAppBundle('fooaRelease', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'fooA', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaRelease', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in release mode', () {
final FlutterProject project = generateFakeAppBundle('release', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, null, treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'release', 'app.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(project, const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barDebug', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in debug mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barDebug', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in debug mode", () {
final FlutterProject project = generateFakeAppBundle('fooDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.debug, 'foo', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooDebug', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in debug mode", () {
final FlutterProject project = generateFakeAppBundle('fooaDebug', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.debug, 'fooA', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaDebug', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in debug mode', () {
final FlutterProject project = generateFakeAppBundle('debug', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, BuildInfo.debug, BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'debug', 'app.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(project, const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in profile mode', () {
final FlutterProject project = generateFakeAppBundle('foo_barProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, 'foo_Bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores in profile mode", () {
final FlutterProject project = generateFakeAppBundle('fooProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, 'foo', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooProfile', 'app.aab'));
});
testWithoutContext("Finds app bundle when flavor doesn't contain underscores but contains uppercase letters in profile mode", () {
final FlutterProject project = generateFakeAppBundle('fooaProfile', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, 'fooA', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'fooaProfile', 'app.aab'));
});
testWithoutContext('Finds app bundle when no flavor is used in profile mode', () {
final FlutterProject project = generateFakeAppBundle('profile', 'app.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, null, treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'profile', 'app.aab'));
});
testWithoutContext('Finds app bundle in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('release', 'app-release.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, null, treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'release', 'app-release.aab'));
});
testWithoutContext('Finds app bundle in profile mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('profile', 'app-profile.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, null, treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'profile', 'app-profile.aab'));
});
testWithoutContext('Finds app bundle in debug mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('debug', 'app-debug.aab', fileSystem);
final File bundle = findBundleFile(project, BuildInfo.debug, BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'debug', 'app-debug.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app-foo_bar-release.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app-foo_bar-release.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in release mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barRelease', 'app-foo_bar-release.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barRelease', 'app-foo_bar-release.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores in profile mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barProfile', 'app-foo_bar-profile.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant', 'app', 'outputs', 'bundle', 'foo_barProfile', 'app-foo_bar-profile.aab'));
});
testWithoutContext('Finds app bundle when flavor contains underscores and uppercase letters in debug mode - Gradle 3.5', () {
final FlutterProject project = generateFakeAppBundle('foo_barDebug', 'app-foo_bar-debug.aab', fileSystem);
final File bundle = findBundleFile(project, const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false), BufferLogger.test());
expect(bundle, isNotNull);
expect(bundle.path, fileSystem.path.join('irrelevant','app', 'outputs', 'bundle', 'foo_barDebug', 'app-foo_bar-debug.aab'));
});
testUsingContext('aab not found', () {
final FlutterProject project = FlutterProject.fromDirectoryTest(globals.fs.currentDirectory);
expect(
() {
findBundleFile(project, const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false), BufferLogger.test());
},
throwsToolExit(
message:
"Gradle build failed to produce an .aab file. It's likely that this file "
"was generated under ${project.android.buildDirectory.path}, but the tool couldn't find it."
)
);
expect(testUsage.events, contains(
const TestUsageEvent(
'build',
'unspecified',
label: 'gradle-expected-file-not-found',
parameters: <String, String> {
'cd37': 'androidGradlePluginVersion: 6.7, fileExtension: .aab',
},
),
));
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
Usage: () => testUsage,
});
});
group('listApkPaths', () {
testWithoutContext('Finds APK without flavor in release', () {
final Iterable<String> apks = listApkPaths(
@ -865,6 +655,7 @@ flutter:
processManager: fakeProcessManager,
fileSystem: fs,
artifacts: Artifacts.test(),
usage: TestUsage(),
);
});
@ -1233,27 +1024,6 @@ plugin1=${plugin1.path}
}, skip: true); // TODO(jonahwilliams): This is an integration test and should be moved to the integration shard.
}
/// Generates a fake app bundle at the location [directoryName]/[fileName].
FlutterProject generateFakeAppBundle(String directoryName, String fileName, FileSystem fileSystem) {
final FlutterProject project = MockFlutterProject();
final AndroidProject androidProject = MockAndroidProject();
when(project.isModule).thenReturn(false);
when(project.android).thenReturn(androidProject);
when(androidProject.buildDirectory).thenReturn(fileSystem.directory('irrelevant'));
final Directory bundleDirectory = getBundleDirectory(project);
bundleDirectory
.childDirectory(directoryName)
.createSync(recursive: true);
bundleDirectory
.childDirectory(directoryName)
.childFile(fileName)
.createSync();
return project;
}
FakePlatform fakePlatform(String name) {
return FakePlatform(
environment: <String, String>{'HOME': '/path/to/home'},