Skip to content

[native_toolchain_c] Inject ProcessManager for process spawning - #3531

Merged
dcharkes merged 6 commits into
dart-lang:mainfrom
Varadraj75:fix-3072-process-manager
Aug 12, 2026
Merged

dcharkes merged 6 commits into
dart-lang:mainfrom
Varadraj75:fix-3072-process-manager

Conversation

@Varadraj75

Copy link
Copy Markdown
Contributor

Description

Most CI time in this repo goes to package:native_toolchain_c and package:hooks_runner integration tests, because every test spawns real toolchains. #3072 proposes flutter_tools style unit tests where the file system and process calls are mocked. This PR does the process half of that seam.

Adds an optional processManager parameter next to the existing logger parameters on CBuilder.run, CLinker.run, CLibrary.build, CLibrary.link, and ToolResolvingContext, defaulting to LocalProcessManager. All process spawning in the package now goes through package:process instead of dart:io Process directly. The tool resolvers get their logger via ToolResolvingContext, so processManager is threaded the same way. This also resolves the package:process half of the TODO in tool_resolver.dart, the package:file half stays for the follow-up.

Adds a fake ProcessManager plus hermetic unit tests for runProcess and environmentFromBatchFile that assert the invoked command lines without running real processes. Follow-up PRs will do the FileSystem side and grow the mocked test coverage from there.

Related Issues

Part of #3072. Not marked Fixes on purpose, the issue stays open for the FileSystem follow-up.

PR Checklist

  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.
  • I've run dart tool/ci.dart --all locally and resolved all issues identified. This ensures the PR is formatted, has no lint errors, and ran all code generators. This applies to the packages part of the toplevel pubspec.yaml workspace.
  • All existing and new tests are passing. I added new tests to check the change I am making.
  • The PR is actually solving the issue. PRs that don't solve the issue will be closed. Please be respectful of the maintainers' time. If it's not clear what the issue is, feel free to ask questions on the GitHub issue before submitting a PR.
  • I have updated CHANGELOG.md for the relevant packages. (Not needed for small changes such as doc typos).
  • I have updated the pubspec package version if necessary.

Adds an optional processManager parameter alongside the existing
logger parameters and routes all process spawning through it,
defaulting to LocalProcessManager. Groundwork for mocked unit
tests in the flutter_tools style.

Issue: dart-lang#3072

@dcharkes dcharkes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this and the file system change, we should start reorganizing the tests into two subdirectories.

  1. for integration tests that use the file system and processes - and some of them may only run on some host OSes
  2. unit tests, the should be blazing fast, and run for every target OS on every host OS.

But that's for a next PR then.

class FakeProcessManager implements ProcessManager {
FakeProcessManager({this.result = const ScriptedResult()});

final ScriptedResult result;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And with the callback you can also create files on the fake file system that way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review! The windows failures look like they're from this change, digging in. Will also rework the fake to take a list of results with a callback like the flutter_tools one.

Spell out where.exe in PathToolResolver: package:process resolves
extension-less executables via PATHEXT, which the filtered hook
environment does not define, crashing every build hook on Windows.

Rework FakeProcessManager to a list of FakeCommands with optional
command matching and an onRun callback, per review.

Issue: dart-lang#3072
…nager

# Conflicts:
#	pkgs/native_toolchain_c/CHANGELOG.md
@Varadraj75

Copy link
Copy Markdown
Contributor Author

Reworked the fake to a list of FakeCommands with optional exact command matching and an onRun callback, same shape as the flutter_tools one. The callback should come in handy for faking file output once the FileSystem part lands.

The windows failures turned out to be package:process itself: without a shell it resolves extension-less names via PATHEXT, and the filtered hook environment doesn't include PATHEXT, so every hook died on the plain "where" lookup. Spelled it out as where.exe. Adding PATHEXT to the hooks_runner environment filter might be worth a separate issue, happy to file it.

Future<Map<String, String>> environmentFromBatchFile(
Uri batchFile, {
List<String> arguments = const [],
required ProcessManager processManager,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change as this function is exported.

How about ProcessManager processManager = const LocalProcessManager(),?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, why did our CI bot not catch this. I would have expected this to go red.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, defaulted to const LocalProcessManager(). Hadn't realized this one was exported, good catch.

On the bot: possibly because 0.19.4 is still -wip, so apitool is diffing against the last published version, where this nets out as non-breaking additions.

class FakeProcessManager implements ProcessManager {
FakeProcessManager(this._commands);

final List<FakeCommand> _commands;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we catch if we did or did not consume all fake commands in a test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an allCommandsConsumed getter so tests can assert everything scripted actually ran.

@dcharkes

Copy link
Copy Markdown
Collaborator

where.exe

SGTM 👍

Adding PATHEXT to the hooks_runner environment filter might be worth a separate issue, happy to file it.

auto-submit Bot pushed a commit that referenced this pull request Aug 11, 2026
When using `package:process` it tries to look at `PATHEXT` before doing process invocations. And we're trying to start to use that in `package:native_toolchain_c`.

Context:

* #3531 (comment)
@dcharkes
dcharkes merged commit 2ee703b into dart-lang:main Aug 12, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants