[flutter_tools] use package:test for coverage and remove build_runner test precompilation (#51966)

diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index b1b389b..59b4029 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -39,8 +39,6 @@
 
 final bool useFlutterTestFormatter = Platform.environment['FLUTTER_TEST_FORMATTER'] == 'true';
 
-final bool canUseBuildRunner = Platform.environment['FLUTTER_TEST_NO_BUILD_RUNNER'] != 'true';
-
 /// The number of Cirrus jobs that run host-only devicelab tests in parallel.
 ///
 /// WARNING: if you change this number, also change .cirrus.yml
@@ -236,18 +234,18 @@
 }
 
 Future<void> _runToolCoverage() async {
-  await runCommand( // Precompile tests to speed up subsequent runs.
-    pub,
-    <String>['run', 'build_runner', 'build'],
-    workingDirectory: toolRoot,
+  await _pubRunTest(
+    toolRoot,
+    testPaths: <String>[
+      path.join('test', 'general.shard'),
+      path.join('test', 'commands.shard', 'hermetic'),
+    ],
+    coverage: 'coverage',
   );
-  await runCommand(
-    dart,
-    <String>[path.join('tool', 'tool_coverage.dart')],
+  await runCommand(pub,
+    <String>['run', 'coverage:format_coverage', '--lcov', '--in=coverage', '--out=coverage/lcov.info'],
     workingDirectory: toolRoot,
-    environment: <String, String>{
-      'FLUTTER_ROOT': flutterRoot,
-    }
+    outputMode: OutputMode.discard,
   );
 }
 
@@ -273,8 +271,7 @@
         : '';
       await _pubRunTest(
         toolsPath,
-        testPath: path.join(kTest, '$subshard$kDotShard', suffix),
-        useBuildRunner: canUseBuildRunner,
+        testPaths: <String>[path.join(kTest, '$subshard$kDotShard', suffix)],
         tableData: bigqueryApi?.tabledata,
         enableFlutterToolAsserts: true,
       );
@@ -706,25 +703,12 @@
 }
 
 Future<void> _pubRunTest(String workingDirectory, {
-  String testPath,
+  List<String> testPaths,
   bool enableFlutterToolAsserts = true,
   bool useBuildRunner = false,
+  String coverage,
   bq.TabledataResourceApi tableData,
 }) async {
-  final List<String> args = <String>['run'];
-  if (useBuildRunner) {
-    final String posixTestPath = path.posix.joinAll(path.split(testPath));
-    args.addAll(<String>[
-      'build_runner',
-      'test',
-      '--build-filter=$posixTestPath/*.dill',
-      '--build-filter=$posixTestPath/**/*.dill',
-      '--',
-    ]);
-  } else {
-    args.add('test');
-  }
-  args.add(useFlutterTestFormatter ? '-rjson' : '-rcompact');
   int cpus;
   final String cpuVariable = Platform.environment['CPU']; // CPU is set in cirrus.yml
   if (cpuVariable != null) {
@@ -737,11 +721,23 @@
   } else {
     cpus = 2; // Don't default to 1, otherwise we won't catch race conditions.
   }
-  args.add('-j$cpus');
-  if (!hasColor)
-    args.add('--no-color');
-  if (testPath != null)
-    args.add(testPath);
+
+  final List<String> args = <String>[
+    'run',
+    'test',
+    if (useFlutterTestFormatter)
+      '-rjson'
+    else
+      '-rcompact',
+    '-j$cpus',
+    if (!hasColor)
+      '--no-color',
+    if (coverage != null)
+      '--coverage=$coverage',
+    if (testPaths != null)
+      for (final String testPath in testPaths)
+        testPath,
+  ];
   final Map<String, String> pubEnvironment = <String, String>{
     'FLUTTER_ROOT': flutterRoot,
   };
diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml
index eb52f3a..9610279 100644
--- a/packages/flutter_tools/pubspec.yaml
+++ b/packages/flutter_tools/pubspec.yaml
@@ -98,30 +98,15 @@
   mockito: 4.1.1
   file_testing: 2.1.0
   test: 1.14.1
-  build_runner: 1.7.4
-  build_vm_compilers: 1.0.4
-  build_test: 0.10.12+1
+  pubspec_parse: 0.1.5
 
-  bazel_worker: 0.1.23+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  build: 1.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  build_config: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  build_modules: 2.8.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  build_resolvers: 1.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  build_runner_core: 4.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
   checked_yaml: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  code_builder: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  dart_style: 1.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  graphs: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
   json_annotation: 3.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
   multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
   node_preamble: 1.4.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  protobuf: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  pubspec_parse: 0.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  scratch_space: 0.0.4+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-  timing: 0.1.1+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
 
 dartdoc:
   # Exclude this package from the hosted API docs.
   nodoc: true
 
-# PUBSPEC CHECKSUM: 193b
+# PUBSPEC CHECKSUM: 86fe
diff --git a/packages/flutter_tools/tool/tool_coverage.dart b/packages/flutter_tools/tool/tool_coverage.dart
deleted file mode 100644
index 9f1816d..0000000
--- a/packages/flutter_tools/tool/tool_coverage.dart
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:developer';
-import 'dart:io';
-import 'dart:isolate';
-
-import 'package:coverage/coverage.dart';
-import 'package:flutter_tools/src/base/common.dart';
-import 'package:flutter_tools/src/context_runner.dart';
-import 'package:flutter_tools/src/test/test_wrapper.dart';
-import 'package:path/path.dart' as path;
-import 'package:stream_channel/isolate_channel.dart';
-import 'package:stream_channel/stream_channel.dart';
-import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
-import 'package:flutter_tools/src/project.dart';
-import 'package:flutter_tools/src/test/coverage_collector.dart';
-
-/// Generates an lcov report for the flutter tool unit tests.
-///
-/// Example invocation:
-///
-///     dart tool/tool_coverage.dart
-Future<void> main(List<String> arguments) async {
-  return runInContext(() async {
-    final VMPlatform vmPlatform = VMPlatform();
-    const TestWrapper test = TestWrapper();
-    test.registerPlatformPlugin(
-      <Runtime>[Runtime.vm],
-      () => vmPlatform,
-    );
-    if (arguments.isEmpty) {
-      arguments = <String>[
-        path.join('test', 'general.shard'),
-        path.join('test', 'commands.shard', 'hermetic'),
-      ];
-    }
-    await test.main(<String>[
-      '--no-color',
-      '-r', 'compact',
-      '-j', '1',
-      ...arguments
-    ]);
-    exit(exitCode);
-  });
-}
-
-/// A platform that loads tests in isolates spawned within this Dart process.
-class VMPlatform extends PlatformPlugin {
-  final CoverageCollector coverageCollector = CoverageCollector(
-    libraryPredicate: (String libraryName) => libraryName.contains(FlutterProject.current().manifest.appName),
-  );
-  final Map<String, Future<void>> _pending = <String, Future<void>>{};
-  final String precompiledPath = path.join('.dart_tool', 'build', 'generated', 'flutter_tools');
-
-  @override
-  StreamChannel<void> loadChannel(String codePath, SuitePlatform platform) =>
-      throw UnimplementedError();
-
-  @override
-  Future<RunnerSuite> load(
-    String codePath,
-    SuitePlatform platform,
-    SuiteConfiguration suiteConfig,
-    Object message,
-  ) async {
-    final ReceivePort receivePort = ReceivePort();
-    Isolate isolate;
-    try {
-      isolate = await _spawnIsolate(codePath, receivePort.sendPort);
-    } catch (error) {
-      receivePort.close();
-      rethrow;
-    }
-    final Completer<void> completer = Completer<void>();
-    // When this is completed we remove it from the map of pending so we can
-    // log the futures that get "stuck".
-    unawaited(completer.future.whenComplete(() {
-      _pending.remove(codePath);
-    }));
-    final ServiceProtocolInfo info = await Service.controlWebServer(enable: true);
-    final StreamChannel<Object> channel = IsolateChannel<Object>.connectReceive(receivePort)
-      .transformStream(StreamTransformer<Object, Object>.fromHandlers(
-        handleDone: (EventSink<Object> sink) async {
-          try {
-            // this will throw if collection fails.
-            await coverageCollector.collectCoverageIsolate(info.serverUri);
-          } finally {
-            isolate.kill(priority: Isolate.immediate);
-            isolate = null;
-            sink.close();
-            completer.complete();
-          }
-        },
-        handleError: (dynamic error, StackTrace stackTrace, EventSink<Object> sink) {
-          isolate.kill(priority: Isolate.immediate);
-          isolate = null;
-          sink.close();
-          completer.complete();
-        },
-      ));
-
-    final RunnerSuiteController controller = deserializeSuite(
-      codePath,
-      platform,
-      suiteConfig,
-      null,
-      channel,
-      message,
-    );
-    _pending[codePath] = completer.future;
-    return await controller.suite;
-  }
-
-  /// Spawns an isolate and passes it [message].
-  ///
-  /// This isolate connects an [IsolateChannel] to [message] and sends the
-  /// serialized tests over that channel.
-  Future<Isolate> _spawnIsolate(String codePath, SendPort message) async {
-    String testPath = path.absolute(path.join(precompiledPath, codePath) + '.vm_test.dart');
-    testPath = testPath.substring(0, testPath.length - '.dart'.length) + '.vm.app.dill';
-    return await Isolate.spawnUri(path.toUri(testPath), <String>[], message,
-      packageConfig: path.toUri('.packages'),
-      checked: true,
-    );
-  }
-
-  @override
-  Future<void> close() async {
-    try {
-      await Future.wait(_pending.values).timeout(const Duration(minutes: 1));
-    } on TimeoutException {
-      // TODO(jonahwilliams): resolve whether there are any specific tests that
-      // get stuck or if it is a general infra issue with how we are collecting
-      // coverage.
-      // Log tests that are "Stuck" waiting for coverage.
-      print('The following tests timed out waiting for coverage:');
-      print(_pending.keys.join(', '));
-    }
-    final String packagePath = Directory.current.path;
-    final Resolver resolver = Resolver(packagesPath: '.packages');
-    final Formatter formatter = LcovFormatter(resolver, reportOn: <String>[
-      'lib',
-    ], basePath: packagePath);
-    final String result = await coverageCollector.finalizeCoverage(
-      formatter: formatter,
-    );
-    final String outputLcovPath = path.join('coverage', 'lcov.info');
-    File(outputLcovPath)
-      ..createSync(recursive: true)
-      ..writeAsStringSync(result);
-  }
-}