Unverified Commit 1c4128c7 authored by Chris Yang's avatar Chris Yang Committed by GitHub

Xcode error message (#94747)

parent 710502c4
......@@ -32,6 +32,7 @@ import 'migrations/remove_framework_link_and_embedding_migration.dart';
import 'migrations/xcode_build_system_migration.dart';
import 'xcode_build_settings.dart';
import 'xcodeproj.dart';
import 'xcresult.dart';
class IMobileDevice {
IMobileDevice({
......@@ -315,11 +316,13 @@ Future<XcodeBuildResult> buildXcodeProject({
Status? buildSubStatus;
Status? initialBuildStatus;
Directory? tempDir;
File? scriptOutputPipeFile;
RunResult? buildResult;
XCResult? xcResult;
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_ios_build_temp_dir');
try {
if (globals.logger.hasTerminal) {
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_build_log_pipe.');
scriptOutputPipeFile = tempDir.childFile('pipe_to_stdout');
globals.os.makePipe(scriptOutputPipeFile.path);
......@@ -330,8 +333,6 @@ Future<XcodeBuildResult> buildXcodeProject({
buildSubStatus?.stop();
buildSubStatus = null;
if (line == 'all done') {
// Free pipe file.
tempDir?.deleteSync(recursive: true);
return;
}
} else {
......@@ -352,6 +353,13 @@ Future<XcodeBuildResult> buildXcodeProject({
buildCommands.add('SCRIPT_OUTPUT_STREAM_FILE=${scriptOutputPipeFile.absolute.path}');
}
buildCommands.addAll(<String>[
'-resultBundlePath',
tempDir.childFile(_kResultBundlePath).absolute.path,
'-resultBundleVersion',
_kResultBundleVersion
]);
// Don't log analytics for downstream Flutter commands.
// e.g. `flutter build bundle`.
buildCommands.add('FLUTTER_SUPPRESS_ANALYTICS=true');
......@@ -369,7 +377,7 @@ Future<XcodeBuildResult> buildXcodeProject({
final Stopwatch sw = Stopwatch()..start();
initialBuildStatus = globals.logger.startProgress('Running Xcode build...');
final RunResult? buildResult = await _runBuildWithRetries(buildCommands, app);
buildResult = await _runBuildWithRetries(buildCommands, app);
// Notifies listener that no more output is coming.
scriptOutputPipeFile?.writeAsStringSync('all done');
......@@ -383,6 +391,22 @@ Future<XcodeBuildResult> buildXcodeProject({
);
globals.flutterUsage.sendTiming(xcodeBuildActionToString(buildAction), 'xcode-ios', Duration(milliseconds: sw.elapsedMilliseconds));
if (tempDir.existsSync()) {
// Display additional warning and error message from xcresult bundle.
final Directory resultBundle = tempDir.childDirectory(_kResultBundlePath);
if (!resultBundle.existsSync()) {
globals.printTrace('The xcresult bundle are not generated. Displaying xcresult is disabled.');
} else {
// Discard unwanted errors. See: https://github.com/flutter/flutter/issues/95354
final XCResultIssueDiscarder warningDiscarder = XCResultIssueDiscarder(typeMatcher: XCResultIssueType.warning);
final XCResultIssueDiscarder dartBuildErrorDiscarder = XCResultIssueDiscarder(messageMatcher: RegExp(r'Command PhaseScriptExecution failed with a nonzero exit code'));
final XCResultGenerator xcResultGenerator = XCResultGenerator(resultPath: resultBundle.absolute.path, xcode: globals.xcode!, processUtils: globals.processUtils);
xcResult = await xcResultGenerator.generate(issueDiscarders: <XCResultIssueDiscarder>[warningDiscarder, dartBuildErrorDiscarder]);
}
}
} finally {
tempDir.deleteSync(recursive: true);
}
if (buildResult != null && buildResult.exitCode != 0) {
globals.printStatus('Failed to build iOS app');
if (buildResult.stderr.isNotEmpty) {
......@@ -403,6 +427,7 @@ Future<XcodeBuildResult> buildXcodeProject({
environmentType: environmentType,
buildSettings: buildSettings,
),
xcResult: xcResult,
);
} else {
String? outputDir;
......@@ -466,6 +491,7 @@ Future<XcodeBuildResult> buildXcodeProject({
environmentType: environmentType,
buildSettings: buildSettings,
),
xcResult: xcResult,
);
}
}
......@@ -585,16 +611,19 @@ Future<void> diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsa
logger.printError(' open ios/Runner.xcworkspace');
return;
}
if (result.stdout?.contains('Code Sign error') == true) {
logger.printError('');
logger.printError('It appears that there was a problem signing your application prior to installation on the device.');
logger.printError('');
logger.printError('Verify that the Bundle Identifier in your project is your signing id in Xcode');
logger.printError(' open ios/Runner.xcworkspace');
logger.printError('');
logger.printError("Also try selecting 'Product > Build' to fix the problem:");
// Handle xcresult errors.
final XCResult? xcResult = result.xcResult;
if (xcResult == null) {
return;
}
if (!xcResult.parseSuccess) {
globals.printTrace('XCResult parsing error: ${xcResult.parsingErrorMessage}');
return;
}
for (final XCResultIssue issue in xcResult.issues) {
_handleXCResultIssue(issue: issue, logger: logger);
}
}
/// xcodebuild <buildaction> parameter (see man xcodebuild for details).
......@@ -618,6 +647,7 @@ class XcodeBuildResult {
this.stdout,
this.stderr,
this.xcodeBuildExecution,
this.xcResult
});
final bool success;
......@@ -626,6 +656,10 @@ class XcodeBuildResult {
final String? stderr;
/// The invocation of the build that resulted in this result instance.
final XcodeBuildExecution? xcodeBuildExecution;
/// Parsed information in xcresult bundle.
///
/// Can be null if the bundle is not created during build.
final XCResult? xcResult;
}
/// Describes an invocation of a Xcode build command.
......@@ -686,3 +720,38 @@ bool upgradePbxProjWithFlutterAssets(IosProject project, Logger logger) {
xcodeProjectFile.writeAsStringSync(buffer.toString());
return true;
}
void _handleXCResultIssue({required XCResultIssue issue, required Logger logger}) {
// Issue summary from xcresult.
final StringBuffer issueSummaryBuffer = StringBuffer();
issueSummaryBuffer.write(issue.subType ?? 'Unknown');
issueSummaryBuffer.write(' (Xcode): ');
issueSummaryBuffer.writeln(issue.message ?? '');
if (issue.location != null ) {
issueSummaryBuffer.writeln(issue.location);
}
final String issueSummary = issueSummaryBuffer.toString();
switch (issue.type) {
case XCResultIssueType.error:
logger.printError(issueSummary);
break;
case XCResultIssueType.warning:
logger.printWarning(issueSummary);
break;
}
// Add more custom output for flutter users.
if (issue.message != null && issue.message!.toLowerCase().contains('provisioning profile')) {
logger.printError('');
logger.printError('It appears that there was a problem signing your application prior to installation on the device.');
logger.printError('');
logger.printError('Verify that the Bundle Identifier in your project is your signing id in Xcode');
logger.printError(' open ios/Runner.xcworkspace');
logger.printError('');
logger.printError("Also try selecting 'Product > Build' to fix the problem:");
}
}
const String _kResultBundlePath = 'temporary_xcresult_bundle';
const String _kResultBundleVersion = '3';
......@@ -545,6 +545,7 @@ class IOSSimulator extends Device {
deviceID: id,
);
if (!buildResult.success) {
await diagnoseXcodeBuildFailure(buildResult, globals.flutterUsage, globals.logger);
throwToolExit('Could not build the application for the simulator.');
}
......
......@@ -78,31 +78,8 @@ class XCResult {
/// Parse the `resultJson` and stores useful informations in the returned `XCResult`.
factory XCResult({required Map<String, Object?> resultJson, List<XCResultIssueDiscarder> issueDiscarders = const <XCResultIssueDiscarder>[]}) {
final List<XCResultIssue> issues = <XCResultIssue>[];
final Object? actionsMap = resultJson['actions'];
if (actionsMap == null || actionsMap is! Map<String, Object?>) {
return XCResult.failed(
errorMessage: 'xcresult parser: Failed to parse the actions map.');
}
final Object? actionValueList = actionsMap['_values'];
if (actionValueList == null ||
actionValueList is! List<Object?> ||
actionValueList.isEmpty) {
return XCResult.failed(
errorMessage: 'xcresult parser: Failed to parse the actions map.');
}
final Object? actionMap = actionValueList.first;
if (actionMap == null || actionMap is! Map<String, Object?>) {
return XCResult.failed(
errorMessage:
'xcresult parser: Failed to parse the first action map.');
}
final Object? buildResultMap = actionMap['buildResult'];
if (buildResultMap == null || buildResultMap is! Map<String, Object?>) {
return XCResult.failed(
errorMessage:
'xcresult parser: Failed to parse the buildResult map.');
}
final Object? issuesMap = buildResultMap['issues'];
final Object? issuesMap = resultJson['issues'];
if (issuesMap == null || issuesMap is! Map<String, Object?>) {
return XCResult.failed(
errorMessage: 'xcresult parser: Failed to parse the issues map.');
......
......@@ -14,6 +14,7 @@ import 'package:flutter_tools/src/commands/build_ios.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import '../../general.shard/ios/xcresult_test_data.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/test_flutter_command_runner.dart';
......@@ -88,12 +89,29 @@ void main() {
'build/ios/Release-iphoneos/Runner.app',
'build/ios/iphoneos',
],
onRun: onRun);
onRun: onRun,
);
}
FakeCommand _setUpXCResultCommand({String stdout = '', void Function() onRun}) {
return FakeCommand(
command: const <String>[
'xcrun',
'xcresulttool',
'get',
'--path',
_xcBundleFilePath,
'--format',
'json',
],
stdout: stdout,
onRun: onRun,
);
}
// Creates a FakeCommand for the xcodebuild call to build the app
// in the given configuration.
FakeCommand _setUpFakeXcodeBuildHandler({ bool verbose = false, bool simulator = false, void Function() onRun }) {
FakeCommand _setUpFakeXcodeBuildHandler({ bool verbose = false, bool simulator = false, int exitCode = 0, void Function() onRun }) {
return FakeCommand(
command: <String>[
'xcrun',
......@@ -120,6 +138,8 @@ void main() {
'-destination',
'generic/platform=iOS',
],
'-resultBundlePath', _xcBundleFilePath,
'-resultBundleVersion', '3',
'FLUTTER_SUPPRESS_ANALYTICS=true',
'COMPILER_INDEX_STORE_ENABLE=NO',
],
......@@ -127,6 +147,7 @@ void main() {
TARGET_BUILD_DIR=build/ios/Release-iphoneos
WRAPPER_NAME=Runner.app
''',
exitCode: exitCode,
onRun: onRun,
);
}
......@@ -281,4 +302,257 @@ void main() {
Usage: () => usage,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
group('xcresults device', () {
testUsingContext('Trace error if xcresult is empty.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('xcresult parser: Unrecognized top level json format.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Display xcresult issues on console if parsed.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Do not display xcresult issues that needs to be discarded.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
expect(testLogger.errorText, isNot(contains('Command PhaseScriptExecution failed with a nonzero exit code')));
expect(testLogger.warningText, isNot(contains("The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.")));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Trace if xcresult bundle does not exist.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('The xcresult bundle are not generated. Displaying xcresult is disabled.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Extra error message for provision profile issue in xcresulb bundle.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains('Some Provisioning profile issue.'));
expect(testLogger.errorText, contains('It appears that there was a problem signing your application prior to installation on the device.'));
expect(testLogger.errorText, contains('Verify that the Bundle Identifier in your project is your signing id in Xcode'));
expect(testLogger.errorText, contains('open ios/Runner.xcworkspace'));
expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem:"));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
});
group('xcresults simulator', () {
testUsingContext('Trace error if xcresult is empty.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--simulator', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('xcresult parser: Unrecognized top level json format.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
},
),
_setUpXCResultCommand(),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Display xcresult issues on console if parsed.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--simulator', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
},
),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Do not display xcresult issues that needs to be discarded.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--simulator', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
expect(testLogger.errorText, isNot(contains('Command PhaseScriptExecution failed with a nonzero exit code')));
expect(testLogger.warningText, isNot(contains("The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.")));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
},
),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Trace if xcresult bundle does not exist.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ios', '--simulator', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('The xcresult bundle are not generated. Displaying xcresult is disabled.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(
simulator: true,
exitCode: 1,
),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
_setUpRsyncCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
});
}
const String _xcBundleFilePath = '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle';
......@@ -15,6 +15,7 @@ import 'package:flutter_tools/src/commands/build_ios.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import '../../general.shard/ios/xcresult_test_data.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/test_flutter_command_runner.dart';
......@@ -62,27 +63,43 @@ void main() {
});
// Sets up the minimal mock project files necessary to look like a Flutter project.
void createCoreMockProjectFiles() {
void _createCoreMockProjectFiles() {
fileSystem.file('pubspec.yaml').createSync();
fileSystem.file('.packages').createSync();
fileSystem.file(fileSystem.path.join('lib', 'main.dart')).createSync(recursive: true);
}
// Sets up the minimal mock project files necessary for iOS builds to succeed.
void createMinimalMockProjectFiles() {
void _createMinimalMockProjectFiles() {
fileSystem.directory(fileSystem.path.join('ios', 'Runner.xcodeproj')).createSync(recursive: true);
fileSystem.directory(fileSystem.path.join('ios', 'Runner.xcworkspace')).createSync(recursive: true);
fileSystem.file(fileSystem.path.join('ios', 'Runner.xcodeproj', 'project.pbxproj')).createSync();
createCoreMockProjectFiles();
_createCoreMockProjectFiles();
}
const FakeCommand xattrCommand = FakeCommand(command: <String>[
'xattr', '-r', '-d', 'com.apple.FinderInfo', '/'
]);
FakeCommand _setUpXCResultCommand({String stdout = '', void Function() onRun}) {
return FakeCommand(
command: const <String>[
'xcrun',
'xcresulttool',
'get',
'--path',
_xcBundleFilePath,
'--format',
'json',
],
stdout: stdout,
onRun: onRun,
);
}
// Creates a FakeCommand for the xcodebuild call to build the app
// in the given configuration.
FakeCommand setUpFakeXcodeBuildHandler({ bool verbose = false, void Function() onRun }) {
FakeCommand _setUpFakeXcodeBuildHandler({ bool verbose = false, int exitCode = 0, void Function() onRun }) {
return FakeCommand(
command: <String>[
'xcrun',
......@@ -97,12 +114,15 @@ void main() {
'-sdk', 'iphoneos',
'-destination',
'generic/platform=iOS',
'-resultBundlePath', '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle',
'-resultBundleVersion', '3',
'FLUTTER_SUPPRESS_ANALYTICS=true',
'COMPILER_INDEX_STORE_ENABLE=NO',
'-archivePath', '/build/ios/archive/Runner',
'archive',
],
stdout: 'STDOUT STUFF',
exitCode: exitCode,
onRun: onRun,
);
}
......@@ -125,7 +145,7 @@ void main() {
testUsingContext('ipa build fails when there is no ios project', () async {
final BuildCommand command = BuildCommand();
createCoreMockProjectFiles();
_createCoreMockProjectFiles();
expect(createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub']
......@@ -139,7 +159,7 @@ void main() {
testUsingContext('ipa build fails in debug with code analysis', () async {
final BuildCommand command = BuildCommand();
createCoreMockProjectFiles();
_createCoreMockProjectFiles();
expect(createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '--debug', '--analyze-size']
......@@ -172,7 +192,7 @@ void main() {
testUsingContext('ipa build fails when export plist does not exist',
() async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await expectToolExitLater(
createTestCommandRunner(command).run(<String>[
......@@ -195,7 +215,7 @@ void main() {
testUsingContext('ipa build fails when export plist is not a file', () async {
final Directory bogus = fileSystem.directory('bogus')..createSync();
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await expectToolExitLater(
createTestCommandRunner(command).run(<String>[
......@@ -217,7 +237,7 @@ void main() {
testUsingContext('ipa build invokes xcode build', () async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub']
......@@ -227,7 +247,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(),
_setUpFakeXcodeBuildHandler(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
......@@ -235,7 +255,7 @@ void main() {
testUsingContext('ipa build invokes xcode build with verbosity', () async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '-v']
......@@ -244,7 +264,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(verbose: true),
_setUpFakeXcodeBuildHandler(verbose: true),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
......@@ -252,7 +272,7 @@ void main() {
testUsingContext('code size analysis fails when app not found', () async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await expectToolExitLater(
createTestCommandRunner(command).run(
......@@ -270,7 +290,7 @@ void main() {
testUsingContext('Performs code size analysis and sends analytics', () async {
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
fileSystem.file('build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Frameworks/App.framework/App')
..createSync(recursive: true)
......@@ -289,7 +309,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(onRun: () {
_setUpFakeXcodeBuildHandler(onRun: () {
fileSystem.file('build/flutter_size_01/snapshot.arm64.json')
..createSync(recursive: true)
..writeAsStringSync('''
......@@ -318,7 +338,7 @@ void main() {
final File exportOptions = fileSystem.file('ExportOptions.plist')
..createSync();
final BuildCommand command = BuildCommand();
createMinimalMockProjectFiles();
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
<String>[
......@@ -335,7 +355,7 @@ void main() {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(),
_setUpFakeXcodeBuildHandler(),
exportArchiveCommand,
]),
Platform: () => macosPlatform,
......@@ -343,4 +363,133 @@ void main() {
XcodeProjectInterpreter: () =>
FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Trace error if xcresult is empty.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ipa', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('xcresult parser: Unrecognized top level json format.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Display xcresult issues on console if parsed.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ipa', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Do not display xcresult issues that needs to be discarded.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ipa', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'"));
expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56'));
expect(testLogger.errorText, isNot(contains('Command PhaseScriptExecution failed with a nonzero exit code')));
expect(testLogger.warningText, isNot(contains("The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.")));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Trace if xcresult bundle does not exist.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ipa', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.traceText, contains('The xcresult bundle are not generated. Displaying xcresult is disabled.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Extra error message for provision profile issue in xcresulb bundle.', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectLater(
createTestCommandRunner(command).run(const <String>['build', 'ipa', '--no-pub']),
throwsToolExit(),
);
expect(testLogger.errorText, contains('Some Provisioning profile issue.'));
expect(testLogger.errorText, contains('It appears that there was a problem signing your application prior to installation on the device.'));
expect(testLogger.errorText, contains('Verify that the Bundle Identifier in your project is your signing id in Xcode'));
expect(testLogger.errorText, contains('open ios/Runner.xcworkspace'));
expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem:"));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
}
const String _xcBundleFilePath = '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle';
......@@ -58,6 +58,8 @@ const List<String> kRunReleaseArgs = <String>[
'id=123',
'ONLY_ACTIVE_ARCH=YES',
'ARCHS=arm64',
'-resultBundlePath', '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle',
'-resultBundleVersion', '3',
'FLUTTER_SUPPRESS_ANALYTICS=true',
'COMPILER_INDEX_STORE_ENABLE=NO',
];
......
......@@ -240,58 +240,17 @@ void main() {
'xcresult parser: Unrecognized top level json format.');
});
testWithoutContext('error: fail to parse actions map', () async {
testWithoutContext('error: fail to parse issue map', () async {
final XCResultGenerator generator = _setupGenerator(resultJson: '{}');
final XCResult result = await generator.generate();
expect(result.issues.length, 0);
expect(result.parseSuccess, false);
expect(result.parsingErrorMessage,
'xcresult parser: Failed to parse the actions map.');
});
testWithoutContext('error: empty actions map', () async {
final XCResultGenerator generator =
_setupGenerator(resultJson: kSampleResultJsonEmptyActionsMap);
final XCResult result = await generator.generate();
expect(result.issues.length, 0);
expect(result.parseSuccess, false);
expect(result.parsingErrorMessage,
'xcresult parser: Failed to parse the actions map.');
});
testWithoutContext('error: empty actions map', () async {
final XCResultGenerator generator = _setupGenerator(resultJson: kSampleResultJsonEmptyActionsMap);
final XCResult result = await generator.generate();
expect(result.issues.length, 0);
expect(result.parseSuccess, false);
expect(result.parsingErrorMessage,
'xcresult parser: Failed to parse the actions map.');
});
testWithoutContext('error: empty actions map', () async {
final XCResultGenerator generator = _setupGenerator(resultJson: kSampleResultJsonInvalidActionMap);
final XCResult result = await generator.generate();
expect(result.issues.length, 0);
expect(result.parseSuccess, false);
expect(result.parsingErrorMessage,
'xcresult parser: Failed to parse the first action map.');
});
testWithoutContext('error: empty actions map', () async {
final XCResultGenerator generator = _setupGenerator(resultJson: kSampleResultJsonInvalidBuildResultMap);
final XCResult result = await generator.generate();
expect(result.issues.length, 0);
expect(result.parseSuccess, false);
expect(result.parsingErrorMessage,
'xcresult parser: Failed to parse the buildResult map.');
'xcresult parser: Failed to parse the issues map.');
});
testWithoutContext('error: empty actions map', () async {
testWithoutContext('error: invalid issue map', () async {
final XCResultGenerator generator = _setupGenerator(resultJson: kSampleResultJsonInvalidIssuesMap);
final XCResult result = await generator.generate();
......
......@@ -8,127 +8,106 @@ const String kSampleResultJsonInvalidIssuesMap = r'''
"_type" : {
"_name" : "ActionsInvocationRecord"
},
"actions" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"buildResult": {
}
}
]
}
"issues": []
}
''';
/// An example xcresult bundle json with invalid build result map.
const String kSampleResultJsonInvalidBuildResultMap = r'''
/// An example xcresult bundle json that contains warnings and errors that needs to be discarded per https://github.com/flutter/flutter/issues/95354.
const String kSampleResultJsonWithIssuesToBeDiscarded = r'''
{
"issues" : {
"_type" : {
"_name" : "ActionsInvocationRecord"
"_name" : "ResultIssueSummaries"
},
"actions" : {
"errorSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{}
]
}
}
''';
/// An example xcresult bundle json with invalid action map.
const String kSampleResultJsonInvalidActionMap = r'''
{
{
"_type" : {
"_name" : "ActionsInvocationRecord"
"_name" : "IssueSummary"
},
"actions" : {
"documentLocationInCreatingWorkspace" : {
"_type" : {
"_name" : "Array"
"_name" : "DocumentLocation"
},
"_values" : [
[]
]
}
}
''';
/// An example xcresult bundle json that contains empty actions map.
const String kSampleResultJsonEmptyActionsMap = r'''
{
"concreteTypeName" : {
"_type" : {
"_name" : "ActionsInvocationRecord"
"_name" : "String"
},
"actions" : {
"_value" : "DVTTextDocumentLocation"
},
"url" : {
"_type" : {
"_name" : "Array"
"_name" : "String"
},
"_values" : [
]
"_value" : "file:\/\/\/Users\/m\/Projects\/test_create\/ios\/Runner\/AppDelegate.m#CharacterRangeLen=0&CharacterRangeLoc=263&EndingColumnNumber=56&EndingLineNumber=7&LocationEncoding=1&StartingColumnNumber=56&StartingLineNumber=7"
}
}
''';
/// An example xcresult bundle json that contains some warning and some errors.
const String kSampleResultJsonWithIssues = r'''
{
},
"issueType" : {
"_type" : {
"_name" : "ActionsInvocationRecord"
"_name" : "String"
},
"_value" : "Semantic Issue"
},
"actions" : {
"message" : {
"_type" : {
"_name" : "Array"
"_name" : "String"
},
"_value" : "Use of undeclared identifier 'asdas'"
}
},
"_values" : [
{
"_type" : {
"_name" : "ActionRecord"
"_name" : "IssueSummary"
},
"actionResult" : {
"issueType" : {
"_type" : {
"_name" : "ActionResult"
"_name" : "String"
},
"coverage" : {
"_value" : "Uncategorized"
},
"message" : {
"_type" : {
"_name" : "CodeCoverageInfo"
"_name" : "String"
},
"_value" : "Command PhaseScriptExecution failed with a nonzero exit code"
}
}
]
},
"issues" : {
"warningSummaries" : {
"_type" : {
"_name" : "ResultIssueSummaries"
}
"_name" : "Array"
},
"metrics" : {
"_values" : [
{
"_type" : {
"_name" : "ResultMetrics"
}
"_name" : "IssueSummary"
},
"resultName" : {
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "action"
"_value" : "Warning"
},
"status" : {
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "notRequested"
"_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99."
}
},
"buildResult" : {
"_type" : {
"_name" : "ActionResult"
},
"coverage" : {
"_type" : {
"_name" : "CodeCoverageInfo"
}
},
]
}
}
}
''';
/// An example xcresult bundle json that contains some warning and some errors.
const String kSampleResultJsonWithIssues = r'''
{
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
......@@ -198,1375 +177,127 @@ const String kSampleResultJsonWithIssues = r'''
}
]
}
},
"logRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~bjiFq9EH53z6VfWSr47dakT0w_aGcY_GFqgPuexHq1JsoKMmvf_6GLglMcWBYRCSNufKEX6l1YgbFmnuobsw5w=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActivityLogSection"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
},
"errorCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"warningCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
}
},
"resultName" : {
"_type" : {
"_name" : "String"
},
"_value" : "build"
},
"status" : {
"_type" : {
"_name" : "String"
},
"_value" : "failed"
}
},
"endedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2020-09-28T14:31:16.931-0700"
},
"runDestination" : {
"_type" : {
"_name" : "ActionRunDestinationRecord"
},
"displayName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
},
"localComputerRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"busSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "100"
},
"cpuCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"cpuKind" : {
"_type" : {
"_name" : "String"
},
"_value" : "8-Core Intel Xeon W"
},
"cpuSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "3200"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "87BE7059-56E3-5470-B52D-31A0F76402B3"
},
"isConcreteDevice" : {
"_type" : {
"_name" : "Bool"
},
"_value" : "true"
},
"logicalCPUCoresPerPackage" : {
}
''';
/// An example xcresult bundle json that contains some warning and some errors.
const String kSampleResultJsonWithIssuesAndInvalidUrl = r'''
{
"issues" : {
"_type" : {
"_name" : "Int"
},
"_value" : "16"
"_name" : "ResultIssueSummaries"
},
"modelCode" : {
"errorSummaries" : {
"_type" : {
"_name" : "String"
},
"_value" : "iMacPro1,1"
"_name" : "Array"
},
"modelName" : {
"_values" : [
{
"_type" : {
"_name" : "String"
},
"_value" : "iMac Pro"
"_name" : "IssueSummary"
},
"modelUTI" : {
"documentLocationInCreatingWorkspace" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.imacpro-2017"
"_name" : "DocumentLocation"
},
"name" : {
"concreteTypeName" : {
"_type" : {
"_name" : "String"
},
"_value" : "My Mac"
"_value" : "DVTTextDocumentLocation"
},
"nativeArchitecture" : {
"url" : {
"_type" : {
"_name" : "String"
},
"_value" : "x86_64h"
"_value" : "3:00"
}
},
"operatingSystemVersion" : {
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "10.15.5"
"_value" : "Semantic Issue"
},
"operatingSystemVersionWithBuildNumber" : {
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "10.15.5 (19F101)"
"_value" : "Use of undeclared identifier 'asdas'"
}
}
]
},
"physicalCPUCoresPerPackage" : {
"warningSummaries" : {
"_type" : {
"_name" : "Int"
},
"_value" : "8"
"_name" : "Array"
},
"platformRecord" : {
"_values" : [
{
"_type" : {
"_name" : "ActionPlatformRecord"
"_name" : "IssueSummary"
},
"identifier" : {
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.macosx"
"_value" : "Warning"
},
"userDescription" : {
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "macOS"
"_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99."
}
},
"ramSizeInMegabytes" : {
"_type" : {
"_name" : "Int"
},
"_value" : "65536"
}
},
"targetArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"targetDeviceRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"identifier" : {
]
}
}
}
''';
/// An example xcresult bundle json that contains no issues.
const String kSampleResultJsonNoIssues = r'''
{
"issues" : {
"_type" : {
"_name" : "String"
},
"_value" : "dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder"
},
"modelCode" : {
"_name" : "ResultIssueSummaries"
}
}
}
''';
/// An example xcresult bundle json with some provision profile issue.
const String kSampleResultJsonWithProvisionIssue = r'''
{
"issues" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
"_name" : "ResultIssueSummaries"
},
"modelName" : {
"errorSummaries" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
"_name" : "Array"
},
"modelUTI" : {
"_values" : [
{
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.dt.Xcode.device.GenericiOS"
"_name" : "IssueSummary"
},
"name" : {
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
"_value" : "Semantic Issue"
},
"nativeArchitecture" : {
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"platformRecord" : {
"_type" : {
"_name" : "ActionPlatformRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.iphoneos"
},
"userDescription" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS"
}
}
},
"targetSDKRecord" : {
"_type" : {
"_name" : "ActionSDKRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "iphoneos14.0"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS 14.0"
},
"operatingSystemVersion" : {
"_type" : {
"_name" : "String"
},
"_value" : "14.0"
}
}
},
"schemeCommandName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Run"
},
"schemeTaskName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build"
},
"startedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2020-09-28T14:31:13.125-0700"
},
"title" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build \"Runner\""
}
}
]
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
},
"errorSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"documentLocationInCreatingWorkspace" : {
"_type" : {
"_name" : "DocumentLocation"
},
"concreteTypeName" : {
"_type" : {
"_name" : "String"
},
"_value" : "DVTTextDocumentLocation"
},
"url" : {
"_type" : {
"_name" : "String"
},
"_value" : "file:\/\/\/Users\/m\/Projects\/test_create\/ios\/Runner\/AppDelegate.m#CharacterRangeLen=0&CharacterRangeLoc=263&EndingColumnNumber=56&EndingLineNumber=7&LocationEncoding=1&StartingColumnNumber=56&StartingLineNumber=7"
}
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Semantic Issue"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "Use of undeclared identifier 'asdas'"
}
}
]
},
"warningSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Warning"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99."
}
}
]
}
},
"metadataRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~hrKQOFMo2Ri-TrlvSpVK8vTHcYQxwuWYJuRHCjoxIleliOdh5fHOdfIALZV0S0FtjVmUB83FpKkPbWajga4wxA=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActionsInvocationMetadata"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
},
"errorCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"warningCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
}
}
}
''';
/// An example xcresult bundle json that contains some warning and some errors.
const String kSampleResultJsonWithIssuesAndInvalidUrl = r'''
{
"_type" : {
"_name" : "ActionsInvocationRecord"
},
"actions" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "ActionRecord"
},
"actionResult" : {
"_type" : {
"_name" : "ActionResult"
},
"coverage" : {
"_type" : {
"_name" : "CodeCoverageInfo"
}
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
}
},
"resultName" : {
"_type" : {
"_name" : "String"
},
"_value" : "action"
},
"status" : {
"_type" : {
"_name" : "String"
},
"_value" : "notRequested"
}
},
"buildResult" : {
"_type" : {
"_name" : "ActionResult"
},
"coverage" : {
"_type" : {
"_name" : "CodeCoverageInfo"
}
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
},
"errorSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"documentLocationInCreatingWorkspace" : {
"_type" : {
"_name" : "DocumentLocation"
},
"concreteTypeName" : {
"_type" : {
"_name" : "String"
},
"_value" : "DVTTextDocumentLocation"
},
"url" : {
"_type" : {
"_name" : "String"
},
"_value" : "3:00"
}
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Semantic Issue"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "Use of undeclared identifier 'asdas'"
}
}
]
},
"warningSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Warning"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99."
}
}
]
}
},
"logRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~bjiFq9EH53z6VfWSr47dakT0w_aGcY_GFqgPuexHq1JsoKMmvf_6GLglMcWBYRCSNufKEX6l1YgbFmnuobsw5w=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActivityLogSection"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
},
"errorCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"warningCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
}
},
"resultName" : {
"_type" : {
"_name" : "String"
},
"_value" : "build"
},
"status" : {
"_type" : {
"_name" : "String"
},
"_value" : "failed"
}
},
"endedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2020-09-28T14:31:16.931-0700"
},
"runDestination" : {
"_type" : {
"_name" : "ActionRunDestinationRecord"
},
"displayName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
},
"localComputerRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"busSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "100"
},
"cpuCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"cpuKind" : {
"_type" : {
"_name" : "String"
},
"_value" : "8-Core Intel Xeon W"
},
"cpuSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "3200"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "87BE7059-56E3-5470-B52D-31A0F76402B3"
},
"isConcreteDevice" : {
"_type" : {
"_name" : "Bool"
},
"_value" : "true"
},
"logicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "16"
},
"modelCode" : {
"_type" : {
"_name" : "String"
},
"_value" : "iMacPro1,1"
},
"modelName" : {
"_type" : {
"_name" : "String"
},
"_value" : "iMac Pro"
},
"modelUTI" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.imacpro-2017"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "My Mac"
},
"nativeArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "x86_64h"
},
"operatingSystemVersion" : {
"_type" : {
"_name" : "String"
},
"_value" : "10.15.5"
},
"operatingSystemVersionWithBuildNumber" : {
"_type" : {
"_name" : "String"
},
"_value" : "10.15.5 (19F101)"
},
"physicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "8"
},
"platformRecord" : {
"_type" : {
"_name" : "ActionPlatformRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.macosx"
},
"userDescription" : {
"_type" : {
"_name" : "String"
},
"_value" : "macOS"
}
},
"ramSizeInMegabytes" : {
"_type" : {
"_name" : "Int"
},
"_value" : "65536"
}
},
"targetArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"targetDeviceRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder"
},
"modelCode" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
},
"modelName" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
},
"modelUTI" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.dt.Xcode.device.GenericiOS"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
},
"nativeArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"platformRecord" : {
"_type" : {
"_name" : "ActionPlatformRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.iphoneos"
},
"userDescription" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS"
}
}
},
"targetSDKRecord" : {
"_type" : {
"_name" : "ActionSDKRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "iphoneos14.0"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS 14.0"
},
"operatingSystemVersion" : {
"_type" : {
"_name" : "String"
},
"_value" : "14.0"
}
}
},
"schemeCommandName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Run"
},
"schemeTaskName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build"
},
"startedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2020-09-28T14:31:13.125-0700"
},
"title" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build \"Runner\""
}
}
]
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
},
"errorSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"documentLocationInCreatingWorkspace" : {
"_type" : {
"_name" : "DocumentLocation"
},
"concreteTypeName" : {
"_type" : {
"_name" : "String"
},
"_value" : "DVTTextDocumentLocation"
},
"url" : {
"_type" : {
"_name" : "String"
},
"_value" : "file:\/\/\/Users\/m\/Projects\/test_create\/ios\/Runner\/AppDelegate.m#CharacterRangeLen=0&CharacterRangeLoc=263&EndingColumnNumber=56&EndingLineNumber=7&LocationEncoding=1&StartingColumnNumber=56&StartingLineNumber=7"
}
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Semantic Issue"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "Use of undeclared identifier 'asdas'"
}
}
]
},
"warningSummaries" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "IssueSummary"
},
"issueType" : {
"_type" : {
"_name" : "String"
},
"_value" : "Warning"
},
"message" : {
"_type" : {
"_name" : "String"
},
"_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99."
}
}
]
}
},
"metadataRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~hrKQOFMo2Ri-TrlvSpVK8vTHcYQxwuWYJuRHCjoxIleliOdh5fHOdfIALZV0S0FtjVmUB83FpKkPbWajga4wxA=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActionsInvocationMetadata"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
},
"errorCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"warningCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
}
}
}
''';
/// An example xcresult bundle json that contains no issues.
const String kSampleResultJsonNoIssues = r'''
{
"_type" : {
"_name" : "ActionsInvocationRecord"
},
"actions" : {
"_type" : {
"_name" : "Array"
},
"_values" : [
{
"_type" : {
"_name" : "ActionRecord"
},
"actionResult" : {
"_type" : {
"_name" : "ActionResult"
},
"coverage" : {
"_type" : {
"_name" : "CodeCoverageInfo"
}
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
}
},
"resultName" : {
"_type" : {
"_name" : "String"
},
"_value" : "action"
},
"status" : {
"_type" : {
"_name" : "String"
},
"_value" : "notRequested"
}
},
"buildResult" : {
"_type" : {
"_name" : "ActionResult"
},
"coverage" : {
"_type" : {
"_name" : "CodeCoverageInfo"
}
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
}
},
"logRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~XBP6QfgBACcao7crWD8_8W18SPIqMzlK0U0oBhSvElOM8k-vQKO4ZmCtUhL-BfTDFSylC3qEPStUI3jNsBPTXA=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActivityLogSection"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
}
},
"resultName" : {
"_type" : {
"_name" : "String"
},
"_value" : "build"
},
"status" : {
"_type" : {
"_name" : "String"
},
"_value" : "succeeded"
}
},
"endedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2021-10-27T13:13:38.875-0700"
},
"runDestination" : {
"_type" : {
"_name" : "ActionRunDestinationRecord"
},
"displayName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
},
"localComputerRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"busSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "100"
},
"cpuCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "1"
},
"cpuKind" : {
"_type" : {
"_name" : "String"
},
"_value" : "12-Core Intel Xeon E5"
},
"cpuSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "2700"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "2BE58010-D352-540B-92E6-9A945BA6D36D"
},
"isConcreteDevice" : {
"_type" : {
"_name" : "Bool"
},
"_value" : "true"
},
"logicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "24"
},
"modelCode" : {
"_type" : {
"_name" : "String"
},
"_value" : "MacPro6,1"
},
"modelName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Mac Pro"
},
"modelUTI" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.macpro-cylinder"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "My Mac"
},
"nativeArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "x86_64"
},
"operatingSystemVersion" : {
"_type" : {
"_name" : "String"
},
"_value" : "11.6"
},
"operatingSystemVersionWithBuildNumber" : {
"_type" : {
"_name" : "String"
},
"_value" : "11.6 (20G165)"
},
"physicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "12"
},
"platformRecord" : {
"_type" : {
"_name" : "ActionPlatformRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.macosx"
},
"userDescription" : {
"_type" : {
"_name" : "String"
},
"_value" : "macOS"
}
},
"ramSizeInMegabytes" : {
"_type" : {
"_name" : "Int"
},
"_value" : "65536"
}
},
"targetArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"targetDeviceRecord" : {
"_type" : {
"_name" : "ActionDeviceRecord"
},
"busSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
},
"cpuCount" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
},
"cpuSpeedInMHz" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder"
},
"logicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
},
"modelCode" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
},
"modelName" : {
"_type" : {
"_name" : "String"
},
"_value" : "GenericiOS"
},
"modelUTI" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.dt.Xcode.device.GenericiOS"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "Any iOS Device"
},
"nativeArchitecture" : {
"_type" : {
"_name" : "String"
},
"_value" : "arm64e"
},
"physicalCPUCoresPerPackage" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
},
"platformRecord" : {
"_type" : {
"_name" : "ActionPlatformRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "com.apple.platform.iphoneos"
},
"userDescription" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS"
}
},
"ramSizeInMegabytes" : {
"_type" : {
"_name" : "Int"
},
"_value" : "0"
}
},
"targetSDKRecord" : {
"_type" : {
"_name" : "ActionSDKRecord"
},
"identifier" : {
"_type" : {
"_name" : "String"
},
"_value" : "iphoneos15.0"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "iOS 15.0"
},
"operatingSystemVersion" : {
"_type" : {
"_name" : "String"
},
"_value" : "15.0"
}
}
},
"schemeCommandName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Run"
},
"schemeTaskName" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build"
},
"startedTime" : {
"_type" : {
"_name" : "Date"
},
"_value" : "2021-10-27T13:13:02.396-0700"
},
"title" : {
"_type" : {
"_name" : "String"
},
"_value" : "Build \"XCResultTestApp\""
"_value" : "Some Provisioning profile issue."
}
}
]
},
"issues" : {
"_type" : {
"_name" : "ResultIssueSummaries"
}
},
"metadataRef" : {
"_type" : {
"_name" : "Reference"
},
"id" : {
"_type" : {
"_name" : "String"
},
"_value" : "0~4PY3oMxYEC19JHgIcIfOFnFe-ngUSzJD4NzcBevC8Y2-5y41lCyXxYXhi9eObvKdlU14arnDn8ilaTw6B_bbQQ=="
},
"targetType" : {
"_type" : {
"_name" : "TypeDefinition"
},
"name" : {
"_type" : {
"_name" : "String"
},
"_value" : "ActionsInvocationMetadata"
}
}
},
"metrics" : {
"_type" : {
"_name" : "ResultMetrics"
}
}
}
......
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