Skip to content

Commit 1f0729d

Browse files
authored
Merge BuildEnvironment and BuildOptions into new BuildRunnerState. (#4166)
1 parent b3eb1dc commit 1f0729d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1141
-1391
lines changed

_test_common/lib/test_phases.dart

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'dart:async';
55
import 'dart:convert';
66

77
import 'package:build/build.dart';
8+
// ignore: implementation_imports
9+
import 'package:build_runner/src/internal.dart';
810
import 'package:build_runner_core/build_runner_core.dart';
911
import 'package:build_test/build_test.dart';
1012
// ignore: implementation_imports
@@ -81,13 +83,11 @@ Future<TestBuildersResult> testPhases(
8183
// A better way to "silence" logging than setting logLevel to OFF.
8284
void Function(LogRecord record) onLog = _printOnFailure,
8385
bool checkBuildStatus = true,
84-
bool deleteFilesByDefault = true,
8586
bool enableLowResourcesMode = false,
8687
bool verbose = false,
8788
Set<BuildDirectory> buildDirs = const {},
8889
Set<BuildFilter> buildFilters = const {},
8990
String? logPerformanceDir,
90-
String expectedGeneratedDir = 'generated',
9191
void Function(AssetId id)? onDelete,
9292
}) async {
9393
packageGraph ??= buildPackageGraph({rootPackage('a'): []});
@@ -132,38 +132,33 @@ Future<TestBuildersResult> testPhases(
132132
}
133133
});
134134

135-
var environment = BuildEnvironment(
136-
packageGraph,
137-
reader: readerWriter,
138-
writer: readerWriter,
139-
);
140-
141135
buildLog.configuration = buildLog.configuration.rebuild((b) {
142136
b.onLog = onLog;
143137
b.verbose = verbose;
144138
});
145139

146-
var options = await BuildConfiguration.create(
147-
packageGraph: packageGraph,
148-
reader: environment.reader,
149-
skipBuildScriptCheck: true,
150-
enableLowResourcesMode: enableLowResourcesMode,
151-
logPerformanceDir: logPerformanceDir,
140+
final buildPlan = await BuildPlan.load(
141+
builders: builders.build(),
142+
// ignore: invalid_use_of_visible_for_testing_member
143+
buildOptions: BuildOptions.forTests(
144+
buildDirs: buildDirs.build(),
145+
buildFilters: buildFilters.build(),
146+
enableLowResourcesMode: enableLowResourcesMode,
147+
logPerformanceDir: logPerformanceDir,
148+
skipBuildScriptCheck: true,
149+
trackPerformance: logPerformanceDir != null,
150+
verbose: verbose,
151+
),
152+
testingOverrides: TestingOverrides(
153+
packageGraph: packageGraph,
154+
reader: readerWriter,
155+
writer: readerWriter,
156+
),
152157
);
153158

154159
BuildResult result;
155-
var build = await BuildRunner.create(
156-
options,
157-
environment,
158-
builders.build(),
159-
BuiltMap(),
160-
isReleaseBuild: false,
161-
);
162-
result = await build.run(
163-
{},
164-
buildDirs: buildDirs.build(),
165-
buildFilters: buildFilters.build(),
166-
);
160+
final build = await BuildSeries.create(buildPlan: buildPlan);
161+
result = await build.run({});
167162
await build.beforeExit();
168163

169164
if (checkBuildStatus) {
@@ -173,7 +168,6 @@ Future<TestBuildersResult> testPhases(
173168
readerWriter: readerWriter,
174169
status: status,
175170
rootPackage: packageGraph.root.name,
176-
expectedGeneratedDir: expectedGeneratedDir,
177171
);
178172
}
179173

@@ -188,7 +182,6 @@ void checkBuild(
188182
required TestReaderWriter readerWriter,
189183
BuildStatus status = BuildStatus.success,
190184
String rootPackage = 'a',
191-
String expectedGeneratedDir = 'generated',
192185
}) {
193186
expect(result.status, status, reason: '$result');
194187

@@ -204,11 +197,11 @@ void checkBuild(
204197
}
205198
}
206199

207-
AssetId mapHidden(AssetId id, String expectedGeneratedDir) =>
200+
AssetId mapHidden(AssetId id) =>
208201
unhiddenAssets.contains(id)
209202
? AssetId(
210203
rootPackage,
211-
'.dart_tool/build/$expectedGeneratedDir/${id.package}/${id.path}',
204+
'.dart_tool/build/generated/${id.package}/${id.path}',
212205
)
213206
: id;
214207

@@ -217,7 +210,7 @@ void checkBuild(
217210
unhiddenOutputs,
218211
result.outputs,
219212
readerWriter,
220-
mapAssetIds: (id) => mapHidden(id, expectedGeneratedDir),
213+
mapAssetIds: mapHidden,
221214
);
222215
}
223216
}

_test_common/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ environment:
99
dependencies:
1010
build: any
1111
build_config: any
12+
build_runner: any
1213
build_runner_core: any
1314
build_test: any
1415
built_collection: any
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:build/build.dart';
6+
import 'package:build_runner_core/build_runner_core.dart';
7+
import 'package:built_collection/built_collection.dart';
8+
9+
import 'commands/build_filter.dart';
10+
import 'commands/build_options.dart';
11+
12+
/// Options and derived configuration for a build.
13+
class BuildPlan {
14+
final BuiltList<BuilderApplication> builders;
15+
final BuildOptions buildOptions;
16+
final TestingOverrides testingOverrides;
17+
18+
final PackageGraph packageGraph;
19+
final AssetReader reader;
20+
final RunnerAssetWriter writer;
21+
final TargetGraph targetGraph;
22+
final BuildPhases buildPhases;
23+
24+
BuildPlan({
25+
required this.builders,
26+
required this.buildOptions,
27+
required this.testingOverrides,
28+
required this.packageGraph,
29+
required this.reader,
30+
required this.writer,
31+
required this.targetGraph,
32+
required this.buildPhases,
33+
});
34+
35+
/// Loads a build plan.
36+
///
37+
/// Loads the package strucure and build configuration; prepares [reader]
38+
/// and [writer] and deduces the [buildPhases] that will run.
39+
static Future<BuildPlan> load({
40+
required BuiltList<BuilderApplication> builders,
41+
required BuildOptions buildOptions,
42+
required TestingOverrides testingOverrides,
43+
}) async {
44+
final packageGraph =
45+
testingOverrides.packageGraph ?? await PackageGraph.forThisPackage();
46+
47+
var reader = testingOverrides.reader;
48+
var writer = testingOverrides.writer;
49+
50+
if (reader == null || writer == null) {
51+
final readerWriter = ReaderWriter(packageGraph);
52+
reader ??= readerWriter;
53+
writer ??= readerWriter;
54+
}
55+
56+
final targetGraph = await TargetGraph.forPackageGraph(
57+
reader: reader,
58+
packageGraph: packageGraph,
59+
testingOverrides: testingOverrides,
60+
configKey: buildOptions.configKey,
61+
);
62+
63+
final buildPhases = await createBuildPhases(
64+
targetGraph,
65+
builders,
66+
buildOptions.builderConfigOverrides,
67+
buildOptions.isReleaseBuild,
68+
);
69+
if (buildPhases.inBuildPhases.isEmpty &&
70+
buildPhases.postBuildPhase.builderActions.isEmpty) {
71+
buildLog.warning('Nothing to build.');
72+
}
73+
74+
return BuildPlan(
75+
builders: builders,
76+
buildOptions: buildOptions,
77+
testingOverrides: testingOverrides,
78+
packageGraph: packageGraph,
79+
reader: reader,
80+
writer: writer,
81+
targetGraph: targetGraph,
82+
buildPhases: buildPhases,
83+
);
84+
}
85+
86+
BuildPlan copyWith({
87+
BuiltSet<BuildDirectory>? buildDirs,
88+
BuiltSet<BuildFilter>? buildFilters,
89+
AssetReader? reader,
90+
RunnerAssetWriter? writer,
91+
}) => BuildPlan(
92+
builders: builders,
93+
buildOptions: buildOptions.copyWith(
94+
buildDirs: buildDirs,
95+
buildFilters: buildFilters,
96+
),
97+
testingOverrides: testingOverrides,
98+
packageGraph: packageGraph,
99+
targetGraph: targetGraph,
100+
reader: reader ?? this.reader,
101+
writer: writer ?? this.writer,
102+
buildPhases: buildPhases,
103+
);
104+
}

build_runner/lib/src/build_script_generate/build_script_generate.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import 'package:graphs/graphs.dart';
1313
import 'package:path/path.dart' as p;
1414
import 'package:pub_semver/pub_semver.dart';
1515

16-
import '../package_graph/build_config_overrides.dart';
1716
import 'builder_ordering.dart';
1817

1918
const scriptLocation = '$entryPointDir/build.dart';
@@ -81,7 +80,11 @@ Future<BuildScriptInfo> findBuildScriptOptions() async {
8180
hashCode: (n) => n.name.hashCode,
8281
).expand((c) => c);
8382
var reader = ReaderWriter(packageGraph);
84-
var overrides = await findBuildConfigOverrides(packageGraph, reader);
83+
var overrides = await findBuildConfigOverrides(
84+
packageGraph: packageGraph,
85+
reader: reader,
86+
configKey: null,
87+
);
8588
Future<BuildConfig> packageBuildConfig(PackageNode package) async {
8689
if (overrides.containsKey(package.name)) {
8790
return overrides[package.name]!;

build_runner/lib/src/commands/build_command.dart

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import 'package:build_runner_core/build_runner_core.dart';
77
import 'package:built_collection/built_collection.dart';
88
import 'package:io/io.dart';
99

10+
import '../build_plan.dart';
1011
import '../build_script_generate/build_process_state.dart';
11-
import '../package_graph/build_config_overrides.dart';
1212
import 'build_options.dart';
1313
import 'build_runner_command.dart';
1414

@@ -42,42 +42,14 @@ class BuildCommand implements BuildRunnerCommand {
4242
b.verbose = buildOptions.verbose;
4343
b.onLog = testingOverrides.onLog;
4444
});
45-
final packageGraph =
46-
testingOverrides.packageGraph ?? await PackageGraph.forThisPackage();
47-
var environment = BuildEnvironment(
48-
packageGraph,
49-
outputSymlinksOnly: buildOptions.outputSymlinksOnly,
50-
reader: testingOverrides.reader,
51-
writer: testingOverrides.writer,
52-
);
53-
var options = await BuildConfiguration.create(
54-
packageGraph: packageGraph,
55-
reader: environment.reader,
56-
skipBuildScriptCheck: buildOptions.skipBuildScriptCheck,
57-
overrideBuildConfig:
58-
testingOverrides.buildConfig ??
59-
await findBuildConfigOverrides(
60-
packageGraph,
61-
environment.reader,
62-
configKey: buildOptions.configKey,
63-
),
64-
enableLowResourcesMode: buildOptions.enableLowResourcesMode,
65-
trackPerformance: buildOptions.trackPerformance,
66-
logPerformanceDir: buildOptions.logPerformanceDir,
67-
resolvers: testingOverrides.resolvers,
68-
);
69-
var build = await BuildRunner.create(
70-
options,
71-
environment,
72-
builders,
73-
buildOptions.builderConfigOverrides,
74-
isReleaseBuild: buildOptions.isReleaseBuild,
75-
);
76-
var result = await build.run(
77-
{},
78-
buildDirs: buildOptions.buildDirs,
79-
buildFilters: buildOptions.buildFilters,
45+
46+
final buildPlan = await BuildPlan.load(
47+
builders: builders,
48+
buildOptions: buildOptions,
49+
testingOverrides: testingOverrides,
8050
);
51+
final build = await BuildSeries.create(buildPlan: buildPlan);
52+
final result = await build.run({});
8153
await build.beforeExit();
8254
return result;
8355
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:build/build.dart';
6+
import 'package:glob/glob.dart';
7+
import 'package:path/path.dart' as p;
8+
9+
/// Describes a set of files that should be built.
10+
class BuildFilter {
11+
/// The package name glob that files must live under in order to match.
12+
final Glob _package;
13+
14+
/// A glob for files under [_package] that must match.
15+
final Glob _path;
16+
17+
BuildFilter(this._package, this._path);
18+
19+
/// Builds a [BuildFilter] from a command line argument.
20+
///
21+
/// Both relative paths and package: uris are supported. Relative
22+
/// paths are treated as relative to the [rootPackage].
23+
///
24+
/// Globs are supported in package names and paths.
25+
factory BuildFilter.fromArg(String arg, String rootPackage) {
26+
var uri = Uri.parse(arg);
27+
if (uri.scheme == 'package') {
28+
var package = uri.pathSegments.first;
29+
var glob = Glob(p.url.joinAll(['lib', ...uri.pathSegments.skip(1)]));
30+
return BuildFilter(Glob(package), glob);
31+
} else if (uri.scheme.isEmpty) {
32+
return BuildFilter(Glob(rootPackage), Glob(uri.path));
33+
} else {
34+
throw FormatException('Unsupported scheme ${uri.scheme}', uri);
35+
}
36+
}
37+
38+
/// Returns whether or not [id] mathes this filter.
39+
bool matches(AssetId id) =>
40+
_package.matches(id.package) && _path.matches(id.path);
41+
42+
@override
43+
int get hashCode => Object.hash(
44+
_package.context,
45+
_package.pattern,
46+
_package.recursive,
47+
_path.context,
48+
_path.pattern,
49+
_path.recursive,
50+
);
51+
52+
@override
53+
bool operator ==(Object other) =>
54+
other is BuildFilter &&
55+
other._path.context == _path.context &&
56+
other._path.pattern == _path.pattern &&
57+
other._path.recursive == _path.recursive &&
58+
other._package.context == _package.context &&
59+
other._package.pattern == _package.pattern &&
60+
other._package.recursive == _package.recursive;
61+
}

0 commit comments

Comments
 (0)