Unverified Commit 03220cac authored by xster's avatar xster Committed by GitHub

Make sure add-to-app build bundle from outer xcodebuild/gradlew sends analytics (#36122)

parent 07735578
......@@ -154,13 +154,18 @@ Future<void> main() async {
Directory(path.join(hostApp.path, 'gradle', 'wrapper')),
);
final File analyticsOutputFile = File(path.join(tempDir.path, 'analytics.log'));
await inDirectory(hostApp, () async {
if (!Platform.isWindows) {
await exec('chmod', <String>['+x', 'gradlew']);
}
await exec(gradlewExecutable,
<String>['app:assembleDebug'],
environment: <String, String>{ 'JAVA_HOME': javaHome },
environment: <String, String>{
'JAVA_HOME': javaHome,
'FLUTTER_ANALYTICS_LOG_FILE': analyticsOutputFile.path,
},
);
});
......@@ -173,10 +178,21 @@ Future<void> main() async {
'debug',
'app-debug.apk',
)));
if (!existingAppBuilt) {
return TaskResult.failure('Failed to build existing app .apk');
}
final String analyticsOutput = analyticsOutputFile.readAsStringSync();
if (!analyticsOutput.contains('cd24: android-arm64')
|| !analyticsOutput.contains('cd25: true')
|| !analyticsOutput.contains('viewName: build/bundle')) {
return TaskResult.failure(
'Building outer app produced the following analytics: "$analyticsOutput"'
'but not the expected strings: "cd24: android-arm64", "cd25: true" and '
'"viewName: build/bundle"'
);
}
return TaskResult.success(null);
} catch (e) {
return TaskResult.failure(e.toString());
......
......@@ -219,6 +219,8 @@ Future<void> main() async {
hostApp,
);
final File analyticsOutputFile = File(path.join(tempDir.path, 'analytics.log'));
await inDirectory(hostApp, () async {
await exec('pod', <String>['install']);
await exec(
......@@ -236,6 +238,9 @@ Future<void> main() async {
'EXPANDED_CODE_SIGN_IDENTITY=-',
'CONFIGURATION_BUILD_DIR=${tempDir.path}',
],
environment: <String, String> {
'FLUTTER_ANALYTICS_LOG_FILE': analyticsOutputFile.path,
}
);
});
......@@ -244,11 +249,20 @@ Future<void> main() async {
'Host.app',
'Host',
)));
if (!existingAppBuilt) {
return TaskResult.failure('Failed to build existing app .app');
}
final String analyticsOutput = analyticsOutputFile.readAsStringSync();
if (!analyticsOutput.contains('cd24: ios')
|| !analyticsOutput.contains('cd25: true')
|| !analyticsOutput.contains('viewName: build/bundle')) {
return TaskResult.failure(
'Building outer app produced the following analytics: "$analyticsOutput"'
'but not the expected strings: "cd24: ios", "cd25: true", "viewName: build/bundle"'
);
}
return TaskResult.success(null);
} catch (e) {
return TaskResult.failure(e.toString());
......
......@@ -249,7 +249,7 @@ BuildApp() {
fi
StreamOutput " ├─Assembling Flutter resources..."
RunCommand "${FLUTTER_ROOT}/bin/flutter" \
RunCommand "${FLUTTER_ROOT}/bin/flutter" \
${verbose_flag} \
build bundle \
--target-platform=ios \
......
......@@ -223,7 +223,7 @@ class FlutterPlugin implements Plugin<Project> {
initWith debug
}
}
pluginProject.android.buildTypes.each {
def buildMode = buildModeFor(it)
addFlutterJarCompileOnlyDependency(pluginProject, it.name, project.files( flutterJar ?: baseJar[buildMode] ))
......@@ -652,6 +652,7 @@ abstract class BaseFlutterTask extends DefaultTask {
project.exec {
executable flutterExecutable.absolutePath
workingDir sourceDir
if (localEngine != null) {
args "--local-engine", localEngine
args "--local-engine-src-path", localEngineSrcPath
......
......@@ -27,6 +27,8 @@ class BotDetector {
// Set by the IDEs to the IDE name, so a strong signal that this is not a bot.
|| platform.environment.containsKey('FLUTTER_HOST')
// When set, GA logs to a local file (normally for tests) so we don't need to filter.
|| platform.environment.containsKey('FLUTTER_ANALYTICS_LOG_FILE')
) {
return false;
}
......
......@@ -69,8 +69,18 @@ class Usage {
Usage({ String settingsName = 'flutter', String versionOverride, String configDirOverride}) {
final FlutterVersion flutterVersion = FlutterVersion.instance;
final String version = versionOverride ?? flutterVersion.getVersionString(redactUnknownBranches: true);
_analytics = AnalyticsIO(_kFlutterUA, settingsName, version,
documentDirectory: configDirOverride != null ? fs.directory(configDirOverride) : null);
final String logFilePath = platform.environment['FLUTTER_ANALYTICS_LOG_FILE'];
_analytics = logFilePath == null || logFilePath.isEmpty ?
AnalyticsIO(
_kFlutterUA,
settingsName,
version,
documentDirectory: configDirOverride != null ? fs.directory(configDirOverride) : null,
) :
// Used for testing.
LogToFileAnalytics(logFilePath);
// Report a more detailed OS version string than package:usage does by default.
_analytics.setSessionValue(kSessionHostOsDetails, os.name);
......@@ -94,6 +104,7 @@ class Usage {
_analytics.analyticsOpt = AnalyticsOpt.optOut;
final bool suppressEnvFlag = platform.environment['FLUTTER_SUPPRESS_ANALYTICS'] == 'true';
_analytics.sendScreenView('version is $version, is bot $isRunningOnBot, suppressed $suppressEnvFlag');
// Many CI systems don't do a full git checkout.
if (version.endsWith('/unknown') || isRunningOnBot || suppressEnvFlag) {
// If we think we're running on a CI system, suppress sending analytics.
......@@ -213,3 +224,22 @@ class Usage {
''', emphasis: true);
}
}
// An Analytics mock that logs to file. Unimplemented methods goes to stdout.
// But stdout can't be used for testing since wrapper scripts like
// xcode_backend.sh etc manipulates them.
class LogToFileAnalytics extends AnalyticsMock {
LogToFileAnalytics(String logFilePath) :
logFile = fs.file(logFilePath)..createSync(recursive: true),
super(true);
final File logFile;
@override
Future<void> sendScreenView(String viewName, {Map<String, String> parameters}) {
parameters ??= <String, String>{};
parameters['viewName'] = viewName;
logFile.writeAsStringSync('screenView $parameters\n');
return Future<void>.value(null);
}
}
......@@ -51,6 +51,15 @@ void main() {
Stdio: () => mockStdio,
Platform: () => fakePlatform,
});
testUsingContext('can test analytics outputs on bots when outputting to a file', () async {
fakePlatform.environment['TRAVIS'] = 'true';
fakePlatform.environment['FLUTTER_ANALYTICS_LOG_FILE'] = '/some/file';
expect(botDetector.isRunningOnBot, isFalse);
}, overrides: <Type, Generator>{
Stdio: () => mockStdio,
Platform: () => fakePlatform,
});
});
});
}
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