Skip to content

Commit

Permalink
Forbid multiple writes to the same asset (#3228)
Browse files Browse the repository at this point in the history
Closes #3227.
  • Loading branch information
simolus3 committed Dec 20, 2021
1 parent 3245c90 commit 045a405
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
5 changes: 5 additions & 0 deletions build/CHANGELOG.md
@@ -1,3 +1,8 @@
## 2.2.1

- Fix a bug where builders were allowed to write to the same asset multiple
times.

## 2.2.0

- Allow reusing the values held by `Resource`s when the resource has a `dispose`
Expand Down
10 changes: 10 additions & 0 deletions build/lib/src/builder/build_step_impl.dart
Expand Up @@ -47,6 +47,8 @@ class BuildStepImpl implements BuildStep {
/// The result of any writes which are starting during this step.
final _writeResults = <Future<Result<void>>>[];

final _writtenAssets = <AssetId>{};

/// Used internally for reading files.
final AssetReader _reader;

Expand Down Expand Up @@ -170,6 +172,14 @@ class BuildStepImpl implements BuildStep {
if (!allowedOutputs.contains(id)) {
throw UnexpectedOutputException(id, expected: allowedOutputs);
}

if (!_writtenAssets.add(id)) {
throw InvalidOutputException(
id,
'This build step already wrote to `$id`. Duplicate writes to the same '
'asset are forbidden.',
);
}
}

@override
Expand Down
2 changes: 1 addition & 1 deletion build/pubspec.yaml
@@ -1,5 +1,5 @@
name: build
version: 2.2.0
version: 2.2.1
description: A package for authoring build_runner compatible code generators.
repository: https://github.com/dart-lang/build/tree/master/build

Expand Down
13 changes: 13 additions & 0 deletions build/test/builder/build_step_impl_test.dart
Expand Up @@ -55,6 +55,19 @@ void main() {
var actual = await buildStep.fetchResource(intResource);
expect(actual, expected);
});

test('does not allow multiple writes to the same output', () async {
final id = outputs.first;
await buildStep.writeAsString(id, 'foo');

final expectedException = isA<InvalidOutputException>()
.having((e) => e.assetId, 'assetId', id)
.having((e) => e.message, 'message', contains('already wrote to'));

expect(
() => buildStep.writeAsString(id, 'bar'), throwsA(expectedException));
expect(() => buildStep.writeAsBytes(id, []), throwsA(expectedException));
});
});

group('with in memory file system', () {
Expand Down

0 comments on commit 045a405

Please sign in to comment.