Let injectPlugins integrate custom pods (#26970)

diff --git a/packages/flutter_tools/lib/src/ios/cocoapods.dart b/packages/flutter_tools/lib/src/ios/cocoapods.dart
index 92b7a3e..7686ef8 100644
--- a/packages/flutter_tools/lib/src/ios/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/ios/cocoapods.dart
@@ -193,6 +193,12 @@
       ));
       podfileTemplate.copySync(podfile.path);
     }
+    addPodsDependencyToFlutterXcconfig(iosProject);
+  }
+
+  /// Ensures all `Flutter/Xxx.xcconfig` files for the given iOS sub-project of
+  /// a parent Flutter project include pods configuration.
+  void addPodsDependencyToFlutterXcconfig(IosProject iosProject) {
     _addPodsDependencyToFlutterXcconfig(iosProject, 'Debug');
     _addPodsDependencyToFlutterXcconfig(iosProject, 'Release');
   }
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index cd4827b..5f67181 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -298,9 +298,16 @@
   await _writeAndroidPluginRegistrant(project, plugins);
   await _writeIOSPluginRegistrant(project, plugins);
   if (!project.isModule && project.ios.hostAppRoot.existsSync()) {
+    final IosProject iosProject = IosProject.fromFlutter(project);
     final CocoaPods cocoaPods = CocoaPods();
-    if (plugins.isNotEmpty)
+    if (plugins.isNotEmpty) {
       cocoaPods.setupPodfile(project.ios);
+    }
+    /// The user may have a custom maintained Podfile that they're running `pod install`
+    /// on themselves.
+    else if (iosProject.podfile.existsSync() && iosProject.podfileLock.existsSync()) {
+      cocoaPods.addPodsDependencyToFlutterXcconfig(iosProject);
+    }
   }
 }
 
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 4c5496b..9e4bdac 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -89,7 +89,7 @@
   }
 
   /// The iOS sub project of this project.
-  IosProject get ios => IosProject._(this);
+  IosProject get ios => IosProject.fromFlutter(this);
 
   /// The Android sub project of this project.
   AndroidProject get android => AndroidProject._(this);
@@ -151,7 +151,7 @@
 /// Instances will reflect the contents of the `ios/` sub-folder of
 /// Flutter applications and the `.ios/` sub-folder of Flutter module projects.
 class IosProject {
-  IosProject._(this.parent);
+  IosProject.fromFlutter(this.parent);
 
   /// The parent of this project.
   final FlutterProject parent;
diff --git a/packages/flutter_tools/test/ios/cocoapods_test.dart b/packages/flutter_tools/test/ios/cocoapods_test.dart
index 1d9c3b6..a769fa7 100644
--- a/packages/flutter_tools/test/ios/cocoapods_test.dart
+++ b/packages/flutter_tools/test/ios/cocoapods_test.dart
@@ -9,6 +9,7 @@
 import 'package:flutter_tools/src/base/common.dart';
 import 'package:flutter_tools/src/base/io.dart';
 import 'package:flutter_tools/src/cache.dart';
+import 'package:flutter_tools/src/plugins.dart';
 import 'package:flutter_tools/src/project.dart';
 import 'package:flutter_tools/src/ios/cocoapods.dart';
 import 'package:flutter_tools/src/ios/xcodeproj.dart';
@@ -202,6 +203,34 @@
     });
   });
 
+  group('Update xcconfig', () {
+    testUsingContext('includes Pod config in xcconfig files, if the user manually added Pod dependencies without using Flutter plugins', () async {
+      projectUnderTest.ios.podfile..createSync()..writeAsStringSync('Custom Podfile');
+      projectUnderTest.ios.podfileLock..createSync()..writeAsStringSync('Podfile.lock from user executed `pod install`');
+      projectUnderTest.packagesFile..createSync()..writeAsStringSync('');
+      projectUnderTest.ios.xcodeConfigFor('Debug')
+        ..createSync(recursive: true)
+        ..writeAsStringSync('Existing debug config');
+      projectUnderTest.ios.xcodeConfigFor('Release')
+        ..createSync(recursive: true)
+        ..writeAsStringSync('Existing release config');
+
+      final FlutterProject project = await FlutterProject.fromPath('project');
+      await injectPlugins(project);
+
+      final String debugContents = projectUnderTest.ios.xcodeConfigFor('Debug').readAsStringSync();
+      expect(debugContents, contains(
+          '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"\n'));
+      expect(debugContents, contains('Existing debug config'));
+      final String releaseContents = projectUnderTest.ios.xcodeConfigFor('Release').readAsStringSync();
+      expect(releaseContents, contains(
+          '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n'));
+      expect(releaseContents, contains('Existing release config'));
+    }, overrides: <Type, Generator>{
+      FileSystem: () => fs,
+    });
+  });
+
   group('Process pods', () {
     testUsingContext('prints error, if CocoaPods is not installed', () async {
       pretendPodIsNotInstalled();