Skip to content

Commit d9c1962

Browse files
author
Emmanuel Garcia
authored
Instrument usage of include_flutter.groovy and xcode_backend.sh (flutter#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.
1 parent 1eb8c64 commit d9c1962

File tree

10 files changed

+250
-110
lines changed

10 files changed

+250
-110
lines changed

packages/flutter_tools/bin/xcode_backend.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ BuildApp() {
249249
fi
250250

251251
StreamOutput " ├─Assembling Flutter resources..."
252-
RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics \
252+
RunCommand "${FLUTTER_ROOT}/bin/flutter" \
253253
${verbose_flag} \
254254
build bundle \
255255
--target-platform=ios \

packages/flutter_tools/gradle/flutter.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,6 @@ abstract class BaseFlutterTask extends DefaultTask {
717717
args "--local-engine-src-path", localEngineSrcPath
718718
}
719719
args "build", "bundle"
720-
args "--suppress-analytics"
721720
args "--target", targetPath
722721
args "--target-platform", "${targetPlatform}"
723722
if (verbose) {

packages/flutter_tools/lib/src/android/gradle.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,10 @@ Map<String, String> get _gradleEnv {
601601
// Use java bundled with Android Studio.
602602
env['JAVA_HOME'] = javaPath;
603603
}
604+
605+
// Don't log analytics for downstream Flutter commands.
606+
// e.g. `flutter build bundle`.
607+
env['FLUTTER_SUPPRESS_ANALYTICS'] = 'true';
604608
return env;
605609
}
606610

packages/flutter_tools/lib/src/bundle.dart

Lines changed: 107 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -48,114 +48,121 @@ const String _kVMSnapshotData = 'vm_snapshot_data';
4848
const String _kIsolateSnapshotData = 'isolate_snapshot_data';
4949
const String _kIsolateSnapshotInstr = 'isolate_snapshot_instr';
5050

51-
Future<void> build({
52-
TargetPlatform platform,
53-
BuildMode buildMode,
54-
String mainPath = defaultMainPath,
55-
String manifestPath = defaultManifestPath,
56-
String applicationKernelFilePath,
57-
String depfilePath,
58-
String privateKeyPath = defaultPrivateKeyPath,
59-
String assetDirPath,
60-
String packagesPath,
61-
bool precompiledSnapshot = false,
62-
bool reportLicensedPackages = false,
63-
bool trackWidgetCreation = false,
64-
String compilationTraceFilePath,
65-
List<String> extraFrontEndOptions = const <String>[],
66-
List<String> extraGenSnapshotOptions = const <String>[],
67-
List<String> fileSystemRoots,
68-
String fileSystemScheme,
69-
}) async {
70-
depfilePath ??= defaultDepfilePath;
71-
assetDirPath ??= getAssetBuildDirectory();
72-
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
73-
applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
74-
final FlutterProject flutterProject = FlutterProject.current();
51+
/// Provides a `build` method that builds the bundle.
52+
class BundleBuilder {
53+
/// Builds the bundle for the given target platform.
54+
///
55+
/// The default `mainPath` is `lib/main.dart`.
56+
/// The default `manifestPath` is `pubspec.yaml`
57+
Future<void> build({
58+
TargetPlatform platform,
59+
BuildMode buildMode,
60+
String mainPath = defaultMainPath,
61+
String manifestPath = defaultManifestPath,
62+
String applicationKernelFilePath,
63+
String depfilePath,
64+
String privateKeyPath = defaultPrivateKeyPath,
65+
String assetDirPath,
66+
String packagesPath,
67+
bool precompiledSnapshot = false,
68+
bool reportLicensedPackages = false,
69+
bool trackWidgetCreation = false,
70+
String compilationTraceFilePath,
71+
List<String> extraFrontEndOptions = const <String>[],
72+
List<String> extraGenSnapshotOptions = const <String>[],
73+
List<String> fileSystemRoots,
74+
String fileSystemScheme,
75+
}) async {
76+
depfilePath ??= defaultDepfilePath;
77+
assetDirPath ??= getAssetBuildDirectory();
78+
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
79+
applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
80+
final FlutterProject flutterProject = FlutterProject.current();
7581

76-
if (compilationTraceFilePath != null) {
77-
if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
78-
// Silently ignore JIT snapshotting for those builds that don't support it.
79-
compilationTraceFilePath = null;
80-
81-
} else if (compilationTraceFilePath.isEmpty) {
82-
// Disable JIT snapshotting if flag is empty.
83-
printStatus('Code snapshot will be disabled for this build.');
84-
compilationTraceFilePath = null;
85-
86-
} else if (!fs.file(compilationTraceFilePath).existsSync()) {
87-
// Be forgiving if compilation trace file is missing.
88-
printStatus('No compilation trace available. To optimize performance, consider using --train.');
89-
final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
90-
compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
91-
92-
} else {
93-
printStatus('Code snapshot will use compilation training file $compilationTraceFilePath.');
94-
}
95-
}
96-
97-
DevFSContent kernelContent;
98-
if (!precompiledSnapshot) {
99-
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
100-
printTrace('Extra front-end options: $extraFrontEndOptions');
101-
ensureDirectoryExists(applicationKernelFilePath);
102-
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
103-
final CompilerOutput compilerOutput = await kernelCompiler.compile(
104-
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
105-
incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
106-
fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
107-
mainPath: fs.file(mainPath).absolute.path,
108-
outputFilePath: applicationKernelFilePath,
109-
depFilePath: depfilePath,
110-
trackWidgetCreation: trackWidgetCreation,
111-
extraFrontEndOptions: extraFrontEndOptions,
112-
fileSystemRoots: fileSystemRoots,
113-
fileSystemScheme: fileSystemScheme,
114-
packagesPath: packagesPath,
115-
linkPlatformKernelIn: compilationTraceFilePath != null,
116-
);
117-
if (compilerOutput?.outputFilename == null) {
118-
throwToolExit('Compiler failed on $mainPath');
82+
if (compilationTraceFilePath != null) {
83+
if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
84+
// Silently ignore JIT snapshotting for those builds that don't support it.
85+
compilationTraceFilePath = null;
86+
87+
} else if (compilationTraceFilePath.isEmpty) {
88+
// Disable JIT snapshotting if flag is empty.
89+
printStatus('Code snapshot will be disabled for this build.');
90+
compilationTraceFilePath = null;
91+
92+
} else if (!fs.file(compilationTraceFilePath).existsSync()) {
93+
// Be forgiving if compilation trace file is missing.
94+
printStatus('No compilation trace available. To optimize performance, consider using --train.');
95+
final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
96+
compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
97+
98+
} else {
99+
printStatus('Code snapshot will use compilation training file $compilationTraceFilePath.');
100+
}
119101
}
120-
kernelContent = DevFSFileContent(fs.file(compilerOutput.outputFilename));
121-
122-
await fs.directory(getBuildDirectory()).childFile('frontend_server.d')
123-
.writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
124102

125-
if (compilationTraceFilePath != null) {
126-
final JITSnapshotter snapshotter = JITSnapshotter();
127-
final int snapshotExitCode = await snapshotter.build(
128-
platform: platform,
129-
buildMode: buildMode,
130-
mainPath: applicationKernelFilePath,
131-
outputPath: getBuildDirectory(),
103+
DevFSContent kernelContent;
104+
if (!precompiledSnapshot) {
105+
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
106+
printTrace('Extra front-end options: $extraFrontEndOptions');
107+
ensureDirectoryExists(applicationKernelFilePath);
108+
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
109+
final CompilerOutput compilerOutput = await kernelCompiler.compile(
110+
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
111+
incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
112+
fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
113+
mainPath: fs.file(mainPath).absolute.path,
114+
outputFilePath: applicationKernelFilePath,
115+
depFilePath: depfilePath,
116+
trackWidgetCreation: trackWidgetCreation,
117+
extraFrontEndOptions: extraFrontEndOptions,
118+
fileSystemRoots: fileSystemRoots,
119+
fileSystemScheme: fileSystemScheme,
132120
packagesPath: packagesPath,
133-
compilationTraceFilePath: compilationTraceFilePath,
134-
extraGenSnapshotOptions: extraGenSnapshotOptions,
121+
linkPlatformKernelIn: compilationTraceFilePath != null,
135122
);
136-
if (snapshotExitCode != 0) {
137-
throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
123+
if (compilerOutput?.outputFilename == null) {
124+
throwToolExit('Compiler failed on $mainPath');
125+
}
126+
kernelContent = DevFSFileContent(fs.file(compilerOutput.outputFilename));
127+
128+
await fs.directory(getBuildDirectory()).childFile('frontend_server.d')
129+
.writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
130+
131+
if (compilationTraceFilePath != null) {
132+
final JITSnapshotter snapshotter = JITSnapshotter();
133+
final int snapshotExitCode = await snapshotter.build(
134+
platform: platform,
135+
buildMode: buildMode,
136+
mainPath: applicationKernelFilePath,
137+
outputPath: getBuildDirectory(),
138+
packagesPath: packagesPath,
139+
compilationTraceFilePath: compilationTraceFilePath,
140+
extraGenSnapshotOptions: extraGenSnapshotOptions,
141+
);
142+
if (snapshotExitCode != 0) {
143+
throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
144+
}
138145
}
139146
}
140-
}
141147

142-
final AssetBundle assets = await buildAssets(
143-
manifestPath: manifestPath,
144-
assetDirPath: assetDirPath,
145-
packagesPath: packagesPath,
146-
reportLicensedPackages: reportLicensedPackages,
147-
);
148-
if (assets == null)
149-
throwToolExit('Error building assets', exitCode: 1);
150-
151-
await assemble(
152-
buildMode: buildMode,
153-
assetBundle: assets,
154-
kernelContent: kernelContent,
155-
privateKeyPath: privateKeyPath,
156-
assetDirPath: assetDirPath,
157-
compilationTraceFilePath: compilationTraceFilePath,
158-
);
148+
final AssetBundle assets = await buildAssets(
149+
manifestPath: manifestPath,
150+
assetDirPath: assetDirPath,
151+
packagesPath: packagesPath,
152+
reportLicensedPackages: reportLicensedPackages,
153+
);
154+
if (assets == null)
155+
throwToolExit('Error building assets', exitCode: 1);
156+
157+
await assemble(
158+
buildMode: buildMode,
159+
assetBundle: assets,
160+
kernelContent: kernelContent,
161+
privateKeyPath: privateKeyPath,
162+
assetDirPath: assetDirPath,
163+
compilationTraceFilePath: compilationTraceFilePath,
164+
);
165+
}
159166
}
160167

161168
Future<AssetBundle> buildAssets({

packages/flutter_tools/lib/src/commands/build_bundle.dart

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
import 'dart:async';
66

77
import '../base/common.dart';
8+
import '../base/file_system.dart';
89
import '../build_info.dart';
910
import '../bundle.dart';
11+
import '../project.dart';
1012
import '../runner/flutter_command.dart' show FlutterOptions, FlutterCommandResult;
13+
import '../usage.dart';
1114
import '../version.dart';
1215
import 'build.dart';
1316

1417
class BuildBundleCommand extends BuildSubCommand {
15-
BuildBundleCommand({bool verboseHelp = false}) {
18+
BuildBundleCommand({bool verboseHelp = false, this.bundleBuilder}) {
1619
usesTargetOption();
1720
usesFilesystemOptions(hide: !verboseHelp);
1821
usesBuildNumberOption();
@@ -57,8 +60,12 @@ class BuildBundleCommand extends BuildSubCommand {
5760
'in the application\'s LICENSE file.',
5861
defaultsTo: false);
5962
usesPubOption();
63+
64+
bundleBuilder ??= BundleBuilder();
6065
}
6166

67+
BundleBuilder bundleBuilder;
68+
6269
@override
6370
final String name = 'bundle';
6471

@@ -70,6 +77,21 @@ class BuildBundleCommand extends BuildSubCommand {
7077
'application code and resources; they are used by some Flutter Android and'
7178
' iOS runtimes.';
7279

80+
@override
81+
Future<Map<String, String>> get usageValues async {
82+
final String projectDir = fs.file(targetFile).parent.parent.path;
83+
final FlutterProject futterProject = FlutterProject.fromPath(projectDir);
84+
85+
if (futterProject == null) {
86+
return const <String, String>{};
87+
}
88+
89+
return <String, String>{
90+
kCommandBuildBundleTargetPlatform: argResults['target-platform'],
91+
kCommandBuildBundleIsModule: '${futterProject.isModule}'
92+
};
93+
}
94+
7395
@override
7496
Future<FlutterCommandResult> runCommand() async {
7597
final String targetPlatform = argResults['target-platform'];
@@ -92,7 +114,7 @@ class BuildBundleCommand extends BuildSubCommand {
92114

93115
final BuildMode buildMode = getBuildMode();
94116

95-
await build(
117+
await bundleBuilder.build(
96118
platform: platform,
97119
buildMode: buildMode,
98120
mainPath: targetFile,

packages/flutter_tools/lib/src/ios/mac.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ Future<XcodeBuildResult> buildXcodeProject({
279279
buildCommands.add('SCRIPT_OUTPUT_STREAM_FILE=${scriptOutputPipeFile.absolute.path}');
280280
}
281281

282+
// Don't log analytics for downstream Flutter commands.
283+
// e.g. `flutter build bundle`.
284+
buildCommands.add('FLUTTER_SUPPRESS_ANALYTICS=true');
285+
282286
final Stopwatch sw = Stopwatch()..start();
283287
initialBuildStatus = logger.startProgress('Running Xcode build...', timeout: timeoutConfiguration.fastOperation);
284288
final RunResult buildResult = await runAsync(

packages/flutter_tools/lib/src/ios/simulators.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import '../base/process.dart';
1515
import '../base/process_manager.dart';
1616
import '../base/utils.dart';
1717
import '../build_info.dart';
18-
import '../bundle.dart' as bundle;
18+
import '../bundle.dart';
1919
import '../convert.dart';
2020
import '../device.dart';
2121
import '../globals.dart';
@@ -412,7 +412,7 @@ class IOSSimulator extends Device {
412412

413413
Future<void> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo, String mainPath) {
414414
// Run compiler to produce kernel file for the application.
415-
return bundle.build(
415+
return BundleBuilder().build(
416416
mainPath: mainPath,
417417
precompiledSnapshot: false,
418418
trackWidgetCreation: buildInfo.trackWidgetCreation,

packages/flutter_tools/lib/src/tester/flutter_tester.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import '../base/file_system.dart';
1313
import '../base/io.dart';
1414
import '../base/process_manager.dart';
1515
import '../build_info.dart';
16-
import '../bundle.dart' as bundle;
16+
import '../bundle.dart';
1717
import '../convert.dart';
1818
import '../dart/package_map.dart';
1919
import '../device.dart';
@@ -129,11 +129,11 @@ class FlutterTesterDevice extends Device {
129129

130130
// Build assets and perform initial compilation.
131131
final String assetDirPath = getAssetBuildDirectory();
132-
final String applicationKernelFilePath = bundle.getKernelPathForTransformerOptions(
132+
final String applicationKernelFilePath = getKernelPathForTransformerOptions(
133133
fs.path.join(getBuildDirectory(), 'flutter-tester-app.dill'),
134134
trackWidgetCreation: buildInfo.trackWidgetCreation,
135135
);
136-
await bundle.build(
136+
await BundleBuilder().build(
137137
mainPath: mainPath,
138138
assetDirPath: assetDirPath,
139139
applicationKernelFilePath: applicationKernelFilePath,

packages/flutter_tools/lib/src/usage.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const String kCommandCreateProjectType = 'cd19';
4545
const String kCommandPackagesNumberPlugins = 'cd20';
4646
const String kCommandPackagesProjectModule = 'cd21';
4747

48+
const String kCommandBuildBundleTargetPlatform = 'cd24';
49+
const String kCommandBuildBundleIsModule = 'cd25';
50+
// Next ID: cd26
51+
4852
Usage get flutterUsage => Usage.instance;
4953

5054
class Usage {
@@ -66,8 +70,9 @@ class Usage {
6670
}
6771
_analytics.analyticsOpt = AnalyticsOpt.optOut;
6872

73+
final bool suppressEnvFlag = platform.environment['FLUTTER_SUPPRESS_ANALYTICS'] == 'true';
6974
// Many CI systems don't do a full git checkout.
70-
if (version.endsWith('/unknown') || isRunningOnBot) {
75+
if (version.endsWith('/unknown') || isRunningOnBot || suppressEnvFlag) {
7176
// If we think we're running on a CI system, suppress sending analytics.
7277
suppressAnalytics = true;
7378
}

0 commit comments

Comments
 (0)