Skip to content

Use built_value for serialization. #3915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions _test_common/lib/matchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,10 @@ class _AssetGraphMatcher extends Matcher {

final configuration = node.globNodeConfiguration!;
final expectedConfiguration = expectedNode.globNodeConfiguration!;
if (configuration.glob.pattern !=
expectedConfiguration.glob.pattern) {
if (configuration.glob != expectedConfiguration.glob) {
matchState['glob of ${node.id}'] = [
configuration.glob.pattern,
expectedConfiguration.glob.pattern,
configuration.glob,
expectedConfiguration.glob,
];
matches = false;
}
Expand Down
2 changes: 1 addition & 1 deletion build_runner/lib/src/server/asset_graph_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class AssetGraphHandler {
'type': node.runtimeType.toString(),
'glob':
node.type == NodeType.glob
? node.globNodeConfiguration!.glob.pattern
? node.globNodeConfiguration!.glob
: null,
'lastKnownDigest': node.lastKnownDigest.toString(),
},
Expand Down
2 changes: 1 addition & 1 deletion build_runner_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
- Refactor `SingleStepReader` to `SingleStepReaderWriter`, incorporating
`AssetWriterSpy` functionality.
- Add `NodeType` to `AssetNode`, remove subtypes. Make mutations explicit.
- Use `built_value` for `AssetNode` and related types.
- Use `built_value` for `AssetNode` and related types, and for serialization.

## 8.0.0

Expand Down
3 changes: 2 additions & 1 deletion build_runner_core/lib/src/asset_graph/graph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ class AssetGraph {
);
for (final node in samePackageGlobNodes) {
final nodeConfiguration = node.globNodeConfiguration!;
if (nodeConfiguration.glob.matches(id.path)) {
final glob = Glob(nodeConfiguration.glob);
if (glob.matches(id.path)) {
invalidateNodeAndDeps(node.id);
updateNode(node.id, (nodeBuilder) {
nodeBuilder.globNodeState.pendingBuildAction =
Expand Down
95 changes: 87 additions & 8 deletions build_runner_core/lib/src/asset_graph/node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import 'dart:convert';
import 'package:build/build.dart' hide Builder;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:crypto/crypto.dart';
import 'package:glob/glob.dart';

import '../generate/phase.dart';

part 'node.g.dart';

/// Types of [AssetNode].
class NodeType extends EnumClass {
static Serializer<NodeType> get serializer => _$nodeTypeSerializer;

static const NodeType builderOptions = _$builderOptions;
static const NodeType generated = _$generated;
static const NodeType glob = _$glob;
Expand All @@ -33,6 +35,8 @@ class NodeType extends EnumClass {

/// A node in the asset graph which may be an input to other assets.
abstract class AssetNode implements Built<AssetNode, AssetNodeBuilder> {
static Serializer<AssetNode> get serializer => _$assetNodeSerializer;

AssetId get id;
NodeType get type;

Expand Down Expand Up @@ -219,7 +223,7 @@ abstract class AssetNode implements Built<AssetNode, AssetNodeBuilder> {
factory AssetNode.glob(
AssetId id, {
Digest? lastKnownDigest,
required Glob glob,
required String glob,
required int phaseNumber,
Iterable<AssetId>? inputs,
required PendingBuildAction pendingBuildAction,
Expand All @@ -236,11 +240,8 @@ abstract class AssetNode implements Built<AssetNode, AssetNodeBuilder> {
..lastKnownDigest = lastKnownDigest,
);

static AssetId createGlobNodeId(String package, Glob glob, int phaseNum) =>
AssetId(
package,
'glob.$phaseNum.${base64.encode(utf8.encode(glob.pattern))}',
);
static AssetId createGlobNodeId(String package, String glob, int phaseNum) =>
AssetId(package, 'glob.$phaseNum.${base64.encode(utf8.encode(glob))}');

/// A [primaryInput] to a [PostBuildAction].
///
Expand Down Expand Up @@ -313,6 +314,9 @@ abstract class AssetNode implements Built<AssetNode, AssetNodeBuilder> {
abstract class GeneratedNodeConfiguration
implements
Built<GeneratedNodeConfiguration, GeneratedNodeConfigurationBuilder> {
static Serializer<GeneratedNodeConfiguration> get serializer =>
_$generatedNodeConfigurationSerializer;

/// The primary input which generated this node.
AssetId get primaryInput;

Expand Down Expand Up @@ -342,6 +346,9 @@ abstract class GeneratedNodeConfiguration
/// State for an [AssetNode.generated] that changes during the build.
abstract class GeneratedNodeState
implements Built<GeneratedNodeState, GeneratedNodeStateBuilder> {
static Serializer<GeneratedNodeState> get serializer =>
_$generatedNodeStateSerializer;

/// All the inputs that were read when generating this asset, or deciding not
/// to generate it.
BuiltSet<AssetId> get inputs;
Expand Down Expand Up @@ -373,7 +380,10 @@ abstract class GeneratedNodeState
/// Additional configuration for an [AssetNode.glob].
abstract class GlobNodeConfiguration
implements Built<GlobNodeConfiguration, GlobNodeConfigurationBuilder> {
Glob get glob;
static Serializer<GlobNodeConfiguration> get serializer =>
_$globNodeConfigurationSerializer;

String get glob;
int get phaseNumber;

factory GlobNodeConfiguration(
Expand All @@ -386,6 +396,10 @@ abstract class GlobNodeConfiguration
/// State for an [AssetNode.glob] that changes during the build.
abstract class GlobNodeState
implements Built<GlobNodeState, GlobNodeStateBuilder> {
static Serializer<GlobNodeState> get serializer => _$globNodeStateSerializer;

/// The next work that needs doing on this node.

/// All the potential inputs matching this glob.
///
/// This field differs from [results] in that [AssetNode.generated] which may
Expand All @@ -412,6 +426,9 @@ abstract class PostProcessAnchorNodeConfiguration
PostProcessAnchorNodeConfiguration,
PostProcessAnchorNodeConfigurationBuilder
> {
static Serializer<PostProcessAnchorNodeConfiguration> get serializer =>
_$postProcessAnchorNodeConfigurationSerializer;

int get actionNumber;
AssetId get builderOptionsId;
AssetId get primaryInput;
Expand All @@ -427,6 +444,9 @@ abstract class PostProcessAnchorNodeConfiguration
abstract class PostProcessAnchorNodeState
implements
Built<PostProcessAnchorNodeState, PostProcessAnchorNodeStateBuilder> {
static Serializer<PostProcessAnchorNodeState> get serializer =>
_$postProcessAnchorNodeStateSerializer;

Digest? get previousInputsDigest;

factory PostProcessAnchorNodeState(
Expand All @@ -438,6 +458,9 @@ abstract class PostProcessAnchorNodeState

/// Work that needs doing for a node that tracks its inputs.
class PendingBuildAction extends EnumClass {
static Serializer<PendingBuildAction> get serializer =>
_$pendingBuildActionSerializer;

static const PendingBuildAction none = _$none;
static const PendingBuildAction buildIfInputsChanged = _$buildIfInputsChanged;
static const PendingBuildAction build = _$build;
Expand All @@ -448,3 +471,59 @@ class PendingBuildAction extends EnumClass {
static PendingBuildAction valueOf(String name) =>
_$pendingBuildActionValueOf(name);
}

@SerializersFor([AssetNode])
final Serializers serializers =
(_$serializers.toBuilder()
..add(AssetIdSerializer())
..add(DigestSerializer()))
.build();

/// Serializer for [AssetId].
///
/// It would also work to make `AssetId` a `built_value` class, but there's
/// little benefit and it's nicer to keep codegen local to this package.
class AssetIdSerializer implements PrimitiveSerializer<AssetId> {
@override
Iterable<Type> get types => [AssetId];

@override
String get wireName => 'AssetId';

@override
AssetId deserialize(
Serializers serializers,
Object serialized, {
FullType specifiedType = FullType.unspecified,
}) => AssetId.parse(serialized as String);

@override
Object serialize(
Serializers serializers,
AssetId object, {
FullType specifiedType = FullType.unspecified,
}) => object.toString();
}

/// Serializer for [Digest].
class DigestSerializer implements PrimitiveSerializer<Digest> {
@override
Iterable<Type> get types => [Digest];

@override
String get wireName => 'Digest';

@override
Digest deserialize(
Serializers serializers,
Object serialized, {
FullType specifiedType = FullType.unspecified,
}) => Digest(base64.decode(serialized as String));

@override
Object serialize(
Serializers serializers,
Digest object, {
FullType specifiedType = FullType.unspecified,
}) => base64.encode(object.bytes);
}
Loading
Loading