cleanup use of build runner internals (#40045)
diff --git a/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart b/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart
index 60d8be3..4425a72 100644
--- a/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart
+++ b/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart
@@ -7,205 +7,74 @@
import 'dart:io' as io; // ignore: dart_io_import
import 'package:build/build.dart';
+import 'package:build_daemon/client.dart';
+import 'package:build_daemon/data/build_status.dart';
import 'package:build_runner_core/build_runner_core.dart' as core;
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'package:build_runner_core/src/generate/build_impl.dart';
-import 'package:build_runner_core/src/generate/options.dart';
import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
-import 'package:watcher/watcher.dart';
-import '../artifacts.dart';
import '../base/file_system.dart';
-import '../base/logger.dart';
-import '../base/platform.dart';
import '../build_info.dart';
-import '../compile.dart';
import '../convert.dart';
-import '../dart/package_map.dart';
-import '../globals.dart';
import '../web/compile.dart';
-import 'build_script.dart';
+import 'web_fs.dart';
/// A build_runner specific implementation of the [WebCompilationProxy].
class BuildRunnerWebCompilationProxy extends WebCompilationProxy {
BuildRunnerWebCompilationProxy();
- core.PackageGraph _packageGraph;
- BuildImpl _builder;
- PackageUriMapper _packageUriMapper;
-
@override
Future<bool> initialize({
Directory projectDirectory,
String testOutputDir,
BuildMode mode,
+ String projectName
}) async {
// Create the .dart_tool directory if it doesn't exist.
- projectDirectory.childDirectory('.dart_tool').createSync();
- final Directory generatedDirectory = projectDirectory
+ projectDirectory
.childDirectory('.dart_tool')
- .childDirectory('build')
- .childDirectory('generated');
-
- // Override the generated output directory so this does not conflict with
- // other build_runner output.
- core.overrideGeneratedOutputDirectory('flutter_web');
- _packageUriMapper = PackageUriMapper(
- path.absolute('lib/main.dart'), PackageMap.globalPackagesPath, null, null);
- _packageGraph = core.PackageGraph.forPath(projectDirectory.path);
-
- final core.BuildEnvironment buildEnvironment = core.OverrideableEnvironment(
- core.IOEnvironment(_packageGraph), onLog: (LogRecord record) {
- if (record.level == Level.SEVERE || record.level == Level.SHOUT) {
- printError(record.message);
- } else {
- printTrace(record.message);
- }
- }, reader: MultirootFileBasedAssetReader(_packageGraph, generatedDirectory));
- final LogSubscription logSubscription = LogSubscription(
- buildEnvironment,
- verbose: false,
- logLevel: Level.FINE,
- );
- final BuildOptions buildOptions = await BuildOptions.create(
- logSubscription,
- packageGraph: _packageGraph,
- skipBuildScriptCheck: true,
- trackPerformance: false,
- deleteFilesByDefault: true,
- enableLowResourcesMode: platform.environment['FLUTTER_LOW_RESOURCE_MODE']?.toLowerCase() == 'true',
- );
- final Set<core.BuildDirectory> buildDirs = <core.BuildDirectory>{
- if (testOutputDir != null)
- core.BuildDirectory(
- 'test',
- outputLocation: core.OutputLocation(
- testOutputDir,
- useSymlinks: !platform.isWindows,
- ),
- ),
- };
- core.BuildResult result;
- try {
- result = await _runBuilder(
- buildEnvironment,
- buildOptions,
- mode,
- buildDirs,
- );
- return result.status == core.BuildStatus.success;
- } on core.BuildConfigChangedException {
- await _cleanAssets(projectDirectory);
- result = await _runBuilder(
- buildEnvironment,
- buildOptions,
- mode,
- buildDirs,
- );
- return result.status == core.BuildStatus.success;
- } on core.BuildScriptChangedException {
- await _cleanAssets(projectDirectory);
- result = await _runBuilder(
- buildEnvironment,
- buildOptions,
- mode,
- buildDirs,
- );
- return result.status == core.BuildStatus.success;
- }
- }
-
- @override
- Future<bool> invalidate({@required List<Uri> inputs}) async {
- final Status status =
- logger.startProgress('Recompiling sources...', timeout: null);
- final Map<AssetId, ChangeType> updates = <AssetId, ChangeType>{};
- for (Uri input in inputs) {
- final AssetId assetId = AssetId.resolve(_packageUriMapper.map(input.toFilePath()).toString());
- updates[assetId] = ChangeType.MODIFY;
- }
- core.BuildResult result;
- try {
- result = await _builder.run(updates);
- } finally {
- status.cancel();
- }
- return result.status == core.BuildStatus.success;
- }
-
- Future<core.BuildResult> _runBuilder(core.BuildEnvironment buildEnvironment, BuildOptions buildOptions, BuildMode buildMode, Set<core.BuildDirectory> buildDirs) async {
- _builder = await BuildImpl.create(
- buildOptions,
- buildEnvironment,
- builders,
- <String, Map<String, dynamic>>{
- 'flutter_tools:ddc': <String, dynamic>{
- 'flutterWebSdk': artifacts.getArtifactPath(Artifact.flutterWebSdk),
- },
- 'flutter_tools:entrypoint': <String, dynamic>{
- 'release': buildMode == BuildMode.release,
- 'flutterWebSdk': artifacts.getArtifactPath(Artifact.flutterWebSdk),
- 'profile': buildMode == BuildMode.profile,
- },
- 'flutter_tools:test_entrypoint': <String, dynamic>{
- 'release': buildMode == BuildMode.release,
- 'profile': buildMode == BuildMode.profile,
- },
- },
- isReleaseBuild: false,
- );
- return _builder.run(
- const <AssetId, ChangeType>{},
- buildDirs: buildDirs,
- );
- }
-
- Future<void> _cleanAssets(Directory projectDirectory) async {
- final File assetGraphFile = fs.file(core.assetGraphPath);
- AssetGraph assetGraph;
- try {
- assetGraph = AssetGraph.deserialize(await assetGraphFile.readAsBytes());
- } catch (_) {
- printTrace('Failed to clean up asset graph.');
- }
- final core.PackageGraph packageGraph = core.PackageGraph.forThisPackage();
- await _cleanUpSourceOutputs(assetGraph, packageGraph);
- final Directory cacheDirectory = fs.directory(fs.path.join(
+ .createSync();
+ final BuildDaemonClient client = await buildDaemonCreator.startBuildDaemon(
projectDirectory.path,
- '.dart_tool',
- 'build',
- 'flutter_web',
- ));
- if (assetGraphFile.existsSync()) {
- assetGraphFile.deleteSync();
+ release: mode == BuildMode.release,
+ profile: mode == BuildMode.profile,
+ hasPlugins: false,
+ includeTests: true,
+ );
+ client.startBuild();
+ bool success = true;
+ await for (BuildResults results in client.buildResults) {
+ final BuildResult result = results.results.firstWhere((BuildResult result) {
+ return result.target == 'web';
+ });
+ if (result.status == BuildStatus.failed) {
+ success = false;
+ break;
+ }
+ if (result.status == BuildStatus.succeeded) {
+ break;
+ }
}
- if (cacheDirectory.existsSync()) {
- cacheDirectory.deleteSync(recursive: true);
- }
- }
+ if (success && testOutputDir != null) {
+ final Directory rootDirectory = projectDirectory
+ .childDirectory('.dart_tool')
+ .childDirectory('build')
+ .childDirectory('flutter_web');
- Future<void> _cleanUpSourceOutputs(AssetGraph assetGraph, core.PackageGraph packageGraph) async {
- final core.FileBasedAssetWriter writer = core.FileBasedAssetWriter(packageGraph);
- if (assetGraph?.outputs == null) {
- return;
- }
- for (AssetId id in assetGraph.outputs) {
- if (id.package != packageGraph.root.name) {
- continue;
+ final Iterable<Directory> childDirectories = rootDirectory
+ .listSync()
+ .whereType<Directory>();
+ for (Directory childDirectory in childDirectories) {
+ final String path = fs.path.join(testOutputDir, 'packages',
+ fs.path.basename(childDirectory.path));
+ copyDirectorySync(childDirectory.childDirectory('lib'), fs.directory(path));
}
- final GeneratedAssetNode node = assetGraph.get(id);
- if (node.wasOutput) {
- // Note that this does a file.exists check in the root package and
- // only tries to delete the file if it exists. This way we only
- // actually delete to_source outputs, without reading in the build
- // actions.
- await writer.delete(id);
- }
+ final Directory outputDirectory = rootDirectory
+ .childDirectory(projectName)
+ .childDirectory('test');
+ copyDirectorySync(outputDirectory, fs.directory(fs.path.join(testOutputDir)));
}
+ return success;
}
}
diff --git a/packages/flutter_tools/lib/src/build_runner/web_fs.dart b/packages/flutter_tools/lib/src/build_runner/web_fs.dart
index fa7aa71..36c3611 100644
--- a/packages/flutter_tools/lib/src/build_runner/web_fs.dart
+++ b/packages/flutter_tools/lib/src/build_runner/web_fs.dart
@@ -336,7 +336,12 @@
static const String _ignoredLine3 = 'have your dependencies specified fully in your pubspec.yaml';
/// Start a build daemon and register the web targets.
- Future<BuildDaemonClient> startBuildDaemon(String workingDirectory, {bool release = false, bool profile = false, bool hasPlugins = false}) async {
+ Future<BuildDaemonClient> startBuildDaemon(String workingDirectory, {
+ bool release = false,
+ bool profile = false,
+ bool hasPlugins = false,
+ bool includeTests = false,
+ }) async {
try {
final BuildDaemonClient client = await _connectClient(
workingDirectory,
@@ -344,7 +349,7 @@
profile: profile,
hasPlugins: hasPlugins,
);
- _registerBuildTargets(client);
+ _registerBuildTargets(client, includeTests);
return client;
} on OptionsSkew {
throwToolExit(
@@ -357,6 +362,7 @@
void _registerBuildTargets(
BuildDaemonClient client,
+ bool includeTests,
) {
final OutputLocation outputLocation = OutputLocation((OutputLocationBuilder b) => b
..output = ''
@@ -365,6 +371,11 @@
client.registerBuildTarget(DefaultBuildTarget((DefaultBuildTargetBuilder b) => b
..target = 'web'
..outputLocation = outputLocation?.toBuilder()));
+ if (includeTests) {
+ client.registerBuildTarget(DefaultBuildTarget((DefaultBuildTargetBuilder b) => b
+ ..target = 'test'
+ ..outputLocation = outputLocation?.toBuilder()));
+ }
}
Future<BuildDaemonClient> _connectClient(
diff --git a/packages/flutter_tools/lib/src/test/runner.dart b/packages/flutter_tools/lib/src/test/runner.dart
index a230b21..dc83d9b 100644
--- a/packages/flutter_tools/lib/src/test/runner.dart
+++ b/packages/flutter_tools/lib/src/test/runner.dart
@@ -69,6 +69,7 @@
final bool result = await webCompilationProxy.initialize(
projectDirectory: flutterProject.directory,
testOutputDir: tempBuildDir,
+ projectName: flutterProject.manifest.appName,
);
if (!result) {
throwToolExit('Failed to compile tests');
diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart
index 94bd2ac..f749851 100644
--- a/packages/flutter_tools/lib/src/web/compile.dart
+++ b/packages/flutter_tools/lib/src/web/compile.dart
@@ -31,6 +31,7 @@
result = await webCompilationProxy.initialize(
projectDirectory: FlutterProject.current().directory,
mode: buildInfo.mode,
+ projectName: flutterProject.manifest.appName,
);
if (result) {
// Places assets adjacent to the web stuff.
@@ -80,14 +81,10 @@
/// the entrypoints for dart2js to later take over.
Future<bool> initialize({
@required Directory projectDirectory,
+ @required String projectName,
String testOutputDir,
BuildMode mode,
}) async {
throw UnimplementedError();
}
-
- /// Invalidate the source files in `inputs` and recompile them to JavaScript.
- Future<void> invalidate({@required List<Uri> inputs}) async {
- throw UnimplementedError();
- }
}
diff --git a/packages/flutter_tools/test/general.shard/commands/build_web_test.dart b/packages/flutter_tools/test/general.shard/commands/build_web_test.dart
index 6f2341a..dab520e 100644
--- a/packages/flutter_tools/test/general.shard/commands/build_web_test.dart
+++ b/packages/flutter_tools/test/general.shard/commands/build_web_test.dart
@@ -41,6 +41,7 @@
fs.file(fs.path.join('web', 'index.html')).createSync(recursive: true);
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
when(mockWebCompilationProxy.initialize(
+ projectName: anyNamed('projectName'),
projectDirectory: anyNamed('projectDirectory'),
mode: anyNamed('mode')
)).thenAnswer((Invocation invocation) {