Harden macOS build use of Xcode project getInfo (#40375)
- Makes build_macos.dart handle the case where there is only one Xcode
project in the macos/ directory, but it's not called Runner.xcodeproj
- Makes getInfo throw a tool exit when trying to get project info and it
can't find a project, since that is a configuration error by the user
rather than a tool bug.
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 181905f..8723faf 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -7,6 +7,7 @@
import 'package:meta/meta.dart';
import '../artifacts.dart';
+import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
@@ -331,6 +332,10 @@
}
Future<XcodeProjectInfo> getInfo(String projectPath, {String projectFilename}) async {
+ // The exit code returned by 'xcodebuild -list' when either:
+ // * -project is passed and the given project isn't there, or
+ // * no -project is passed and there isn't a project.
+ const int missingProjectExitCode = 66;
final RunResult result = await processUtils.run(
<String>[
_executable,
@@ -338,8 +343,12 @@
if (projectFilename != null) ...<String>['-project', projectFilename],
],
throwOnError: true,
+ whiteListFailures: (int c) => c == missingProjectExitCode,
workingDirectory: projectPath,
);
+ if (result.exitCode == missingProjectExitCode) {
+ throwToolExit('Unable to get Xcode project information:\n ${result.stderr}');
+ }
return XcodeProjectInfo.fromXcodeBuildOutput(result.toString());
}
}
diff --git a/packages/flutter_tools/lib/src/macos/build_macos.dart b/packages/flutter_tools/lib/src/macos/build_macos.dart
index 0aa94f5..678c14c 100644
--- a/packages/flutter_tools/lib/src/macos/build_macos.dart
+++ b/packages/flutter_tools/lib/src/macos/build_macos.dart
@@ -46,9 +46,13 @@
final Directory xcodeProject = flutterProject.macos.xcodeProject;
+ // If the standard project exists, specify it to getInfo to handle the case where there are
+ // other Xcode projects in the macos/ directory. Otherwise pass no name, which will work
+ // regardless of the project name so long as there is exactly one project.
+ final String xcodeProjectName = xcodeProject.existsSync() ? xcodeProject.basename : null;
final XcodeProjectInfo projectInfo = await xcodeProjectInterpreter.getInfo(
xcodeProject.parent.path,
- projectFilename: xcodeProject.basename,
+ projectFilename: xcodeProjectName,
);
final String scheme = projectInfo.schemeFor(buildInfo);
if (scheme == null) {