Skip to content

Combine InMemoryAssetReader and InMemoryAssetWriter into InMemoryAssetReaderWriter #3854

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 5 commits into from
Feb 14, 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
3 changes: 1 addition & 2 deletions _test_common/lib/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export 'package:build_test/build_test.dart'
export 'assets.dart';
export 'builders.dart';
export 'descriptors.dart';
export 'in_memory_reader.dart';
export 'in_memory_writer.dart';
export 'in_memory_reader_writer.dart';
export 'matchers.dart';
export 'package_graphs.dart';
export 'sdk.dart';
Expand Down
30 changes: 0 additions & 30 deletions _test_common/lib/in_memory_reader.dart

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@ import 'package:build_test/build_test.dart';
import 'package:path/path.dart' as p;
import 'package:watcher/watcher.dart';

class InMemoryRunnerAssetWriter extends InMemoryAssetWriter
implements RunnerAssetWriter {
class InMemoryRunnerAssetReaderWriter extends InMemoryAssetReaderWriter
implements RunnerAssetReader, RunnerAssetWriter {
final _onCanReadController = StreamController<AssetId>.broadcast();
Stream<AssetId> get onCanRead => _onCanReadController.stream;
void Function(AssetId)? onDelete;

InMemoryRunnerAssetReaderWriter({super.sourceAssets, super.rootPackage});

@override
Future<bool> canRead(AssetId id) {
_onCanReadController.add(id);
return super.canRead(id);
}

@override
Future writeAsBytes(AssetId id, List<int> bytes) async {
var type = assets.containsKey(id) ? ChangeType.MODIFY : ChangeType.ADD;
Expand Down
23 changes: 9 additions & 14 deletions _test_common/lib/test_environment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,26 @@

import 'dart:async';

// ignore: implementation_imports
import 'package:build_runner_core/src/asset/reader.dart';
// ignore: implementation_imports
import 'package:build_runner_core/src/asset/writer.dart';
// ignore: implementation_imports
import 'package:build_runner_core/src/environment/build_environment.dart';
import 'package:build_runner_core/build_runner_core.dart';
import 'package:logging/logging.dart';

import 'common.dart';
import 'in_memory_reader_writer.dart';

/// A [BuildEnvironment] for testing.
///
/// Defaults to using an [InMemoryRunnerAssetReader] and
/// [InMemoryRunnerAssetWriter].
/// Defaults to an empty [InMemoryRunnerAssetReaderWriter].
///
/// To handle prompts you must first set `nextPromptResponse`. Alternatively
/// you can set `throwOnPrompt` to `true` to emulate a
/// [NonInteractiveBuildException].
class TestBuildEnvironment extends BuildEnvironment {
final InMemoryRunnerAssetReaderWriter _readerWriter;

@override
final RunnerAssetReader reader;
RunnerAssetReader get reader => _readerWriter;
@override
final RunnerAssetWriter writer;
RunnerAssetWriter get writer => _readerWriter;

/// If true, this will throw a [NonInteractiveBuildException] for all calls to
/// [prompt].
Expand All @@ -44,11 +41,9 @@ class TestBuildEnvironment extends BuildEnvironment {
int? _nextPromptResponse;

TestBuildEnvironment(
{RunnerAssetReader? reader,
RunnerAssetWriter? writer,
{InMemoryRunnerAssetReaderWriter? readerWriter,
this.throwOnPrompt = false})
: reader = reader ?? InMemoryRunnerAssetReader(),
writer = writer ?? InMemoryRunnerAssetWriter();
: _readerWriter = readerWriter ?? InMemoryRunnerAssetReaderWriter();

@override
void onLog(LogRecord record) => logRecords.add(record);
Expand Down
43 changes: 25 additions & 18 deletions _test_common/lib/test_phases.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import 'package:build_test/build_test.dart';
import 'package:logging/logging.dart';
import 'package:test/test.dart';

import 'in_memory_reader.dart';
import 'in_memory_writer.dart';
import 'in_memory_reader_writer.dart';
import 'package_graphs.dart';

Future<void> wait(int milliseconds) =>
Expand Down Expand Up @@ -41,14 +40,13 @@ void _printOnFailure(LogRecord record) {
/// For example `$$myapp|lib/utils.copy.dart` will check that the generated
/// output was written to the build cache.
///
/// [resumeFrom] reuses the `readerWriter` from a previous [BuildResult].
///
/// [packageGraph] supplies the root package into which the outputs are to be
/// written.
///
/// [status] optionally indicates the desired outcome.
///
/// [writer] can optionally be provided to capture assets written by the
/// builders (e.g. when [outputs] is not sufficient).
///
/// [logLevel] sets the builder log level and [onLog] can optionally capture
/// build log messages.
///
Expand All @@ -67,15 +65,14 @@ void _printOnFailure(LogRecord record) {
/// });
/// }
///
Future<BuildResult> testBuilders(
Future<TestBuildersResult> testBuilders(
List<BuilderApplication> builders,
Map<String, /*String|List<int>*/ Object> inputs, {
TestBuildersResult? resumeFrom,
Map<String, /*String|List<int>*/ Object>? outputs,
PackageGraph? packageGraph,
BuildStatus status = BuildStatus.success,
Map<String, BuildConfig>? overrideBuildConfig,
InMemoryRunnerAssetReader? reader,
InMemoryRunnerAssetWriter? writer,
Level? logLevel,
// A better way to "silence" logging than setting logLevel to OFF.
void Function(LogRecord record) onLog = _printOnFailure,
Expand All @@ -88,14 +85,16 @@ Future<BuildResult> testBuilders(
Set<BuildFilter> buildFilters = const {},
String? logPerformanceDir,
String expectedGeneratedDir = 'generated',
void Function(AssetId id)? onDelete,
}) async {
packageGraph ??= buildPackageGraph({rootPackage('a'): []});
writer ??= InMemoryRunnerAssetWriter();
reader ??= InMemoryRunnerAssetReader.shareAssetCache(writer.assets,
rootPackage: packageGraph.root.name);
final readerWriter = resumeFrom == null
? InMemoryRunnerAssetReaderWriter(rootPackage: packageGraph.root.name)
: resumeFrom.readerWriter;
readerWriter.onDelete = onDelete;
var pkgConfigId =
AssetId(packageGraph.root.name, '.dart_tool/package_config.json');
if (!await reader.canRead(pkgConfigId)) {
if (!await readerWriter.canRead(pkgConfigId)) {
var packageConfig = {
'configVersion': 2,
'packages': [
Expand All @@ -108,21 +107,21 @@ Future<BuildResult> testBuilders(
},
],
};
await writer.writeAsString(pkgConfigId, jsonEncode(packageConfig));
await readerWriter.writeAsString(pkgConfigId, jsonEncode(packageConfig));
}

inputs.forEach((serializedId, contents) {
var id = makeAssetId(serializedId);
if (contents is String) {
reader!.cacheStringAsset(id, contents);
readerWriter.cacheStringAsset(id, contents);
} else if (contents is List<int>) {
reader!.cacheBytesAsset(id, contents);
readerWriter.cacheBytesAsset(id, contents);
}
});

builderConfigOverrides ??= const {};
var environment = OverrideableEnvironment(IOEnvironment(packageGraph),
reader: reader, writer: writer, onLog: onLog);
reader: readerWriter, writer: readerWriter, onLog: onLog);
var logSubscription =
LogSubscription(environment, verbose: verbose, logLevel: logLevel);
var options = await BuildOptions.create(logSubscription,
Expand All @@ -149,12 +148,13 @@ Future<BuildResult> testBuilders(
if (checkBuildStatus) {
checkBuild(result,
outputs: outputs,
writer: writer,
writer: readerWriter,
status: status,
rootPackage: packageGraph.root.name,
expectedGeneratedDir: expectedGeneratedDir);
}
return result;

return TestBuildersResult(buildResult: result, readerWriter: readerWriter);
}

/// Translates expected outptus which start with `$$` to the build cache and
Expand Down Expand Up @@ -190,3 +190,10 @@ void checkBuild(BuildResult result,
mapAssetIds: (id) => mapHidden(id, expectedGeneratedDir));
}
}

class TestBuildersResult {
final BuildResult buildResult;
final InMemoryRunnerAssetReaderWriter readerWriter;

TestBuildersResult({required this.buildResult, required this.readerWriter});
}
1 change: 1 addition & 0 deletions build/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Add `package:build/src/internal.dart` for use by `build_resolvers`,
`build_runner_core` and `build_test`.
- Use `build_test` 3.0.0.

## 2.4.2

Expand Down
2 changes: 1 addition & 1 deletion build/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dependencies:

dev_dependencies:
build_resolvers: ^2.4.0
build_test: ^2.0.0
build_test: ^3.0.0-wip
dart_flutter_team_lints: ^3.1.0
test: ^1.16.0

Expand Down
3 changes: 1 addition & 2 deletions build/test/builder/build_step_impl_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ void main() {
late InMemoryAssetReader reader;

setUp(() {
writer = InMemoryAssetWriter();
reader = InMemoryAssetReader.shareAssetCache(writer.assets);
writer = reader = InMemoryAssetReaderWriter();
});

test('tracks outputs created by a builder', () async {
Expand Down
3 changes: 1 addition & 2 deletions build/test/generate/run_builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ void main() {
});
builder = TestBuilder(
extraWork: (buildStep, __) => buildStep.fetchResource(resource));
writer = InMemoryAssetWriter();
reader = InMemoryAssetReader.shareAssetCache(writer.assets);
writer = reader = InMemoryAssetReaderWriter();
addAssets(inputs, writer);
});

Expand Down
4 changes: 4 additions & 0 deletions build_modules/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.0.12-wip

- Use `build_test` 3.0.0.

## 5.0.11

- Support 3.8.0 pre-release sdks.
Expand Down
4 changes: 2 additions & 2 deletions build_modules/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: build_modules
version: 5.0.11
version: 5.0.12-wip
description: >-
Builders to analyze and split Dart code into individually compilable modules
based on imports.
Expand Down Expand Up @@ -32,7 +32,7 @@ dev_dependencies:
path: test/fixtures/b
# Used inside tests
build_runner: ^2.0.0
build_test: ^2.0.0
build_test: ^3.0.0-wip
json_serializable: ^6.0.0
test: ^1.16.0

Expand Down
8 changes: 3 additions & 5 deletions build_modules/test/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ Future<void> testBuilderAndCollectAssets(
void Function(LogRecord log)? onLog,
void Function(AssetId, Iterable<AssetId>)?
reportUnusedAssetsForInput}) async {
var writer = InMemoryAssetWriter();
onLog ??= (log) => printOnFailure('${log.level}: ${log.message}');
await testBuilder(builder, assets,
final result = await testBuilder(builder, assets,
generateFor: generateFor,
outputs: outputs,
onLog: onLog,
reportUnusedAssetsForInput: reportUnusedAssetsForInput,
writer: writer);
writer.assets.forEach((id, value) {
reportUnusedAssetsForInput: reportUnusedAssetsForInput);
result.readerWriter.assets.forEach((id, value) {
assets['${id.package}|${id.path}'] = value;
});
}
1 change: 1 addition & 0 deletions build_resolvers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Start using `package:build/src/internal.dart`.
- Switch `BuildAssetUriResolver` dependency crawl to an iterative
algorithm, preventing stack overflows.
- Use `build_test` 3.0.0.

## 2.4.4

Expand Down
2 changes: 1 addition & 1 deletion build_resolvers/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies:
yaml: ^3.0.0

dev_dependencies:
build_test: ^2.0.0
build_test: ^3.0.0-wip
dart_flutter_team_lints: ^3.1.0
test: ^1.16.0

Expand Down
Loading
Loading