[script/tool] speed up the pub get portion of the analyze command (#3982)

diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart
index b36c43e..872645e 100644
--- a/script/tool/lib/src/analyze_command.dart
+++ b/script/tool/lib/src/analyze_command.dart
@@ -41,6 +41,7 @@
   @override
   Future<void> run() async {
     print('Verifying analysis settings...');
+
     final List<FileSystemEntity> files = packagesDir.listSync(recursive: true);
     for (final FileSystemEntity file in files) {
       if (file.basename != 'analysis_options.yaml' &&
@@ -64,6 +65,14 @@
     }
 
     final List<Directory> packageDirectories = await getPackages().toList();
+    final Set<String> packagePaths =
+        packageDirectories.map((Directory dir) => dir.path).toSet();
+    packageDirectories.removeWhere((Directory directory) {
+      // We remove the 'example' subdirectories - 'flutter pub get' automatically
+      // runs 'pub get' there as part of handling the parent directory.
+      return directory.basename == 'example' &&
+          packagePaths.contains(directory.parent.path);
+    });
     for (final Directory package in packageDirectories) {
       await processRunner.runAndStream('flutter', <String>['packages', 'get'],
           workingDir: package, exitOnError: true);
@@ -86,6 +95,7 @@
     }
 
     print('\n\n');
+
     if (failingPackages.isNotEmpty) {
       print('The following packages have analyzer errors (see above):');
       for (final String package in failingPackages) {
diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart
index 5e548cb..b536c2b 100644
--- a/script/tool/test/analyze_command_test.dart
+++ b/script/tool/test/analyze_command_test.dart
@@ -53,6 +53,47 @@
         ]));
   });
 
+  test('skips flutter pub get for examples', () async {
+    final Directory plugin1Dir = createFakePlugin('a', withSingleExample: true);
+
+    final MockProcess mockProcess = MockProcess();
+    mockProcess.exitCodeCompleter.complete(0);
+    processRunner.processToReturn = mockProcess;
+    await runner.run(<String>['analyze']);
+
+    expect(
+        processRunner.recordedCalls,
+        orderedEquals(<ProcessCall>[
+          ProcessCall(
+              'flutter', const <String>['packages', 'get'], plugin1Dir.path),
+          ProcessCall('dart', const <String>['analyze', '--fatal-infos'],
+              plugin1Dir.path),
+        ]));
+  });
+
+  test('don\'t elide a non-contained example package', () async {
+    final Directory plugin1Dir = createFakePlugin('a');
+    final Directory plugin2Dir = createFakePlugin('example');
+
+    final MockProcess mockProcess = MockProcess();
+    mockProcess.exitCodeCompleter.complete(0);
+    processRunner.processToReturn = mockProcess;
+    await runner.run(<String>['analyze']);
+
+    expect(
+        processRunner.recordedCalls,
+        orderedEquals(<ProcessCall>[
+          ProcessCall(
+              'flutter', const <String>['packages', 'get'], plugin1Dir.path),
+          ProcessCall(
+              'flutter', const <String>['packages', 'get'], plugin2Dir.path),
+          ProcessCall('dart', const <String>['analyze', '--fatal-infos'],
+              plugin1Dir.path),
+          ProcessCall('dart', const <String>['analyze', '--fatal-infos'],
+              plugin2Dir.path),
+        ]));
+  });
+
   test('uses a separate analysis sdk', () async {
     final Directory pluginDir = createFakePlugin('a');