Fix `_checkPodCondition` not handling `CocoaPodsStatus.brokenInstall` (#51676)
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart index d748ab1..4283826 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapods.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -143,13 +143,14 @@ throwToolExit('Podfile missing'); } bool podsProcessed = false; - if (await _checkPodCondition()) { - if (_shouldRunPodInstall(xcodeProject, dependenciesChanged)) { - await _runPodInstall(xcodeProject, engineDir); - podsProcessed = true; + if (_shouldRunPodInstall(xcodeProject, dependenciesChanged)) { + if (!await _checkPodCondition()) { + throwToolExit('CocoaPods not installed or not in valid state.'); } - _warnIfPodfileOutOfDate(xcodeProject); + await _runPodInstall(xcodeProject, engineDir); + podsProcessed = true; } + _warnIfPodfileOutOfDate(xcodeProject); return podsProcessed; } @@ -166,6 +167,15 @@ emphasis: true, ); return false; + case CocoaPodsStatus.brokenInstall: + globals.printError( + 'Warning: CocoaPods is installed but broken. Skipping pod install.\n' + '$brokenCocoaPodsConsequence\n' + 'To re-install:\n' + '$cocoaPodsUpgradeInstructions\n', + emphasis: true, + ); + return false; case CocoaPodsStatus.unknownVersion: globals.printError( 'Warning: Unknown CocoaPods version installed.\n' @@ -193,7 +203,7 @@ emphasis: true, ); break; - default: + case CocoaPodsStatus.recommended: break; } if (!await isCocoaPodsInitialized) {
diff --git a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart index ebfd87b..d712f7f 100644 --- a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart
@@ -109,6 +109,22 @@ )).thenAnswer((_) async => exitsWithError()); } + void pretendPodIsBroken() { + // it is present + when(mockProcessManager.run( + <String>['which', 'pod'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenAnswer((_) async => exitsHappy()); + + // but is not working + when(mockProcessManager.run( + <String>['pod', '--version'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenAnswer((_) async => exitsWithError()); + } + void pretendPodIsInstalled() { when(mockProcessManager.run( <String>['which', 'pod'], @@ -306,21 +322,37 @@ podsIsInHomeDir(); }); - testUsingContext('prints error, if CocoaPods is not installed', () async { + testUsingContext('throwsToolExit if CocoaPods is not installed', () async { pretendPodIsNotInstalled(); projectUnderTest.ios.podfile.createSync(); - final bool didInstall = await cocoaPodsUnderTest.processPods( + final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods( xcodeProject: projectUnderTest.ios, engineDir: 'engine/path', ); + expect(invokeProcessPods, throwsToolExit()); verifyNever(mockProcessManager.run( argThat(containsAllInOrder(<String>['pod', 'install'])), workingDirectory: anyNamed('workingDirectory'), environment: anyNamed('environment'), )); - expect(testLogger.errorText, contains('not installed')); - expect(testLogger.errorText, contains('Skipping pod install')); - expect(didInstall, isFalse); + }, overrides: <Type, Generator>{ + FileSystem: () => fs, + ProcessManager: () => mockProcessManager, + }); + + testUsingContext('throwsToolExit if CocoaPods install is broken', () async { + pretendPodIsBroken(); + projectUnderTest.ios.podfile.createSync(); + final Function invokeProcessPods = () async => await cocoaPodsUnderTest.processPods( + xcodeProject: projectUnderTest.ios, + engineDir: 'engine/path', + ); + expect(invokeProcessPods, throwsToolExit()); + verifyNever(mockProcessManager.run( + argThat(containsAllInOrder(<String>['pod', 'install'])), + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )); }, overrides: <Type, Generator>{ FileSystem: () => fs, ProcessManager: () => mockProcessManager,