Instrument usage of include_flutter.groovy and xcode_backend.sh (#34189)
This is done via `flutter build bundle`. As a consequence, this PR introduces a new way to disable analytics via the `FLUTTER_SUPPRESS_ANALYTICS` env flag.
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index bf53166..1391187 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -601,6 +601,10 @@
// Use java bundled with Android Studio.
env['JAVA_HOME'] = javaPath;
}
+
+ // Don't log analytics for downstream Flutter commands.
+ // e.g. `flutter build bundle`.
+ env['FLUTTER_SUPPRESS_ANALYTICS'] = 'true';
return env;
}
diff --git a/packages/flutter_tools/lib/src/bundle.dart b/packages/flutter_tools/lib/src/bundle.dart
index 7cd7956..aefc3c6 100644
--- a/packages/flutter_tools/lib/src/bundle.dart
+++ b/packages/flutter_tools/lib/src/bundle.dart
@@ -48,114 +48,121 @@
const String _kIsolateSnapshotData = 'isolate_snapshot_data';
const String _kIsolateSnapshotInstr = 'isolate_snapshot_instr';
-Future<void> build({
- TargetPlatform platform,
- BuildMode buildMode,
- String mainPath = defaultMainPath,
- String manifestPath = defaultManifestPath,
- String applicationKernelFilePath,
- String depfilePath,
- String privateKeyPath = defaultPrivateKeyPath,
- String assetDirPath,
- String packagesPath,
- bool precompiledSnapshot = false,
- bool reportLicensedPackages = false,
- bool trackWidgetCreation = false,
- String compilationTraceFilePath,
- List<String> extraFrontEndOptions = const <String>[],
- List<String> extraGenSnapshotOptions = const <String>[],
- List<String> fileSystemRoots,
- String fileSystemScheme,
-}) async {
- depfilePath ??= defaultDepfilePath;
- assetDirPath ??= getAssetBuildDirectory();
- packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
- applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
- final FlutterProject flutterProject = FlutterProject.current();
-
- if (compilationTraceFilePath != null) {
- if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
- // Silently ignore JIT snapshotting for those builds that don't support it.
- compilationTraceFilePath = null;
-
- } else if (compilationTraceFilePath.isEmpty) {
- // Disable JIT snapshotting if flag is empty.
- printStatus('Code snapshot will be disabled for this build.');
- compilationTraceFilePath = null;
-
- } else if (!fs.file(compilationTraceFilePath).existsSync()) {
- // Be forgiving if compilation trace file is missing.
- printStatus('No compilation trace available. To optimize performance, consider using --train.');
- final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
- compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
-
- } else {
- printStatus('Code snapshot will use compilation training file $compilationTraceFilePath.');
- }
- }
-
- DevFSContent kernelContent;
- if (!precompiledSnapshot) {
- if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
- printTrace('Extra front-end options: $extraFrontEndOptions');
- ensureDirectoryExists(applicationKernelFilePath);
- final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
- final CompilerOutput compilerOutput = await kernelCompiler.compile(
- sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
- incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
- fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
- mainPath: fs.file(mainPath).absolute.path,
- outputFilePath: applicationKernelFilePath,
- depFilePath: depfilePath,
- trackWidgetCreation: trackWidgetCreation,
- extraFrontEndOptions: extraFrontEndOptions,
- fileSystemRoots: fileSystemRoots,
- fileSystemScheme: fileSystemScheme,
- packagesPath: packagesPath,
- linkPlatformKernelIn: compilationTraceFilePath != null,
- );
- if (compilerOutput?.outputFilename == null) {
- throwToolExit('Compiler failed on $mainPath');
- }
- kernelContent = DevFSFileContent(fs.file(compilerOutput.outputFilename));
-
- await fs.directory(getBuildDirectory()).childFile('frontend_server.d')
- .writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
+/// Provides a `build` method that builds the bundle.
+class BundleBuilder {
+ /// Builds the bundle for the given target platform.
+ ///
+ /// The default `mainPath` is `lib/main.dart`.
+ /// The default `manifestPath` is `pubspec.yaml`
+ Future<void> build({
+ TargetPlatform platform,
+ BuildMode buildMode,
+ String mainPath = defaultMainPath,
+ String manifestPath = defaultManifestPath,
+ String applicationKernelFilePath,
+ String depfilePath,
+ String privateKeyPath = defaultPrivateKeyPath,
+ String assetDirPath,
+ String packagesPath,
+ bool precompiledSnapshot = false,
+ bool reportLicensedPackages = false,
+ bool trackWidgetCreation = false,
+ String compilationTraceFilePath,
+ List<String> extraFrontEndOptions = const <String>[],
+ List<String> extraGenSnapshotOptions = const <String>[],
+ List<String> fileSystemRoots,
+ String fileSystemScheme,
+ }) async {
+ depfilePath ??= defaultDepfilePath;
+ assetDirPath ??= getAssetBuildDirectory();
+ packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
+ applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
+ final FlutterProject flutterProject = FlutterProject.current();
if (compilationTraceFilePath != null) {
- final JITSnapshotter snapshotter = JITSnapshotter();
- final int snapshotExitCode = await snapshotter.build(
- platform: platform,
- buildMode: buildMode,
- mainPath: applicationKernelFilePath,
- outputPath: getBuildDirectory(),
- packagesPath: packagesPath,
- compilationTraceFilePath: compilationTraceFilePath,
- extraGenSnapshotOptions: extraGenSnapshotOptions,
- );
- if (snapshotExitCode != 0) {
- throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
+ if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
+ // Silently ignore JIT snapshotting for those builds that don't support it.
+ compilationTraceFilePath = null;
+
+ } else if (compilationTraceFilePath.isEmpty) {
+ // Disable JIT snapshotting if flag is empty.
+ printStatus('Code snapshot will be disabled for this build.');
+ compilationTraceFilePath = null;
+
+ } else if (!fs.file(compilationTraceFilePath).existsSync()) {
+ // Be forgiving if compilation trace file is missing.
+ printStatus('No compilation trace available. To optimize performance, consider using --train.');
+ final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
+ compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
+
+ } else {
+ printStatus('Code snapshot will use compilation training file $compilationTraceFilePath.');
}
}
+
+ DevFSContent kernelContent;
+ if (!precompiledSnapshot) {
+ if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
+ printTrace('Extra front-end options: $extraFrontEndOptions');
+ ensureDirectoryExists(applicationKernelFilePath);
+ final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
+ final CompilerOutput compilerOutput = await kernelCompiler.compile(
+ sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
+ incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
+ fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
+ mainPath: fs.file(mainPath).absolute.path,
+ outputFilePath: applicationKernelFilePath,
+ depFilePath: depfilePath,
+ trackWidgetCreation: trackWidgetCreation,
+ extraFrontEndOptions: extraFrontEndOptions,
+ fileSystemRoots: fileSystemRoots,
+ fileSystemScheme: fileSystemScheme,
+ packagesPath: packagesPath,
+ linkPlatformKernelIn: compilationTraceFilePath != null,
+ );
+ if (compilerOutput?.outputFilename == null) {
+ throwToolExit('Compiler failed on $mainPath');
+ }
+ kernelContent = DevFSFileContent(fs.file(compilerOutput.outputFilename));
+
+ await fs.directory(getBuildDirectory()).childFile('frontend_server.d')
+ .writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
+
+ if (compilationTraceFilePath != null) {
+ final JITSnapshotter snapshotter = JITSnapshotter();
+ final int snapshotExitCode = await snapshotter.build(
+ platform: platform,
+ buildMode: buildMode,
+ mainPath: applicationKernelFilePath,
+ outputPath: getBuildDirectory(),
+ packagesPath: packagesPath,
+ compilationTraceFilePath: compilationTraceFilePath,
+ extraGenSnapshotOptions: extraGenSnapshotOptions,
+ );
+ if (snapshotExitCode != 0) {
+ throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
+ }
+ }
+ }
+
+ final AssetBundle assets = await buildAssets(
+ manifestPath: manifestPath,
+ assetDirPath: assetDirPath,
+ packagesPath: packagesPath,
+ reportLicensedPackages: reportLicensedPackages,
+ );
+ if (assets == null)
+ throwToolExit('Error building assets', exitCode: 1);
+
+ await assemble(
+ buildMode: buildMode,
+ assetBundle: assets,
+ kernelContent: kernelContent,
+ privateKeyPath: privateKeyPath,
+ assetDirPath: assetDirPath,
+ compilationTraceFilePath: compilationTraceFilePath,
+ );
}
-
- final AssetBundle assets = await buildAssets(
- manifestPath: manifestPath,
- assetDirPath: assetDirPath,
- packagesPath: packagesPath,
- reportLicensedPackages: reportLicensedPackages,
- );
- if (assets == null)
- throwToolExit('Error building assets', exitCode: 1);
-
- await assemble(
- buildMode: buildMode,
- assetBundle: assets,
- kernelContent: kernelContent,
- privateKeyPath: privateKeyPath,
- assetDirPath: assetDirPath,
- compilationTraceFilePath: compilationTraceFilePath,
- );
}
Future<AssetBundle> buildAssets({
diff --git a/packages/flutter_tools/lib/src/commands/build_bundle.dart b/packages/flutter_tools/lib/src/commands/build_bundle.dart
index 3d909ed..f134c8c 100644
--- a/packages/flutter_tools/lib/src/commands/build_bundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_bundle.dart
@@ -5,14 +5,17 @@
import 'dart:async';
import '../base/common.dart';
+import '../base/file_system.dart';
import '../build_info.dart';
import '../bundle.dart';
+import '../project.dart';
import '../runner/flutter_command.dart' show FlutterOptions, FlutterCommandResult;
+import '../usage.dart';
import '../version.dart';
import 'build.dart';
class BuildBundleCommand extends BuildSubCommand {
- BuildBundleCommand({bool verboseHelp = false}) {
+ BuildBundleCommand({bool verboseHelp = false, this.bundleBuilder}) {
usesTargetOption();
usesFilesystemOptions(hide: !verboseHelp);
usesBuildNumberOption();
@@ -57,8 +60,12 @@
'in the application\'s LICENSE file.',
defaultsTo: false);
usesPubOption();
+
+ bundleBuilder ??= BundleBuilder();
}
+ BundleBuilder bundleBuilder;
+
@override
final String name = 'bundle';
@@ -71,6 +78,21 @@
' iOS runtimes.';
@override
+ Future<Map<String, String>> get usageValues async {
+ final String projectDir = fs.file(targetFile).parent.parent.path;
+ final FlutterProject futterProject = FlutterProject.fromPath(projectDir);
+
+ if (futterProject == null) {
+ return const <String, String>{};
+ }
+
+ return <String, String>{
+ kCommandBuildBundleTargetPlatform: argResults['target-platform'],
+ kCommandBuildBundleIsModule: '${futterProject.isModule}'
+ };
+ }
+
+ @override
Future<FlutterCommandResult> runCommand() async {
final String targetPlatform = argResults['target-platform'];
final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
@@ -92,7 +114,7 @@
final BuildMode buildMode = getBuildMode();
- await build(
+ await bundleBuilder.build(
platform: platform,
buildMode: buildMode,
mainPath: targetFile,
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index cfe4ad4..dcc7f5a 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -279,6 +279,10 @@
buildCommands.add('SCRIPT_OUTPUT_STREAM_FILE=${scriptOutputPipeFile.absolute.path}');
}
+ // Don't log analytics for downstream Flutter commands.
+ // e.g. `flutter build bundle`.
+ buildCommands.add('FLUTTER_SUPPRESS_ANALYTICS=true');
+
final Stopwatch sw = Stopwatch()..start();
initialBuildStatus = logger.startProgress('Running Xcode build...', timeout: timeoutConfiguration.fastOperation);
final RunResult buildResult = await runAsync(
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 62535d0..b22e32d 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -15,7 +15,7 @@
import '../base/process_manager.dart';
import '../base/utils.dart';
import '../build_info.dart';
-import '../bundle.dart' as bundle;
+import '../bundle.dart';
import '../convert.dart';
import '../device.dart';
import '../globals.dart';
@@ -412,7 +412,7 @@
Future<void> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath) {
// Run compiler to produce kernel file for the application.
- return bundle.build(
+ return BundleBuilder().build(
mainPath: mainPath,
precompiledSnapshot: false,
trackWidgetCreation: buildInfo.trackWidgetCreation,
diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
index 988fbeb..3705057 100644
--- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart
+++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
@@ -13,7 +13,7 @@
import '../base/io.dart';
import '../base/process_manager.dart';
import '../build_info.dart';
-import '../bundle.dart' as bundle;
+import '../bundle.dart';
import '../convert.dart';
import '../dart/package_map.dart';
import '../device.dart';
@@ -129,11 +129,11 @@
// Build assets and perform initial compilation.
final String assetDirPath = getAssetBuildDirectory();
- final String applicationKernelFilePath = bundle.getKernelPathForTransformerOptions(
+ final String applicationKernelFilePath = getKernelPathForTransformerOptions(
fs.path.join(getBuildDirectory(), 'flutter-tester-app.dill'),
trackWidgetCreation: buildInfo.trackWidgetCreation,
);
- await bundle.build(
+ await BundleBuilder().build(
mainPath: mainPath,
assetDirPath: assetDirPath,
applicationKernelFilePath: applicationKernelFilePath,
diff --git a/packages/flutter_tools/lib/src/usage.dart b/packages/flutter_tools/lib/src/usage.dart
index 6cd1eb3..d74437b 100644
--- a/packages/flutter_tools/lib/src/usage.dart
+++ b/packages/flutter_tools/lib/src/usage.dart
@@ -45,6 +45,10 @@
const String kCommandPackagesNumberPlugins = 'cd20';
const String kCommandPackagesProjectModule = 'cd21';
+const String kCommandBuildBundleTargetPlatform = 'cd24';
+const String kCommandBuildBundleIsModule = 'cd25';
+// Next ID: cd26
+
Usage get flutterUsage => Usage.instance;
class Usage {
@@ -66,8 +70,9 @@
}
_analytics.analyticsOpt = AnalyticsOpt.optOut;
+ final bool suppressEnvFlag = platform.environment['FLUTTER_SUPPRESS_ANALYTICS'] == 'true';
// Many CI systems don't do a full git checkout.
- if (version.endsWith('/unknown') || isRunningOnBot) {
+ if (version.endsWith('/unknown') || isRunningOnBot || suppressEnvFlag) {
// If we think we're running on a CI system, suppress sending analytics.
suppressAnalytics = true;
}