Skip to content

Commit 6f58924

Browse files
committed
Split out post process builder state.
1 parent 7bb331e commit 6f58924

17 files changed

+741
-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: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import 'package:build/experiments.dart' as experiments_zone;
1212
// ignore: implementation_imports
1313
import 'package:build/src/internal.dart';
1414
import 'package:built_collection/built_collection.dart';
15+
import 'package:built_value/serializer.dart';
1516
import 'package:crypto/crypto.dart';
1617
import 'package:glob/glob.dart';
18+
import 'package:meta/meta.dart';
1719
import 'package:package_config/package_config.dart';
1820
import 'package:watcher/watcher.dart';
1921

@@ -23,6 +25,8 @@ import '../generate/phase.dart';
2325
import '../util/constants.dart';
2426
import 'exceptions.dart';
2527
import 'node.dart';
28+
import 'post_process_build_step_id.dart';
29+
import 'serializers.dart';
2630

2731
part 'serialization.dart';
2832

@@ -46,6 +50,14 @@ class AssetGraph implements GeneratedAssetHider {
4650

4751
final BuiltMap<String, LanguageVersion?> packageLanguageVersions;
4852

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

94106
List<int> serialize() => _AssetGraphSerializer(this).serialize();
95107

108+
@visibleForTesting
109+
Map<String, Map<PostProcessBuildStepId, Set<AssetId>>>
110+
get allPostProcessBuildStepOutputs => _postProcessBuildStepOutputs;
111+
96112
/// Checks if [id] exists in the graph.
97113
bool contains(AssetId id) =>
98114
_nodesByPackage[id.package]?.containsKey(id.path) ?? false;
@@ -243,9 +259,6 @@ class AssetGraph implements GeneratedAssetHider {
243259
var node = get(id);
244260
if (node == null) return removedIds;
245261
removedIds.add(id);
246-
for (var anchor in node.anchorOutputs.toList()) {
247-
_removeRecursive(anchor, removedIds: removedIds);
248-
}
249262
for (var output in node.primaryOutputs.toList()) {
250263
_removeRecursive(output, removedIds: removedIds);
251264
}
@@ -290,6 +303,12 @@ class AssetGraph implements GeneratedAssetHider {
290303
if (node.type != NodeType.missingSource) {
291304
_nodesByPackage[id.package]!.remove(id.path);
292305
}
306+
307+
// Remove post build action applications with removed assets as inputs.
308+
for (final packageOutputs in _postProcessBuildStepOutputs.values) {
309+
packageOutputs.removeWhere((id, _) => removedIds!.contains(id.input));
310+
}
311+
293312
return removedIds;
294313
}
295314

@@ -301,6 +320,31 @@ class AssetGraph implements GeneratedAssetHider {
301320
Iterable<AssetNode> packageNodes(String package) =>
302321
_nodesByPackage[package]?.values ?? [];
303322

323+
/// All the post process build steps for `package`.
324+
Iterable<PostProcessBuildStepId> postProcessBuildStepIds({
325+
required String package,
326+
}) => _postProcessBuildStepOutputs[package]?.keys ?? const [];
327+
328+
/// Creates or updates state for a [PostProcessBuildStepId].
329+
void updatePostProcessBuildStep(
330+
PostProcessBuildStepId buildStepId, {
331+
required Set<AssetId> outputs,
332+
}) {
333+
_postProcessBuildStepOutputs.putIfAbsent(
334+
buildStepId.input.package,
335+
() => {},
336+
)[buildStepId] =
337+
outputs;
338+
}
339+
340+
/// Gets outputs of a [PostProcessBuildStepId].
341+
///
342+
/// These are set using [updatePostProcessBuildStep] during the build, then
343+
/// used to clean up prior outputs in the next build.
344+
Iterable<AssetId> postProcessBuildStepOutputs(PostProcessBuildStepId action) {
345+
return _postProcessBuildStepOutputs[action.input.package]![action]!;
346+
}
347+
304348
/// All the generated outputs in the graph.
305349
Iterable<AssetId> get outputs =>
306350
allNodes.where((n) => n.type == NodeType.generated).map((n) => n.id);
@@ -547,7 +591,7 @@ class AssetGraph implements GeneratedAssetHider {
547591
),
548592
);
549593
} else if (phase is PostBuildPhase) {
550-
_addPostBuildPhaseAnchors(phase, allInputs);
594+
_addPostBuildActionApplications(phase, allInputs);
551595
} else {
552596
throw StateError('Unrecognized phase type $phase');
553597
}
@@ -600,27 +644,21 @@ class AssetGraph implements GeneratedAssetHider {
600644
return phaseOutputs;
601645
}
602646

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;
647+
/// Adds all [PostProcessBuildStepId]s for [phase] given [allInputs];
648+
void _addPostBuildActionApplications(
649+
PostBuildPhase phase,
650+
Set<AssetId> allInputs,
651+
) {
652+
var actionNumber = 0;
609653
for (var action in phase.builderActions) {
610654
var inputs = allInputs.where((input) => _actionMatches(action, input));
611655
for (var input in inputs) {
612-
var buildOptionsNodeId = builderOptionsIdForAction(action, actionNum);
613-
var anchor = AssetNode.postProcessAnchorForInputAndAction(
614-
input,
615-
actionNum,
616-
buildOptionsNodeId,
656+
updatePostProcessBuildStep(
657+
PostProcessBuildStepId(input: input, actionNumber: actionNumber),
658+
outputs: {},
617659
);
618-
add(anchor);
619-
updateNode(input, (nodeBuilder) {
620-
nodeBuilder.anchorOutputs.add(anchor.id);
621-
});
622660
}
623-
actionNum++;
661+
actionNumber++;
624662
}
625663
}
626664

@@ -762,11 +800,14 @@ class AssetGraph implements GeneratedAssetHider {
762800
Digest computeBuilderOptionsDigest(BuilderOptions options) =>
763801
md5.convert(utf8.encode(json.encode(options.config)));
764802

765-
AssetId builderOptionsIdForAction(BuildAction action, int actionNum) {
803+
AssetId builderOptionsIdForAction(BuildAction action, int actionNumber) {
766804
if (action is InBuildPhase) {
767-
return AssetId(action.package, 'Phase$actionNum.builderOptions');
805+
return AssetId(action.package, 'Phase$actionNumber.builderOptions');
768806
} else if (action is PostBuildAction) {
769-
return AssetId(action.package, 'PostPhase$actionNum.builderOptions');
807+
return PostProcessBuildStepId.builderOptionsIdFor(
808+
package: action.package,
809+
actionNumber: actionNumber,
810+
);
770811
} else {
771812
throw StateError('Unsupported action type $action');
772813
}

0 commit comments

Comments
 (0)