Unverified Commit 802d872d authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Revert "Export an IPA for distribution via "flutter build ipa" without...

Revert "Export an IPA for distribution via "flutter build ipa" without --export-options-plist" (#97616)
parent dff9126d
......@@ -19,8 +19,6 @@ Future<void> main() async {
await inDirectory(flutterProject.rootPath, () async {
await flutter('build', options: <String>[
'xcarchive',
'--export-method',
'development',
]);
});
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'package:file/file.dart';
import 'package:meta/meta.dart';
import '../base/analyze_size.dart';
import '../base/common.dart';
......@@ -67,23 +66,12 @@ class BuildIOSCommand extends _BuildIOSSubCommand {
class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
BuildIOSArchiveCommand({required bool verboseHelp})
: super(verboseHelp: verboseHelp) {
argParser.addOption(
'export-method',
defaultsTo: 'app-store',
allowed: <String>['app-store', 'ad-hoc', 'development'],
help: 'Specify how the IPA will be distributed.',
allowedHelp: <String, String>{
'app-store': 'Upload to the App Store.',
'ad-hoc': 'Distribute to designated devices that do not need to be registered with the Apple developer account. '
'Requires a distribution certificate.',
'development': 'Distribute only to development devices registered with the Apple developer account.',
},
);
argParser.addOption(
'export-options-plist',
valueHelp: 'ExportOptions.plist',
// TODO(jmagman): Update help text with link to Flutter docs.
help:
'Export an IPA with these options. See "xcodebuild -h" for available exportOptionsPlist keys.',
'Optionally export an IPA with these options. See "xcodebuild -h" for available exportOptionsPlist keys.',
);
}
......@@ -94,7 +82,7 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
final List<String> aliases = <String>['xcarchive'];
@override
final String description = 'Build an iOS archive bundle and IPA for distribution (Mac OS X host only).';
final String description = 'Build an iOS archive bundle (Mac OS X host only).';
@override
final XcodeBuildAction xcodeBuildAction = XcodeBuildAction.archive;
......@@ -117,16 +105,9 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
.childDirectory('Applications');
@override
Future<void> validateCommand() async {
Future<FlutterCommandResult> runCommand() async {
final String? exportOptions = exportOptionsPlist;
if (exportOptions != null) {
if (argResults?.wasParsed('export-method') == true) {
throwToolExit(
'"--export-options-plist" is not compatible with "--export-method". Either use "--export-options-plist" and '
'a plist describing how the IPA should be exported by Xcode, or use "--export-method" to create a new plist.\n'
'See "xcodebuild -h" for available exportOptionsPlist keys.'
);
}
final FileSystemEntityType type = globals.fs.typeSync(exportOptions);
if (type == FileSystemEntityType.notFound) {
throwToolExit(
......@@ -136,15 +117,14 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
'"$exportOptions" is not a file. See "xcodebuild -h" for available keys.');
}
}
return super.validateCommand();
}
@override
Future<FlutterCommandResult> runCommand() async {
final FlutterCommandResult xcarchiveResult = await super.runCommand();
final BuildInfo buildInfo = await getBuildInfo();
displayNullSafetyMode(buildInfo);
if (exportOptions == null) {
return xcarchiveResult;
}
// xcarchive failed or not at expected location.
if (xcarchiveResult.exitStatus != ExitStatus.success) {
globals.printStatus('Skipping IPA');
......@@ -155,20 +135,9 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
final BuildableIOSApp app = await buildableIOSApp;
Status? status;
RunResult? result;
final String relativeOutputPath = app.ipaOutputPath;
final String absoluteOutputPath = globals.fs.path.absolute(relativeOutputPath);
final String absoluteArchivePath = globals.fs.path.absolute(app.archiveBundleOutputPath);
final String exportMethod = stringArg('export-method')!;
final bool isAppStoreUpload = exportMethod == 'app-store';
File? generatedExportPlist;
final String outputPath = globals.fs.path.absolute(app.ipaOutputPath);
try {
final String exportMethodDisplayName = isAppStoreUpload ? 'App Store' : exportMethod;
status = globals.logger.startProgress('Building $exportMethodDisplayName IPA...');
String? exportOptions = exportOptionsPlist;
if (exportOptions == null) {
generatedExportPlist = _createExportPlist();
exportOptions = generatedExportPlist.path;
}
status = globals.logger.startProgress('Building IPA...');
result = await globals.processUtils.run(
<String>[
......@@ -180,15 +149,14 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
'-allowProvisioningUpdates',
],
'-archivePath',
absoluteArchivePath,
globals.fs.path.absolute(app.archiveBundleOutputPath),
'-exportPath',
absoluteOutputPath,
outputPath,
'-exportOptionsPlist',
globals.fs.path.absolute(exportOptions),
],
);
} finally {
generatedExportPlist?.deleteSync();
status?.stop();
}
......@@ -203,68 +171,13 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
LineSplitter.split(result.stderr)
.where((String line) => line.contains('error: '))
.forEach(errorMessage.writeln);
globals.printError('Encountered error while creating the IPA:');
globals.printError(errorMessage.toString());
globals.printError('Try distributing the app in Xcode: "open $absoluteArchivePath"');
throwToolExit(null);
throwToolExit('Encountered error while building IPA:\n$errorMessage');
}
globals.printStatus('Built IPA to $absoluteOutputPath.');
if (isAppStoreUpload) {
globals.printStatus('To upload to the App Store either:');
globals.printStatus(
'1. Drag and drop the "$relativeOutputPath/*.ipa" bundle into the Apple Transport macOS app https://apps.apple.com/us/app/transporter/id1450874784',
indent: 4,
);
globals.printStatus(
'2. Run "xcrun altool --upload-app --type ios -f $relativeOutputPath/*.ipa --apiKey your_api_key --apiIssuer your_issuer_id".',
indent: 4,
);
globals.printStatus(
'See "man altool" for details about how to authenticate with the App Store Connect API key.',
indent: 7,
);
}
globals.printStatus('Built IPA to $outputPath.');
return FlutterCommandResult.success();
}
File _createExportPlist() {
// Create the plist to be passed into xcodebuild -exportOptionsPlist.
final StringBuffer plistContents = StringBuffer('''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
''');
plistContents.write('''
<string>${stringArg('export-method')}</string>
''');
if (xcodeBuildResult?.xcodeBuildExecution?.buildSettings['ENABLE_BITCODE'] != 'YES') {
// Bitcode is off by default in Flutter iOS apps.
plistContents.write('''
<key>uploadBitcode</key>
<false/>
</dict>
</plist>
''');
} else {
plistContents.write('''
</dict>
</plist>
''');
}
final File tempPlist = globals.fs.systemTempDirectory
.createTempSync('flutter_build_ios.').childFile('ExportOptions.plist');
tempPlist.writeAsStringSync(plistContents.toString());
return tempPlist;
}
}
abstract class _BuildIOSSubCommand extends BuildSubCommand {
......@@ -295,10 +208,6 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
};
XcodeBuildAction get xcodeBuildAction;
/// The result of the Xcode build command. Null until it finishes.
@protected
XcodeBuildResult? xcodeBuildResult;
EnvironmentType get environmentType;
bool get configOnly;
bool get shouldCodesign;
......@@ -362,7 +271,6 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
buildAction: xcodeBuildAction,
deviceID: globals.deviceManager?.specifiedDeviceId,
);
xcodeBuildResult = result;
if (!result.success) {
await diagnoseXcodeBuildFailure(result, globals.flutterUsage, globals.logger);
......
......@@ -7,6 +7,7 @@
import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build.dart';
......@@ -17,14 +18,9 @@ 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/fake_process_manager.dart';
import '../../src/test_flutter_command_runner.dart';
class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInterpreter {
FakeXcodeProjectInterpreterWithBuildSettings({ this.overrides = const <String, String>{} });
final Map<String, String> overrides;
@override
Future<Map<String, String>> getBuildSettings(
String projectPath, {
......@@ -32,7 +28,6 @@ class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInter
Duration timeout = const Duration(minutes: 1),
}) async {
return <String, String>{
...overrides,
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
'DEVELOPMENT_TEAM': 'abc',
};
......@@ -55,7 +50,7 @@ final Platform notMacosPlatform = FakePlatform(
void main() {
FileSystem fileSystem;
TestUsage usage;
FakeProcessManager fakeProcessManager;
BufferLogger logger;
setUpAll(() {
Cache.disableLocking();
......@@ -64,7 +59,7 @@ void main() {
setUp(() {
fileSystem = MemoryFileSystem.test();
usage = TestUsage();
fakeProcessManager = FakeProcessManager.empty();
logger = BufferLogger.test();
});
// Sets up the minimal mock project files necessary to look like a Flutter project.
......@@ -132,11 +127,7 @@ void main() {
);
}
FakeCommand _exportArchiveCommand({
String exportOptionsPlist = '/ExportOptions.plist',
File cachePlist,
}) {
return FakeCommand(
const FakeCommand exportArchiveCommand = FakeCommand(
command: <String>[
'xcrun',
'xcodebuild',
......@@ -148,17 +139,9 @@ void main() {
'-exportPath',
'/build/ios/ipa',
'-exportOptionsPlist',
exportOptionsPlist,
'/ExportOptions.plist'
],
onRun: () {
// exportOptionsPlist will be cleaned up within the command.
// Save it somewhere else so test expectations can be run on it.
if (cachePlist != null) {
cachePlist.writeAsStringSync(fileSystem.file(_exportOptionsPlist).readAsStringSync());
}
}
);
}
testUsingContext('ipa build fails when there is no ios project', () async {
final BuildCommand command = BuildCommand();
......@@ -252,167 +235,37 @@ void main() {
FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('ipa build fails when --export-options-plist and --export-method are used together', () async {
final BuildCommand command = BuildCommand();
_createMinimalMockProjectFiles();
await expectToolExitLater(
createTestCommandRunner(command).run(<String>[
'build',
'ipa',
'--export-options-plist',
'ExportOptions.plist',
'--export-method',
'app-store',
'--no-pub',
]),
contains('"--export-options-plist" is not compatible with "--export-method"'),
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () =>
FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('ipa build invokes xcodebuild and archives for app store', () async {
final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist');
testUsingContext('ipa build invokes xcode build', () async {
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(),
_exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub']
);
const String expectedIpaPlistContents = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>uploadBitcode</key>
<false/>
</dict>
</plist>
''';
final String actualIpaPlistContents = fileSystem.file(cachedExportOptionsPlist).readAsStringSync();
expect(actualIpaPlistContents, expectedIpaPlistContents);
expect(testLogger.statusText, contains('build/ios/archive/Runner.xcarchive'));
expect(testLogger.statusText, contains('Building App Store IPA'));
expect(testLogger.statusText, contains('Built IPA to /build/ios/ipa'));
expect(testLogger.statusText, contains('To upload to the App Store'));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('ipa build invokes xcodebuild and archives for ad-hoc distribution', () async {
final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist');
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(),
_exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '--export-method', 'ad-hoc']
);
const String expectedIpaPlistContents = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>ad-hoc</string>
<key>uploadBitcode</key>
<false/>
</dict>
</plist>
''';
final String actualIpaPlistContents = fileSystem.file(cachedExportOptionsPlist).readAsStringSync();
expect(actualIpaPlistContents, expectedIpaPlistContents);
expect(testLogger.statusText, contains('build/ios/archive/Runner.xcarchive'));
expect(testLogger.statusText, contains('Building ad-hoc IPA'));
expect(testLogger.statusText, contains('Built IPA to /build/ios/ipa'));
// Don't instruct how to upload to the App Store.
expect(testLogger.statusText, isNot(contains('To upload')));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('ipa build invokes xcodebuild and archives with bitcode on', () async {
final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist');
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(),
_exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist, cachePlist: cachedExportOptionsPlist),
]);
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub',]
);
const String expectedIpaPlistContents = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
</dict>
</plist>
''';
final String actualIpaPlistContents = fileSystem.file(cachedExportOptionsPlist).readAsStringSync();
expect(actualIpaPlistContents, expectedIpaPlistContents);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(
overrides: <String, String>{'ENABLE_BITCODE': 'YES'},
),
});
testUsingContext('ipa build invokes xcode build with verbosity', () async {
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(verbose: true),
_exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '-v']
);
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(verbose: true),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
......@@ -442,7 +295,19 @@ void main() {
fileSystem.file('build/ios/archive/Runner.xcarchive/Products/Applications/Runner.app/Frameworks/App.framework/App')
..createSync(recursive: true)
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
fakeProcessManager.addCommands(<FakeCommand>[
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '--analyze-size']
);
expect(testLogger.statusText, contains('A summary of your iOS bundle analysis can be found at'));
expect(testLogger.statusText, contains('flutter pub global activate devtools; flutter pub global run devtools --appSizeBase='));
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'ios'),
));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(onRun: () {
fileSystem.file('build/flutter_size_01/snapshot.arm64.json')
......@@ -460,39 +325,19 @@ void main() {
..createSync(recursive: true)
..writeAsStringSync('{}');
}),
_exportArchiveCommand(exportOptionsPlist: _exportOptionsPlist),
]);
await createTestCommandRunner(command).run(
const <String>['build', 'ipa', '--no-pub', '--analyze-size']
);
expect(testLogger.statusText, contains('A summary of your iOS bundle analysis can be found at'));
expect(testLogger.statusText, contains('flutter pub global activate devtools; flutter pub global run devtools --appSizeBase='));
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'ios'),
));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
]),
Platform: () => macosPlatform,
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
Usage: () => usage,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('ipa build invokes xcode build export archive when passed plist', () async {
testUsingContext('ipa build invokes xcode build export archive', () async {
final String outputPath =
fileSystem.path.absolute(fileSystem.path.join('build', 'ios', 'ipa'));
final File exportOptions = fileSystem.file('ExportOptions.plist')
..createSync();
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(),
_exportArchiveCommand(),
]);
_createMinimalMockProjectFiles();
await createTestCommandRunner(command).run(
......@@ -505,25 +350,23 @@ void main() {
],
);
expect(testLogger.statusText, contains('Built IPA to $outputPath.'));
expect(fakeProcessManager, hasNoRemainingExpectations);
expect(logger.statusText, contains('Built IPA to $outputPath.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(),
exportArchiveCommand,
]),
Platform: () => macosPlatform,
Logger: () => logger,
XcodeProjectInterpreter: () =>
FakeXcodeProjectInterpreterWithBuildSettings(),
});
testUsingContext('Trace error if xcresult is empty.', () async {
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(),
]);
_createMinimalMockProjectFiles();
await expectLater(
......@@ -532,23 +375,22 @@ void main() {
);
expect(testLogger.traceText, contains('xcresult parser: Unrecognized top level json format.'));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
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();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
]);
_createMinimalMockProjectFiles();
await expectLater(
......@@ -558,23 +400,22 @@ void main() {
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(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
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();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
]);
_createMinimalMockProjectFiles();
await expectLater(
......@@ -586,20 +427,22 @@ void main() {
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.")));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
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();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1),
]);
_createMinimalMockProjectFiles();
await expectLater(
......@@ -608,10 +451,13 @@ void main() {
);
expect(testLogger.traceText, contains('The xcresult bundle are not generated. Displaying xcresult is disabled.'));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1),
_setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
]),
Platform: () => macosPlatform,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
......@@ -619,13 +465,7 @@ void main() {
testUsingContext('Extra error message for provision profile issue in xcresulb bundle.', () async {
final BuildCommand command = BuildCommand();
fakeProcessManager.addCommands(<FakeCommand>[
xattrCommand,
_setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
}),
_setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue),
]);
_createMinimalMockProjectFiles();
await expectLater(
......@@ -638,14 +478,18 @@ void main() {
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:"));
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => fakeProcessManager,
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';
const String _exportOptionsPlist = '/.tmp_rand0/flutter_build_ios.rand0/ExportOptions.plist';
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