Rerun pod install on changed Xcode project, Podfile (#17274)
If the developer changes their Xcode build settings and their project
has plugins, pod install is required, (e.g. to pick up changes to the
target architecture).
Similarly, manual edits to the Podfile should trigger a pod install.
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index dc1320a..2ea5189 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -11,6 +11,7 @@
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
+import '../base/fingerprint.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
@@ -193,7 +194,7 @@
bool codesign: true,
bool usesTerminalUi: true,
}) async {
- if (!await upgradePbxProjWithFlutterAssets(app.name))
+ if (!await upgradePbxProjWithFlutterAssets(app.name, app.appDirectory))
return new XcodeBuildResult(success: false);
if (!_checkXcodeVersion())
@@ -241,7 +242,6 @@
// copied over to a location that is suitable for Xcodebuild to find them.
final Directory appDirectory = fs.directory(app.appDirectory);
await _addServicesToBundle(appDirectory);
- final String previousGeneratedXcconfig = readGeneratedXcconfig(app.appDirectory);
updateGeneratedXcodeProperties(
projectPath: fs.currentDirectory.path,
@@ -251,13 +251,26 @@
);
if (hasPlugins()) {
- final String currentGeneratedXcconfig = readGeneratedXcconfig(app.appDirectory);
- await cocoaPods.processPods(
+ final String iosPath = fs.path.join(fs.currentDirectory.path, app.appDirectory);
+ // If the Xcode project, Podfile, or Generated.xcconfig have changed since
+ // last run, pods should be updated.
+ final Fingerprinter fingerprinter = new Fingerprinter(
+ fingerprintPath: fs.path.join(getIosBuildDirectory(), 'pod_inputs.fingerprint'),
+ paths: <String>[
+ _getPbxProjPath(app.appDirectory),
+ fs.path.join(iosPath, 'Podfile'),
+ fs.path.join(iosPath, 'Flutter', 'Generated.xcconfig'),
+ ],
+ properties: <String, String>{},
+ );
+ final bool didPodInstall = await cocoaPods.processPods(
appIosDirectory: appDirectory,
iosEngineDir: flutterFrameworkDir(buildInfo.mode),
isSwift: app.isSwift,
- flutterPodChanged: previousGeneratedXcconfig != currentGeneratedXcconfig,
+ dependenciesChanged: !await fingerprinter.doesFingerprintMatch()
);
+ if (didPodInstall)
+ await fingerprinter.writeFingerprint();
}
// If buildNumber is not specified, keep the project untouched.
@@ -614,6 +627,9 @@
}
}
+/// The path of the Xcode project file.
+String _getPbxProjPath(String appPath) => fs.path.join(fs.currentDirectory.path, appPath, 'Runner.xcodeproj', 'project.pbxproj');
+
void _copyServiceDefinitionsManifest(List<Map<String, String>> services, File manifest) {
printTrace("Creating service definitions manifest at '${manifest.path}'");
final List<Map<String, String>> jsonServices = services.map((Map<String, String> service) => <String, String>{
@@ -626,9 +642,8 @@
manifest.writeAsStringSync(json.encode(jsonObject), mode: FileMode.write, flush: true);
}
-Future<bool> upgradePbxProjWithFlutterAssets(String app) async {
- final File xcodeProjectFile = fs.file(fs.path.join('ios', 'Runner.xcodeproj',
- 'project.pbxproj'));
+Future<bool> upgradePbxProjWithFlutterAssets(String app, String appPath) async {
+ final File xcodeProjectFile = fs.file(_getPbxProjPath(appPath));
assert(await xcodeProjectFile.exists());
final List<String> lines = await xcodeProjectFile.readAsLines();
@@ -651,7 +666,7 @@
if (!lines.contains(l1) || !lines.contains(l3) ||
!lines.contains(l5) || !lines.contains(l7)) {
printError('Automatic upgrade of project.pbxproj failed.');
- printError(' To manually upgrade, open ios/Runner.xcodeproj/project.pbxproj:');
+ printError(' To manually upgrade, open ${xcodeProjectFile.path}:');
printError(' Add the following line in the "PBXBuildFile" section');
printError(l2);
printError(' Add the following line in the "PBXFileReference" section');