Skip to content

Commit f08f498

Browse files
committed
Refactor file outputs to BuildOutputReader.
1 parent 310cd82 commit f08f498

22 files changed

+735
-814
lines changed

build_runner/lib/src/build/build.dart

Lines changed: 41 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import 'dart:convert';
88
import 'package:analyzer/dart/analysis/utilities.dart';
99
import 'package:analyzer/dart/ast/ast.dart';
1010
import 'package:build/build.dart';
11-
import 'package:built_collection/built_collection.dart';
1211
import 'package:crypto/crypto.dart';
1312
import 'package:glob/glob.dart';
1413
import 'package:path/path.dart' as p;
1514
import 'package:watcher/watcher.dart';
1615

1716
import '../bootstrap/build_process_state.dart';
18-
import '../build_plan/build_directory.dart';
1917
import '../build_plan/build_options.dart';
2018
import '../build_plan/build_phases.dart';
2119
import '../build_plan/build_plan.dart';
@@ -24,6 +22,7 @@ import '../build_plan/phase.dart';
2422
import '../build_plan/target_graph.dart';
2523
import '../build_plan/testing_overrides.dart';
2624
import '../constants.dart';
25+
import '../io/build_output_reader.dart';
2726
import '../io/create_merged_dir.dart';
2827
import '../io/reader_writer.dart';
2928
import '../logging/build_log.dart';
@@ -33,12 +32,10 @@ import 'asset_graph/node.dart';
3332
import 'asset_graph/post_process_build_step_id.dart';
3433
import 'build_dirs.dart';
3534
import 'build_result.dart';
36-
import 'finalized_assets_view.dart';
3735
import 'input_tracker.dart';
3836
import 'library_cycle_graph/asset_deps_loader.dart';
3937
import 'library_cycle_graph/library_cycle_graph.dart';
4038
import 'library_cycle_graph/library_cycle_graph_loader.dart';
41-
import 'optional_output_tracker.dart';
4239
import 'performance_tracker.dart';
4340
import 'performance_tracking_resolvers.dart';
4441
import 'resolver/analysis_driver_model.dart';
@@ -110,6 +107,9 @@ class Build {
110107
/// transitive source.
111108
final Map<LibraryCycleGraph, bool> changedGraphs = Map.identity();
112109

110+
/// The build output.
111+
final BuildOutputReader buildOutputReader;
112+
113113
Build({
114114
required this.buildPlan,
115115
required this.readerWriter,
@@ -122,7 +122,12 @@ class Build {
122122
previousDepsLoader =
123123
assetGraph.previousPhasedAssetDeps == null
124124
? null
125-
: AssetDepsLoader.fromDeps(assetGraph.previousPhasedAssetDeps!);
125+
: AssetDepsLoader.fromDeps(assetGraph.previousPhasedAssetDeps!),
126+
buildOutputReader = BuildOutputReader(
127+
buildPlan: buildPlan,
128+
readerWriter: readerWriter,
129+
assetGraph: assetGraph,
130+
);
126131

127132
BuildOptions get buildOptions => buildPlan.buildOptions;
128133
TestingOverrides get testingOverrides => buildPlan.testingOverrides;
@@ -138,13 +143,6 @@ class Build {
138143
(b) => b..rootPackageName = packageGraph.root.name,
139144
);
140145
var result = await _safeBuild(updates);
141-
final optionalOutputTracker = OptionalOutputTracker(
142-
assetGraph,
143-
targetGraph,
144-
BuildDirectory.buildPaths(buildPlan.buildOptions.buildDirs),
145-
buildPlan.buildOptions.buildFilters,
146-
buildPhases,
147-
);
148146
if (result.status == BuildStatus.success) {
149147
final failures = <AssetNode>[];
150148
for (final output in processedOutputs) {
@@ -169,21 +167,31 @@ class Build {
169167
logger.severe(error);
170168
}
171169
}
172-
result = BuildResult(
173-
BuildStatus.failure,
174-
result.outputs,
175-
performance: result.performance,
176-
);
170+
result = result.copyWith(buildStatus: BuildStatus.failure);
177171
}
178172
}
179173
readerWriter.cache.flush();
180174
await resourceManager.disposeAll();
181-
result = await _finalizeBuild(
182-
result,
183-
FinalizedAssetsView(assetGraph, packageGraph, optionalOutputTracker),
184-
readerWriter,
185-
buildPlan.buildOptions.buildDirs,
186-
);
175+
176+
// If requested, create output directories. If that fails, fail the build.
177+
if (buildPlan.buildOptions.buildDirs.any(
178+
(target) => target.outputLocation?.path.isNotEmpty ?? false,
179+
) &&
180+
result.status == BuildStatus.success) {
181+
if (!await createMergedOutputDirectories(
182+
packageGraph: packageGraph,
183+
outputSymlinksOnly: buildOptions.outputSymlinksOnly,
184+
buildDirs: buildOptions.buildDirs,
185+
buildOutputReader: buildOutputReader,
186+
readerWriter: readerWriter,
187+
)) {
188+
result = result.copyWith(
189+
buildStatus: BuildStatus.failure,
190+
failureType: FailureType.cantCreate,
191+
);
192+
}
193+
}
194+
187195
_resolvers.reset();
188196
buildLog.finishBuild(
189197
result: result.status == BuildStatus.success,
@@ -282,7 +290,13 @@ class Build {
282290
buildLog.error(
283291
buildLog.renderThrowable('Unhandled build failure!', e, st),
284292
);
285-
done.complete(BuildResult(BuildStatus.failure, []));
293+
done.complete(
294+
BuildResult(
295+
BuildStatus.failure,
296+
[],
297+
buildOutputReader: buildOutputReader,
298+
),
299+
);
286300
}
287301
},
288302
);
@@ -370,11 +384,13 @@ class Build {
370384
(Future<Iterable<AssetId>> lazyOuts) async =>
371385
outputs.addAll(await lazyOuts),
372386
);
387+
373388
// Assume success, `_assetGraph.failedOutputs` will be checked later.
374389
return BuildResult(
375390
BuildStatus.success,
376391
outputs,
377392
performance: performanceTracker,
393+
buildOutputReader: buildOutputReader,
378394
);
379395
});
380396
}
@@ -394,7 +410,7 @@ class Build {
394410
.toList(growable: false)) {
395411
if (!shouldBuildForDirs(
396412
node.id,
397-
buildDirs: BuildDirectory.buildPaths(buildPlan.buildOptions.buildDirs),
413+
buildDirs: buildPlan.buildOptions.buildDirs,
398414
buildFilters: buildPlan.buildOptions.buildFilters,
399415
phase: phase,
400416
targetGraph: targetGraph,
@@ -1211,60 +1227,6 @@ class Build {
12111227
}
12121228

12131229
Future _delete(AssetId id) => readerWriter.delete(id);
1214-
1215-
/// Invoked after each build, can modify the [BuildResult] in any way, even
1216-
/// converting it to a failure.
1217-
///
1218-
/// The [finalizedAssetsView] can only be used until the returned [Future]
1219-
/// completes, it will expire afterwords since it can no longer guarantee a
1220-
/// consistent state.
1221-
///
1222-
/// By default this returns the original result.
1223-
///
1224-
/// Any operation may be performed, as determined by environment.
1225-
Future<BuildResult> _finalizeBuild(
1226-
BuildResult buildResult,
1227-
FinalizedAssetsView finalizedAssetsView,
1228-
ReaderWriter readerWriter,
1229-
BuiltSet<BuildDirectory> buildDirs,
1230-
) async {
1231-
if (testingOverrides.finalizeBuild != null) {
1232-
return testingOverrides.finalizeBuild!(
1233-
buildResult,
1234-
finalizedAssetsView,
1235-
readerWriter,
1236-
buildDirs,
1237-
);
1238-
}
1239-
if (buildDirs.any(
1240-
(target) => target.outputLocation?.path.isNotEmpty ?? false,
1241-
) &&
1242-
buildResult.status == BuildStatus.success) {
1243-
if (!await createMergedOutputDirectories(
1244-
buildDirs,
1245-
packageGraph,
1246-
readerWriter,
1247-
finalizedAssetsView,
1248-
buildOptions.outputSymlinksOnly,
1249-
)) {
1250-
return _convertToFailure(
1251-
buildResult,
1252-
failureType: FailureType.cantCreate,
1253-
);
1254-
}
1255-
}
1256-
return buildResult;
1257-
}
12581230
}
12591231

12601232
String _twoDigits(int n) => '$n'.padLeft(2, '0');
1261-
1262-
BuildResult _convertToFailure(
1263-
BuildResult previous, {
1264-
FailureType? failureType,
1265-
}) => BuildResult(
1266-
BuildStatus.failure,
1267-
previous.outputs,
1268-
performance: previous.performance,
1269-
failureType: failureType,
1270-
);

build_runner/lib/src/build/build_dirs.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:build/build.dart';
66
import 'package:built_collection/built_collection.dart';
77

8+
import '../build_plan/build_directory.dart';
89
import '../build_plan/build_filter.dart';
910
import '../build_plan/phase.dart';
1011
import '../build_plan/target_graph.dart';
@@ -23,18 +24,19 @@ import '../build_plan/target_graph.dart';
2324
/// `id.path` must start with one of the specified directory names.
2425
bool shouldBuildForDirs(
2526
AssetId id, {
26-
required BuiltSet<String> buildDirs,
27+
required BuiltSet<BuildDirectory> buildDirs,
2728
required BuildPhase phase,
2829
required TargetGraph targetGraph,
2930
BuiltSet<BuildFilter>? buildFilters,
3031
}) {
32+
final paths = BuildDirectory.buildPaths(buildDirs);
3133
buildFilters ??= BuiltSet();
3234
if (buildFilters.isEmpty) {
3335
// Build asset if: It's built to source, it's public or if it's matched by
3436
// a build directory.
3537
return !phase.hideOutput ||
3638
buildDirs.isEmpty ||
37-
buildDirs.any(id.path.startsWith) ||
39+
paths.any(id.path.startsWith) ||
3840
targetGraph.isPublicAsset(id);
3941
} else {
4042
// Don't build assets not matched by build filters
@@ -45,7 +47,7 @@ bool shouldBuildForDirs(
4547
// In filtered assets, build the public ones or those inside a build
4648
// directory.
4749
return buildDirs.isEmpty ||
48-
buildDirs.any(id.path.startsWith) ||
50+
paths.any(id.path.startsWith) ||
4951
targetGraph.isPublicAsset(id);
5052
}
5153
}

build_runner/lib/src/build/build_result.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
4-
import 'dart:async';
54

65
import 'package:build/build.dart';
76
import 'package:meta/meta.dart';
87

8+
import '../io/build_output_reader.dart';
99
import 'performance_tracker.dart';
1010

1111
/// The result of an individual build, this may be an incremental build or
@@ -20,20 +20,34 @@ class BuildResult {
2020
/// All outputs created/updated during this build.
2121
final List<AssetId> outputs;
2222

23+
// The build output.
24+
final BuildOutputReader buildOutputReader;
25+
2326
/// The [BuildPerformance] broken out by build action, may be `null`.
2427
@experimental
2528
final BuildPerformance? performance;
2629

2730
BuildResult(
2831
this.status,
2932
List<AssetId> outputs, {
33+
required this.buildOutputReader,
3034
this.performance,
3135
FailureType? failureType,
3236
}) : outputs = List.unmodifiable(outputs),
3337
failureType =
3438
failureType == null && status == BuildStatus.failure
3539
? FailureType.general
3640
: failureType;
41+
42+
BuildResult copyWith({BuildStatus? buildStatus, FailureType? failureType}) =>
43+
BuildResult(
44+
buildStatus ?? status,
45+
outputs,
46+
buildOutputReader: buildOutputReader,
47+
performance: performance,
48+
failureType: failureType ?? this.failureType,
49+
);
50+
3751
@override
3852
String toString() {
3953
if (status == BuildStatus.success) {
@@ -53,6 +67,7 @@ Build Failed :(
5367
BuildStatus.failure,
5468
const [],
5569
failureType: FailureType.buildScriptChanged,
70+
buildOutputReader: BuildOutputReader.empty(),
5671
);
5772
}
5873

@@ -68,8 +83,3 @@ class FailureType {
6883
final int exitCode;
6984
FailureType._(this.exitCode);
7085
}
71-
72-
abstract class BuildState {
73-
Future<BuildResult>? get currentBuild;
74-
Stream<BuildResult> get buildResults;
75-
}

0 commit comments

Comments
 (0)