From e826c63aec783faa561de853916bc3daa9381fa7 Mon Sep 17 00:00:00 2001 From: Victoria Ashworth <15619084+vashworth@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:25:17 -0600 Subject: [PATCH] Fix file deletion crash in BuildIOSArchiveCommand.runCommand (#138734) Fixes https://github.com/flutter/flutter/issues/138030 --- .../lib/src/commands/build_ios.dart | 5 ++- .../hermetic/build_ipa_test.dart | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index 5d8f434d14..98fb199d39 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -11,6 +11,7 @@ import 'package:unified_analytics/unified_analytics.dart'; import '../base/analyze_size.dart'; import '../base/common.dart'; +import '../base/error_handling_io.dart'; import '../base/logger.dart'; import '../base/process.dart'; import '../base/utils.dart'; @@ -492,7 +493,9 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { ], ); } finally { - generatedExportPlist?.deleteSync(); + if (generatedExportPlist != null) { + ErrorHandlingFileSystem.deleteIfExists(generatedExportPlist); + } status?.stop(); } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart index 802226b510..9c71896457 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart @@ -180,6 +180,7 @@ void main() { FakeCommand exportArchiveCommand({ String exportOptionsPlist = '/ExportOptions.plist', File? cachePlist, + bool deleteExportOptionsPlist = false, }) { return FakeCommand( command: [ @@ -201,6 +202,9 @@ void main() { if (cachePlist != null) { cachePlist.writeAsStringSync(fileSystem.file(_exportOptionsPlist).readAsStringSync()); } + if (deleteExportOptionsPlist) { + fileSystem.file(_exportOptionsPlist).deleteSync(); + } } ); } @@ -419,6 +423,40 @@ void main() { XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), }); + testUsingContext('ipa build ignores deletion failure if generatedExportPlist does not exist', () async { + final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist'); + final BuildCommand command = BuildCommand( + artifacts: artifacts, + androidSdk: FakeAndroidSdk(), + buildSystem: TestBuildSystem.all(BuildResult(success: true)), + logger: logger, + fileSystem: fileSystem, + processUtils: processUtils, + osUtils: FakeOperatingSystemUtils(), + ); + fakeProcessManager.addCommands([ + xattrCommand, + setUpFakeXcodeBuildHandler(), + exportArchiveCommand( + exportOptionsPlist: _exportOptionsPlist, + cachePlist: cachedExportOptionsPlist, + deleteExportOptionsPlist: true, + ), + ]); + createMinimalMockProjectFiles(); + + await createTestCommandRunner(command).run( + const ['build', 'ipa', '--no-pub'] + ); + expect(fakeProcessManager, hasNoRemainingExpectations); + }, overrides: { + FileSystem: () => fileSystem, + Logger: () => logger, + ProcessManager: () => fakeProcessManager, + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), + }); + testUsingContext('ipa build invokes xcodebuild and archives for app store', () async { final File cachedExportOptionsPlist = fileSystem.file('/CachedExportOptions.plist'); final BuildCommand command = BuildCommand(