Another internals question: if there’s an external...
# development
e
Another internals question: if there’s an external rustup toolchain, any idea why it’s being ignored when locating tools inside unit tests, e.g.
rustfmt
? I read the code, and see:
Copy code
def run_rustfmt(
    rule_runner: RuleRunner,
    targets: list[Target],
    *,
    extra_args: list[str] | None = None,
) -> FmtResult:
    rule_runner.set_options(extra_args or (), env_inherit={"PATH"})
in
src/python/pants/backend/rust/lint/rustfmt/rules_integration_test.py
. And rustfmt and rustup are in PATH:
Copy code
vscode ➜ /workspaces/pants (fix-vscode-devcontainer-arm64) $ rustup which rustfmt
/usr/local/rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin/rustfmt
Digging deeper, I see that Pants uses
rustup which
to locate
rustfmt
. In fact, when I debug it, I can see the
rustup
found is the right one, as is
rustfmt
, but somehow inside
src/python/pants/core/util_rules/system_binaries.py
it gets rewritten right before the unit test calls it, and then it fails because that path doesn’t exist:
Copy code
E       pants.core.util_rules.system_binaries.BinaryNotFoundError: Cannot find `rustfmt` on `['/home/vscode/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin']`. Please ensure that it is installed so that Pants can invoke Rust.
Note that
/home/vscode/.rustup
is empty except for
settings.toml
. This is running inside a VS Code dev container using
main
code + some work in progress; it is quite possibly a regression my end, and can keep looking.
A theory — in my installation,
$RUSTUP_HOME
is set. Is it possible that it’s getting re-set to
$HOME/.rustup
inside the unit test somehow? Below is my workaround in the dev container, and I could put this into the
postCreateCommand.sh
but this feels like a hack.
Copy code
vscode ➜ /workspaces/pants (fix-vscode-devcontainer-arm64) $ ls $RUSTUP_HOME/toolchains
1.85.0-aarch64-unknown-linux-gnu  stable-aarch64-unknown-linux-gnu
vscode ➜ /workspaces/pants (fix-vscode-devcontainer-arm64) $ ln -s $RUSTUP_HOME/toolchains ~/.rustup/toolchains
vscode ➜ /workspaces/pants (fix-vscode-devcontainer-arm64) $ ./pants test src/python/pants/backend/rust/lint/rustfmt/rules_integration_test.py
00:19:23.29 [INFO] Completed: Run Pytest - src/python/pants/backend/rust/lint/rustfmt/rules_integration_test.py:tests - succeeded.

✓ src/python/pants/backend/rust/lint/rustfmt/rules_integration_test.py:tests succeeded in 1.29s.
b
$RUSTUP_HOME
is set
Ah, this may be key. It's probably not being propagated through to the rustup call, and thus I suspect rustup defaults to ~/.rustup as you say.
In particular, https://github.com/pantsbuild/pants/blob/efab3e40cedce5c31dcab729fe3ffb8b4314be3e/src/python/pants/backend/rust/util_rules/toolchains.py#L87-L99 doesn't set or propagate any env vars (via
Process(..., env=...)
), and thus will be executing with an empty environment, I think
Sounds like a bug in that rustup backend
e
@broad-processor-92400 yes I think you’re right, but the layers of process execution code are proving a bit hard for me to unpick.
RustToolchainProcess
is a dataclass that gets run this way, using a generic function with no Rust-specific logic. I see other parts of code that forward environment and use
Process
but this one does not. Is there some implicit behavior here to some lower-level function turns into a
Process
call?
Copy code
result = await execute_process_or_raise(
        **implicitly(
            RustToolchainProcess(
                binary="rustfmt",
                args=request.snapshot.files,
                input_digest=request.snapshot.digest,
                output_files=request.snapshot.files,
                description=f"Run rustfmt on {pluralize(len(request.files), 'file')}.",
                level=LogLevel.DEBUG,
            )
        )
    )
I found a comment that hints that this is the case, in `pants.engine.process`:
Copy code
# result = await execute_process_or_raise(
#         **implicitly(
#             Process(...) # Or something that some other rule can convert to a Process.
#         )
#     )
@broad-processor-92400 I found and fixed the problem: https://github.com/pantsbuild/pants/pull/22094/commits/327ac814cdb2faf6a38622378cc6ffef491ec6b6. One more failing test left to go and we’ll be in a place where you can open dev container in VS Code with no errors and run all tests.
b
Ah cool, nice fix. Thanks for debugging these issues!
e
The very last one is
cgo_test.py
under the Go backend. It just silently dies on my ARM64 dev container:
Copy code
src/python/pants/backend/go/util_rules/cgo_test.py::test_cgo_with_embedded_static_library
Tonight and this weekend I’ll try and figure out what’s happening.