fix(sphinx): prefix sphinx binary paths with ./ in run script (#4201) (#4261) When the sphinx binary target is in the root package, its short_path contains no directory separator. Executing it via `env` in the `.run` script searches `$PATH` instead of the current directory and fails with `No such file or directory`. Prefix `%SPHINX_RUNFILES_PATH%` and `%SPHINX_EXEC_PATH%` with `./` in `sphinx_run_template.sh` so `env` resolves the binary relative to the working directory. Fixes #4201
diff --git a/news/4201.fixed.md b/news/4201.fixed.md new file mode 100644 index 0000000..f686516 --- /dev/null +++ b/news/4201.fixed.md
@@ -0,0 +1,3 @@ +(sphinxdocs) Fixed `sphinx_docs` `.run` targets failing to locate the `sphinx` +binary when defined in the root package +([#4201](https://github.com/bazel-contrib/rules_python/issues/4201)).
diff --git a/sphinxdocs/sphinxdocs/private/sphinx_run_template.sh b/sphinxdocs/sphinxdocs/private/sphinx_run_template.sh index aa83757..b2371f6 100644 --- a/sphinxdocs/sphinxdocs/private/sphinx_run_template.sh +++ b/sphinxdocs/sphinxdocs/private/sphinx_run_template.sh
@@ -18,7 +18,7 @@ exit 1 fi -for path in "%SPHINX_RUNFILES_PATH%" "%SPHINX_EXEC_PATH%"; do +for path in "./%SPHINX_RUNFILES_PATH%" "./%SPHINX_EXEC_PATH%"; do if [[ -e $path ]]; then sphinx=$path break
diff --git a/sphinxdocs/tests/sphinx_docs/BUILD.bazel b/sphinxdocs/tests/sphinx_docs/BUILD.bazel index 99b84ce..87e014f 100644 --- a/sphinxdocs/tests/sphinx_docs/BUILD.bazel +++ b/sphinxdocs/tests/sphinx_docs/BUILD.bazel
@@ -89,6 +89,9 @@ py_test( name = "sphinx_docs_output_test", srcs = ["sphinx_docs_output_test.py"], - data = [":docs"], + data = [ + ":docs", + ":docs.run", + ], deps = ["@pypi//absl_py"], )
diff --git a/sphinxdocs/tests/sphinx_docs/sphinx_docs_output_test.py b/sphinxdocs/tests/sphinx_docs/sphinx_docs_output_test.py index f4e9104..a4a7067 100644 --- a/sphinxdocs/tests/sphinx_docs/sphinx_docs_output_test.py +++ b/sphinxdocs/tests/sphinx_docs/sphinx_docs_output_test.py
@@ -42,6 +42,18 @@ ) self.assertTrue(os.path.exists(str(page_path)), f"Not found at {page_path}") + def test_sphinx_run_script_uses_relative_sphinx_paths(self): + # Verify the generated .run script prefixes the sphinx binary paths with "./" + # so `env` resolves the binary relative to the working directory instead of + # searching $PATH when the target is in the root package (where short_path + # has no slash). See https://github.com/bazel-contrib/rules_python/issues/4201. + docs_run_path = importlib.resources.files(sphinx_docs).joinpath("docs.run") + script_content = docs_run_path.read_text() + self.assertIn( + 'for path in "./tests/sphinx_docs/sphinx-build" "./bazel-out/', + script_content, + ) + if __name__ == "__main__": absltest.main()