Skip to content

Commit 3e6e1ac

Browse files
authored
Split out post process builder state. (#3959)
1 parent 2d21f21 commit 3e6e1ac

17 files changed

+740
-628
lines changed

build_runner/test/generate/watch_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ void main() {
426426
cachedGraph,
427427
equalsAssetGraph(expectedGraph, checkPreviousInputsDigest: false),
428428
);
429+
expect(
430+
cachedGraph.allPostProcessBuildStepOutputs,
431+
expectedGraph.allPostProcessBuildStepOutputs,
432+
);
429433
});
430434

431435
test('ignores events from nested packages', () async {

build_runner/test/server/asset_handler_test.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:build_runner/src/server/server.dart';
1010
import 'package:build_runner_core/build_runner_core.dart';
1111
import 'package:build_runner_core/src/asset_graph/graph.dart';
1212
import 'package:build_runner_core/src/asset_graph/node.dart';
13+
import 'package:build_runner_core/src/asset_graph/post_process_build_step_id.dart';
1314
import 'package:build_runner_core/src/generate/build_phases.dart';
1415
import 'package:build_runner_core/src/generate/options.dart';
1516
import 'package:build_runner_core/src/package_graph/target_graph.dart';
@@ -48,9 +49,11 @@ void main() {
4849
void addAsset(String id, String content, {bool deleted = false}) {
4950
var node = makeAssetNode(id, [], computeDigest(AssetId.parse(id), 'a'));
5051
if (deleted) {
51-
node = node.rebuild(
52-
(b) => b..deletedBy.add(node.id.addExtension('.post_anchor.1')),
53-
);
52+
node = node.rebuild((b) {
53+
b.deletedBy.add(
54+
PostProcessBuildStepId(input: node.id, actionNumber: 1),
55+
);
56+
});
5457
}
5558
graph.add(node);
5659
delegate.testing.writeString(node.id, content);

build_runner/test/server/serve_handler_test.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:build_runner/src/server/server.dart';
1515
import 'package:build_runner_core/build_runner_core.dart';
1616
import 'package:build_runner_core/src/asset_graph/graph.dart';
1717
import 'package:build_runner_core/src/asset_graph/node.dart';
18+
import 'package:build_runner_core/src/asset_graph/post_process_build_step_id.dart';
1819
import 'package:build_runner_core/src/generate/build_phases.dart';
1920
import 'package:build_runner_core/src/generate/options.dart';
2021
import 'package:build_runner_core/src/generate/performance_tracker.dart';
@@ -139,9 +140,11 @@ void main() {
139140
void addSource(String id, String content, {bool deleted = false}) {
140141
var node = makeAssetNode(id, [], computeDigest(AssetId.parse(id), content));
141142
if (deleted) {
142-
node = node.rebuild(
143-
(b) => b..deletedBy.add(node.id.addExtension('.post_anchor.1')),
144-
);
143+
node = node.rebuild((b) {
144+
b.deletedBy.add(
145+
PostProcessBuildStepId(input: node.id, actionNumber: 1),
146+
);
147+
});
145148
}
146149
assetGraph.add(node);
147150
readerWriter.testing.writeString(node.id, content);

build_runner_core/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
- Add `reportUnusedAssetsForInput` to `BuildOptions`, to listen for when
2828
a builder notifies that an asset is unused.
2929
- Use `LibraryCycleGraphLoader` to load transitive deps for analysis.
30+
- Track post process builder outputs separately from the main graph Instead of
31+
in `postProcessAnchor` nodes.
3032

3133
## 8.0.0
3234

build_runner_core/lib/src/asset_graph/graph.dart

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:build/src/internal.dart';
1414
import 'package:built_collection/built_collection.dart';
1515
import 'package:crypto/crypto.dart';
1616
import 'package:glob/glob.dart';
17+
import 'package:meta/meta.dart';
1718
import 'package:package_config/package_config.dart';
1819
import 'package:watcher/watcher.dart';
1920

@@ -23,6 +24,8 @@ import '../generate/phase.dart';
2324
import '../util/constants.dart';
2425
import 'exceptions.dart';
2526
import 'node.dart';
27+
import 'post_process_build_step_id.dart';
28+
import 'serializers.dart';
2629

2730
part 'serialization.dart';
2831

@@ -46,6 +49,14 @@ class AssetGraph implements GeneratedAssetHider {
4649

4750
final BuiltMap<String, LanguageVersion?> packageLanguageVersions;
4851

52+
/// All post process build steps outputs, indexed by package then
53+
/// [PostProcessBuildStepId].
54+
///
55+
/// Created with empty outputs at the start of the build if it's a new build
56+
/// step; or deserialized with previous build outputs if it has run before.
57+
final Map<String, Map<PostProcessBuildStepId, Set<AssetId>>>
58+
_postProcessBuildStepOutputs = {};
59+
4960
AssetGraph._(
5061
this.buildPhasesDigest,
5162
this.dartVersion,
@@ -93,6 +104,10 @@ class AssetGraph implements GeneratedAssetHider {
93104

94105
List<int> serialize() => _AssetGraphSerializer(this).serialize();
95106

107+
@visibleForTesting
108+
Map<String, Map<PostProcessBuildStepId, Set<AssetId>>>
109+
get allPostProcessBuildStepOutputs => _postProcessBuildStepOutputs;
110+
96111
/// Checks if [id] exists in the graph.
97112
bool contains(AssetId id) =>
98113
_nodesByPackage[id.package]?.containsKey(id.path) ?? false;
@@ -243,9 +258,6 @@ class AssetGraph implements GeneratedAssetHider {
243258
var node = get(id);
244259
if (node == null) return removedIds;
245260
removedIds.add(id);
246-
for (var anchor in node.anchorOutputs.toList()) {
247-
_removeRecursive(anchor, removedIds: removedIds);
248-
}
249261
for (var output in node.primaryOutputs.toList()) {
250262
_removeRecursive(output, removedIds: removedIds);
251263
}
@@ -290,6 +302,12 @@ class AssetGraph implements GeneratedAssetHider {
290302
if (node.type != NodeType.missingSource) {
291303
_nodesByPackage[id.package]!.remove(id.path);
292304
}
305+
306+
// Remove post build action applications with removed assets as inputs.
307+
for (final packageOutputs in _postProcessBuildStepOutputs.values) {
308+
packageOutputs.removeWhere((id, _) => removedIds!.contains(id.input));
309+
}
310+
293311
return removedIds;
294312
}
295313

@@ -301,6 +319,31 @@ class AssetGraph implements GeneratedAssetHider {
301319
Iterable<AssetNode> packageNodes(String package) =>
302320
_nodesByPackage[package]?.values ?? [];
303321

322+
/// All the post process build steps for `package`.
323+
Iterable<PostProcessBuildStepId> postProcessBuildStepIds({
324+
required String package,
325+
}) => _postProcessBuildStepOutputs[package]?.keys ?? const [];
326+
327+
/// Creates or updates state for a [PostProcessBuildStepId].
328+
void updatePostProcessBuildStep(
329+
PostProcessBuildStepId buildStepId, {
330+
required Set<AssetId> outputs,
331+
}) {
332+
_postProcessBuildStepOutputs.putIfAbsent(
333+
buildStepId.input.package,
334+
() => {},
335+
)[buildStepId] =
336+
outputs;
337+
}
338+
339+
/// Gets outputs of a [PostProcessBuildStepId].
340+
///
341+
/// These are set using [updatePostProcessBuildStep] during the build, then
342+
/// used to clean up prior outputs in the next build.
343+
Iterable<AssetId> postProcessBuildStepOutputs(PostProcessBuildStepId action) {
344+
return _postProcessBuildStepOutputs[action.input.package]![action]!;
345+
}
346+
304347
/// All the generated outputs in the graph.
305348
Iterable<AssetId> get outputs =>
306349
allNodes.where((n) => n.type == NodeType.generated).map((n) => n.id);
@@ -547,7 +590,7 @@ class AssetGraph implements GeneratedAssetHider {
547590
),
548591
);
549592
} else if (phase is PostBuildPhase) {
550-
_addPostBuildPhaseAnchors(phase, allInputs);
593+
_addPostBuildActionApplications(phase, allInputs);
551594
} else {
552595
throw StateError('Unrecognized phase type $phase');
553596
}
@@ -600,27 +643,21 @@ class AssetGraph implements GeneratedAssetHider {
600643
return phaseOutputs;
601644
}
602645

603-
/// Adds all [AssetNode.postProcessAnchor]s for [phase] given [allInputs];
604-
///
605-
/// Does not return anything because [AssetNode.postProcessAnchor]s are
606-
/// synthetic and should not be treated as inputs.
607-
void _addPostBuildPhaseAnchors(PostBuildPhase phase, Set<AssetId> allInputs) {
608-
var actionNum = 0;
646+
/// Adds all [PostProcessBuildStepId]s for [phase] given [allInputs];
647+
void _addPostBuildActionApplications(
648+
PostBuildPhase phase,
649+
Set<AssetId> allInputs,
650+
) {
651+
var actionNumber = 0;
609652
for (var action in phase.builderActions) {
610653
var inputs = allInputs.where((input) => _actionMatches(action, input));
611654
for (var input in inputs) {
612-
var buildOptionsNodeId = builderOptionsIdForAction(action, actionNum);
613-
var anchor = AssetNode.postProcessAnchorForInputAndAction(
614-
input,
615-
actionNum,
616-
buildOptionsNodeId,
655+
updatePostProcessBuildStep(
656+
PostProcessBuildStepId(input: input, actionNumber: actionNumber),
657+
outputs: {},
617658
);
618-
add(anchor);
619-
updateNode(input, (nodeBuilder) {
620-
nodeBuilder.anchorOutputs.add(anchor.id);
621-
});
622659
}
623-
actionNum++;
660+
actionNumber++;
624661
}
625662
}
626663

@@ -762,11 +799,14 @@ class AssetGraph implements GeneratedAssetHider {
762799
Digest computeBuilderOptionsDigest(BuilderOptions options) =>
763800
md5.convert(utf8.encode(json.encode(options.config)));
764801

765-
AssetId builderOptionsIdForAction(BuildAction action, int actionNum) {
802+
AssetId builderOptionsIdForAction(BuildAction action, int actionNumber) {
766803
if (action is InBuildPhase) {
767-
return AssetId(action.package, 'Phase$actionNum.builderOptions');
804+
return AssetId(action.package, 'Phase$actionNumber.builderOptions');
768805
} else if (action is PostBuildAction) {
769-
return AssetId(action.package, 'PostPhase$actionNum.builderOptions');
806+
return PostProcessBuildStepId.builderOptionsIdFor(
807+
package: action.package,
808+
actionNumber: actionNumber,
809+
);
770810
} else {
771811
throw StateError('Unsupported action type $action');
772812
}

0 commit comments

Comments
 (0)