Optimize cocoapods logic in flutter doctor. (#25872)

diff --git a/packages/flutter_tools/lib/src/base/user_messages.dart b/packages/flutter_tools/lib/src/base/user_messages.dart
index 4e0e4a8..bfcead6 100644
--- a/packages/flutter_tools/lib/src/base/user_messages.dart
+++ b/packages/flutter_tools/lib/src/base/user_messages.dart
@@ -170,6 +170,11 @@
       '$consequence\n'
       'To install:\n'
       '$installInstructions';
+  String cocoaPodsUnknownVersion(String consequence, String upgradeInstructions) =>
+      'Unknown CocoaPods version installed.\n'
+      '$consequence\n'
+      'To upgrade:\n'
+      '$upgradeInstructions';
   String cocoaPodsOutdated(String recVersion, String consequence, String upgradeInstructions) =>
       'CocoaPods out of date ($recVersion is recommended).\n'
       '$consequence\n'
diff --git a/packages/flutter_tools/lib/src/ios/cocoapods.dart b/packages/flutter_tools/lib/src/ios/cocoapods.dart
index 26a903d..ce1cbbe 100644
--- a/packages/flutter_tools/lib/src/ios/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/ios/cocoapods.dart
@@ -24,6 +24,10 @@
   Without resolving iOS dependencies with CocoaPods, plugins will not work on iOS.
   For more info, see https://flutter.io/platform-plugins''';
 
+const String unknownCocoaPodsConsequence = '''
+  Flutter is unable to determine the installed CocoaPods's version.
+  Ensure that the output of 'pod --version' contains only digits and . to be recognized by Flutter.''';
+
 const String cocoaPodsInstallInstructions = '''
   brew install cocoapods
   pod setup''';
@@ -38,6 +42,8 @@
 enum CocoaPodsStatus {
   /// iOS plugins will not work, installation required.
   notInstalled,
+  /// iOS plugins might not work, upgrade recommended.
+  unknownVersion,
   /// iOS plugins will not work, upgrade required.
   belowMinimumVersion,
   /// iOS plugins may not work in certain situations (Swift, static libraries),
@@ -66,6 +72,8 @@
       return CocoaPodsStatus.notInstalled;
     try {
       final Version installedVersion = Version.parse(versionText);
+      if (installedVersion == null)
+        return CocoaPodsStatus.unknownVersion;
       if (installedVersion < Version.parse(cocoaPodsMinimumVersion))
         return CocoaPodsStatus.belowMinimumVersion;
       else if (installedVersion < Version.parse(cocoaPodsRecommendedVersion))
@@ -112,6 +120,15 @@
           emphasis: true,
         );
         return false;
+      case CocoaPodsStatus.unknownVersion:
+        printError(
+          'Warning: Unknown CocoaPods version installed.\n'
+          '$unknownCocoaPodsConsequence\n'
+          'To upgrade:\n'
+          '$cocoaPodsUpgradeInstructions\n',
+          emphasis: true,
+        );
+        break;
       case CocoaPodsStatus.belowMinimumVersion:
         printError(
           'Warning: CocoaPods minimum required version $cocoaPodsMinimumVersion or greater not installed. Skipping pod install.\n'
diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
index f7cdc35..98b4ef6 100644
--- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
@@ -192,6 +192,11 @@
           status = ValidationType.missing;
           messages.add(ValidationMessage.error(
               userMessages.cocoaPodsMissing(noCocoaPodsConsequence, cocoaPodsInstallInstructions)));
+        }
+        else if (cocoaPodsStatus == CocoaPodsStatus.unknownVersion) {
+          status = ValidationType.partial;
+          messages.add(ValidationMessage.hint(
+              userMessages.cocoaPodsUnknownVersion(unknownCocoaPodsConsequence, cocoaPodsUpgradeInstructions)));
         } else {
           status = ValidationType.partial;
           messages.add(ValidationMessage.hint(
diff --git a/packages/flutter_tools/test/ios/cocoapods_test.dart b/packages/flutter_tools/test/ios/cocoapods_test.dart
index a69b5ac..1d9c3b6 100644
--- a/packages/flutter_tools/test/ios/cocoapods_test.dart
+++ b/packages/flutter_tools/test/ios/cocoapods_test.dart
@@ -94,6 +94,13 @@
       ProcessManager: () => mockProcessManager,
     });
 
+    testUsingContext('detects unknown version', () async {
+      pretendPodVersionIs('Plugin loaded.\n1.5.3');
+      expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.unknownVersion);
+    }, overrides: <Type, Generator>{
+      ProcessManager: () => mockProcessManager,
+    });
+
     testUsingContext('detects below minimum version', () async {
       pretendPodVersionIs('0.39.8');
       expect(await cocoaPodsUnderTest.evaluateCocoaPodsInstallation, CocoaPodsStatus.belowMinimumVersion);
diff --git a/packages/flutter_tools/test/ios/ios_workflow_test.dart b/packages/flutter_tools/test/ios/ios_workflow_test.dart
index b084462..179799d 100644
--- a/packages/flutter_tools/test/ios/ios_workflow_test.dart
+++ b/packages/flutter_tools/test/ios/ios_workflow_test.dart
@@ -297,6 +297,16 @@
       CocoaPods: () => cocoaPods,
     });
 
+    testUsingContext('Emits partial status when CocoaPods is installed with unknown version', () async {
+      when(cocoaPods.evaluateCocoaPodsInstallation)
+          .thenAnswer((_) async => CocoaPodsStatus.unknownVersion);
+      final CocoaPodsTestTarget workflow = CocoaPodsTestTarget();
+      final ValidationResult result = await workflow.validate();
+      expect(result.type, ValidationType.partial);
+    }, overrides: <Type, Generator>{
+      CocoaPods: () => cocoaPods,
+    });
+
     testUsingContext('Emits partial status when CocoaPods is not initialized', () async {
       when(cocoaPods.isCocoaPodsInitialized).thenAnswer((_) async => false);
       final CocoaPodsTestTarget workflow = CocoaPodsTestTarget();