Skip to content

Commit 3fc9510

Browse files
authored
Add --debug-builders flag (#4243)
* Add `--debug-builders` flag * Reword * Rename to --dart-jit-vm-arg * Remove unused flag * Fix processes integration test
1 parent 657e55f commit 3fc9510

File tree

8 files changed

+67
-1
lines changed

8 files changed

+67
-1
lines changed

build_runner/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
## 2.9.1-wip
22

33
- Internal changes for `build_test`.
4+
- Add the `--dart-jit-vm-arg` option. Its values are passed to `dart run` when
5+
a build script is started in JIT mode. This allows specifying options to
6+
attach a debugger to builders.
47

58
## 2.9.0
69

build_runner/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
_Questions? Suggestions? Found a bug? Please
1+
_Questions? Suggestions? Found a bug? Please
22
[file an issue](https://github.com/dart-lang/build/issues) or
33
[start a discussion](https://github.com/dart-lang/build/discussions)._
44

@@ -203,3 +203,14 @@ targets:
203203
For advanced use cases it's possible to write your own builder.
204204
205205
Get started with the [build package documentation](https://pub.dev/packages/build).
206+
For testing builders, see the [`build_test` package](https://pub.dev/packages/build_test).
207+
208+
## Debugging builds
209+
210+
To debug the build process, note that `build_runner` spawns a child process to run
211+
the build.
212+
Options used to spawn this process can be customized, which allows attaching a debugger:
213+
214+
```shell
215+
dart run build_runner build --dart-jit-vm-arg=--observe --dart-jit-vm-arg=--pause-isolates-on-start
216+
```

build_runner/lib/src/bootstrap/bootstrapper.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Bootstrapper {
4141
/// they do not exist or have the wrong types.
4242
Future<int> run(
4343
BuiltList<String> arguments, {
44+
required Iterable<String> jitVmArgs,
4445
Iterable<String>? experiments,
4546
}) async {
4647
while (true) {
@@ -67,6 +68,7 @@ class Bootstrapper {
6768
script: entrypointDillPath,
6869
arguments: arguments,
6970
message: buildProcessState.serialize(),
71+
jitVmArgs: jitVmArgs,
7072
);
7173
buildProcessState.deserializeAndSet(result.message);
7274
final exitCode = result.exitCode;

build_runner/lib/src/bootstrap/processes.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,21 @@ class ParentProcess {
2020
/// Runs Dart [script] with [arguments], sends it [message], listens for and
2121
/// returns the response.
2222
///
23+
/// When the underlying script is run with `dart run`, the [jitVmArgs] are
24+
/// forwarded to the Dart VM. This can be used to e.g. start the VM with
25+
/// debugging options.
26+
///
2327
/// The child process should use [ChildProcess] to communicate with the
2428
/// parent.
2529
static Future<RunAndSendResult> runAndSend({
2630
required String script,
2731
required Iterable<String> arguments,
2832
required String message,
33+
required Iterable<String> jitVmArgs,
2934
}) async {
3035
final process = await _startWithReaper(Platform.resolvedExecutable, [
3136
'run',
37+
...jitVmArgs,
3238
script,
3339
...arguments,
3440
]);

build_runner/lib/src/build_runner.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class BuildRunner {
162162

163163
return await Bootstrapper().run(
164164
arguments,
165+
jitVmArgs: commandLine.jitVmArgs ?? const Iterable.empty(),
165166
experiments: commandLine.enableExperiments,
166167
);
167168
}

build_runner/lib/src/build_runner_command_line.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class BuildRunnerCommandLine {
4545
final String? config;
4646
final BuiltList<String>? defines;
4747
final BuiltList<String>? enableExperiments;
48+
final BuiltList<String>? jitVmArgs;
4849
final String? hostname;
4950
final bool? liveReload;
5051
final String? logPerformance;
@@ -67,6 +68,7 @@ class BuildRunnerCommandLine {
6768
config = argResults.stringNamed(configOption),
6869
defines = argResults.listNamed(defineOption),
6970
enableExperiments = argResults.listNamed(enableExperimentOption),
71+
jitVmArgs = argResults.listNamed(dartJitVmArgOption),
7072
hostname = argResults.stringNamed(hostnameOption),
7173
liveReload = argResults.boolNamed(liveReloadOption),
7274
logPerformance = argResults.stringNamed(logPerformanceOption),
@@ -121,6 +123,7 @@ const configOption = 'config';
121123
const defineOption = 'define';
122124
const deleteFilesByDefaultOption = 'delete-conflicting-outputs';
123125
const enableExperimentOption = 'enable-experiment';
126+
const dartJitVmArgOption = 'dart-jit-vm-arg';
124127
const hostnameOption = 'hostname';
125128
const liveReloadOption = 'live-reload';
126129
const logPerformanceOption = 'log-performance';
@@ -252,6 +255,15 @@ class _Build extends Command<BuildRunnerCommandLine> {
252255
..addMultiOption(
253256
enableExperimentOption,
254257
help: 'A list of dart language experiments to enable.',
258+
)
259+
..addMultiOption(
260+
dartJitVmArgOption,
261+
help:
262+
'Flags to pass to `dart run` when launching the inner build '
263+
'script\n.'
264+
'For example, `--dart-jit-vm-arg "--observe" '
265+
'--dart-jit-vm-arg "--pause-isolates-on-start"` would start the '
266+
'build script with a debugger attached to it.',
255267
);
256268
}
257269

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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:test/test.dart';
6+
7+
import '../common/common.dart';
8+
9+
void main() {
10+
test('passing custom vm args to build script', () async {
11+
final pubspecs = await Pubspecs.load();
12+
final tester = BuildRunnerTester(pubspecs);
13+
14+
tester.writePackage(
15+
name: 'root_pkg',
16+
dependencies: ['build_runner'],
17+
files: {},
18+
);
19+
20+
// This should lauch the inner build script with dart run --help ..., so we
21+
// check that help output is emitted to verify that the option is respected.
22+
final output = await tester.run(
23+
'root_pkg',
24+
'dart run build_runner build --dart-jit-vm-arg=--help',
25+
);
26+
27+
expect(output, contains('Run "dart help" to see global options.'));
28+
});
29+
}

build_runner/test/integration_tests/processes_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Future<void> main() async {
3434
final processResult = await ParentProcess.runAndSend(
3535
script: 'bin/child.dart',
3636
arguments: [],
37+
jitVmArgs: [],
3738
message: 'payload');
3839
stdout.write(
3940
'Parent received: '
@@ -78,6 +79,7 @@ Future<void> main() async {
7879
await ParentProcess.runAndSend(
7980
script: 'bin/child.dart',
8081
arguments: [],
82+
jitVmArgs: [],
8183
message: 'payload');
8284
}
8385
''');

0 commit comments

Comments
 (0)