fix: make sphinxdocs support directory inputs (#2375)
The logic to relocate files assumed that all the inputs were plain file
artifacts. When
a directory artifact was used, then `ctx.actions.symlink()` would fail
because it requires
the output artifact and input target artifact to be the same type of
file (plain file or
directory).
To fix, use `File.is_directory` to detect if the input is a directory or
file, then call
`declare_file()` or `declare_directory()` as appropriate. The later
`symlink()` call is
then happy the two args match.
Fixes https://github.com/bazelbuild/rules_python/issues/2374
diff --git a/sphinxdocs/private/sphinx.bzl b/sphinxdocs/private/sphinx.bzl
index 2ee6cfc..678d01b 100644
--- a/sphinxdocs/private/sphinx.bzl
+++ b/sphinxdocs/private/sphinx.bzl
@@ -325,7 +325,12 @@
def _relocate(source_file, dest_path = None):
if not dest_path:
dest_path = source_file.short_path.removeprefix(ctx.attr.strip_prefix)
- dest_file = ctx.actions.declare_file(paths.join(source_prefix, dest_path))
+
+ dest_path = paths.join(source_prefix, dest_path)
+ if source_file.is_directory:
+ dest_file = ctx.actions.declare_directory(dest_path)
+ else:
+ dest_file = ctx.actions.declare_file(dest_path)
ctx.actions.symlink(
output = dest_file,
target_file = source_file,
diff --git a/sphinxdocs/tests/sphinx_docs/BUILD.bazel b/sphinxdocs/tests/sphinx_docs/BUILD.bazel
new file mode 100644
index 0000000..1a05db0
--- /dev/null
+++ b/sphinxdocs/tests/sphinx_docs/BUILD.bazel
@@ -0,0 +1,45 @@
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable=bzl-visibility
+load("//sphinxdocs:sphinx.bzl", "sphinx_build_binary", "sphinx_docs")
+load(":defs.bzl", "gen_directory")
+
+# We only build for Linux and Mac because:
+# 1. The actual doc process only runs on Linux
+# 2. Mac is a common development platform, and is close enough to Linux
+# it's feasible to make work.
+# Making CI happy under Windows is too much of a headache, though, so we don't
+# bother with that.
+_TARGET_COMPATIBLE_WITH = select({
+ "@platforms//os:linux": [],
+ "@platforms//os:macos": [],
+ "//conditions:default": ["@platforms//:incompatible"],
+}) if IS_BAZEL_7_OR_HIGHER else ["@platforms//:incompatible"]
+
+sphinx_docs(
+ name = "docs",
+ srcs = glob(["*.md"]) + [
+ ":generated_directory",
+ ],
+ config = "conf.py",
+ formats = ["html"],
+ sphinx = ":sphinx-build",
+ target_compatible_with = _TARGET_COMPATIBLE_WITH,
+)
+
+gen_directory(
+ name = "generated_directory",
+)
+
+sphinx_build_binary(
+ name = "sphinx-build",
+ tags = ["manual"], # Only needed as part of sphinx doc building
+ deps = [
+ "@dev_pip//myst_parser",
+ "@dev_pip//sphinx",
+ ],
+)
+
+build_test(
+ name = "build_tests",
+ targets = [":docs"],
+)
diff --git a/sphinxdocs/tests/sphinx_docs/conf.py b/sphinxdocs/tests/sphinx_docs/conf.py
new file mode 100644
index 0000000..d96fa36
--- /dev/null
+++ b/sphinxdocs/tests/sphinx_docs/conf.py
@@ -0,0 +1,15 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# For the full list of built-in configuration values, see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Project info
+
+project = "Sphinx Docs Test"
+
+extensions = [
+ "myst_parser",
+]
+myst_enable_extensions = [
+ "colon_fence",
+]
diff --git a/sphinxdocs/tests/sphinx_docs/defs.bzl b/sphinxdocs/tests/sphinx_docs/defs.bzl
new file mode 100644
index 0000000..2e47ecc
--- /dev/null
+++ b/sphinxdocs/tests/sphinx_docs/defs.bzl
@@ -0,0 +1,19 @@
+"""Supporting code for tests."""
+
+def _gen_directory_impl(ctx):
+ out = ctx.actions.declare_directory(ctx.label.name)
+
+ ctx.actions.run_shell(
+ outputs = [out],
+ command = """
+echo "# Hello" > {outdir}/index.md
+""".format(
+ outdir = out.path,
+ ),
+ )
+
+ return [DefaultInfo(files = depset([out]))]
+
+gen_directory = rule(
+ implementation = _gen_directory_impl,
+)
diff --git a/sphinxdocs/tests/sphinx_docs/index.md b/sphinxdocs/tests/sphinx_docs/index.md
new file mode 100644
index 0000000..cdce641
--- /dev/null
+++ b/sphinxdocs/tests/sphinx_docs/index.md
@@ -0,0 +1,8 @@
+# Sphinx docs test
+
+:::{toctree}
+:glob:
+
+**
+genindex
+:::