FR: allow ctx.which to watch for PATH/ program changes
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the feature request:
In short: Add a `watch=True` arg to `ctx.which()`. This makes it parse `PATH` and watch for `$program` to exist/change in a directory _before_ where it first found `$program`. Unless that condition is met, the which() result is not invalidated. The pesudo-code for this would be something like:
Background:
The `ctx.which()` function is used to find a program by looking for it in the locations specified by the `PATH` environment variable. Thus, changing PATH _could_ change the result of which(), depending on how path changed and where a program was found.
Today, changes to the PATH environment variable won't invalidate any lookups using which(). This makes some sense because it's pretty context specific as to whether it matters or not. However, this is problematic for cases which _do_ care if the result would have changed. My go-to example is when configuring a language toolchain using the local system (non-ideal, but IMHO, quite reasonable when users intentionally want to use a custom toolchain for whatever reason).
While a repository rule can call `getenv("PATH")` to watch the path environment variable, this ends up being too noisy -- tools like git may modify PATH when running hooks (https://github.com/bazelbuild/rules_python/issues/2551#issue-2775670673) in such a way that _wouldn't_ invalidate most which() calls.
### Which category does this issue belong to?
External Dependency
### What underlying problem are you trying to solve with this feature?
Making a repository rule correctly watch for changes to its inputs while not invalidating when unnecessary.
### Which operating system are you running Bazel on?
Linux
### What is the output of `bazel info release`?
8.0.0
### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.
_No response_
### What's the output of `git remote get-url origin; git rev-parse HEAD` ?
_No response_
### Have you found anything relevant by searching the web?
Searched all, didn't find a mention of this.
### Any other information, logs, or outputs that you want to share?
This feature request originates from discussion in https://github.com/bazelbuild/rules_python/issues/2551
Contributor guide
Research direction
Start by locating the ctx.which() entry point and its existing tests, then trace how PATH lookups are cached and invalidated. Define tests for watch=True when a program appears or changes in an earlier PATH directory, while unchanged results remain valid; done means the behavior is covered without altering default lookups.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, linux, shell
- Domain
- build-system, devtools
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100