Skip to content

Commit

Permalink
fix: _which_unchecked: don't watch PATH if binary exists. (#2552)
Browse files Browse the repository at this point in the history
Currently, the _which_unchecked helper unconditionally watches the
`PATH` env var via repository_ctx.getenv. getenv is documented
https://bazel.build/rules/lib/builtins/repository_ctx#getenv:

> any change to the value of the variable named by name will cause this
repository to be re-fetched.

Thus, any change to `PATH` will cause any repository rule that
transitively calls _which_unchecked to be re-fetched. This includes
python_repository and whl_library.

There are reasonable development workflows that modify `PATH`. In
particular, when git runs a hook, it adds the value of `GIT_EXEC_PATH`
to `PATH` before invoking the hook. If the hook invokes bazel (for
example, a pre-commit hook running `bazel build ...`), it will cause the
Python repository rules to be re-fetched.

This commit lowers the repository_ctx.getenv("PATH") call to its only
use site in _which_unchecked, which happens to be a failure case (when
the binary is not found). This allows the success case to not watch
`PATH`, and therefore not to re-fetch the repository rule when it
changes.

Fixes #2551.
  • Loading branch information
Ubehebe authored Jan 9, 2025
1 parent 4e95a60 commit 89d850a
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ Unreleased changes template.
change. Fixes [#2468](https://github.com/bazelbuild/rules_python/issues/2468).
+ (gazelle) Gazelle no longer ignores `setup.py` files by default. To restore
this behavior, apply the `# gazelle:python_ignore_files setup.py` directive.
* Don't re-fetch whl_library, python_repository, etc. repository rules
whenever `PATH` changes. Fixes
[#2551](https://github.com/bazelbuild/rules_python/issues/2551).

[pep-695]: https://peps.python.org/pep-0695/

Expand Down
4 changes: 2 additions & 2 deletions python/private/repo_utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def _which_checked(mrctx, binary_name):
def _which_unchecked(mrctx, binary_name):
"""Tests to see if a binary exists.
This is also watch the `PATH` environment variable.
Watches the `PATH` environment variable if the binary doesn't exist.
Args:
binary_name: name of the binary to find.
Expand All @@ -268,12 +268,12 @@ def _which_unchecked(mrctx, binary_name):
* `describe_failure`: `Callable | None`; takes no args. If the
binary couldn't be found, provides a detailed error description.
"""
path = _getenv(mrctx, "PATH", "")
binary = mrctx.which(binary_name)
if binary:
_watch(mrctx, binary)
describe_failure = None
else:
path = _getenv(mrctx, "PATH", "")
describe_failure = lambda: _which_describe_failure(binary_name, path)

return struct(
Expand Down

0 comments on commit 89d850a

Please sign in to comment.