docs: initial doc generation using Sphinx (#1489)
This lays the groundwork for using Sphinx to generate user-facing
documentation and
having it published on readthedocs. It integrates with Bazel Stardoc to
generate
MyST-flavored Markdown that Sphinx can process.
There are 4 basic pieces that are glued together:
1. `sphinx_docs`: This rule invokes Sphinx to generate e.g. html, latex,
etc
2. `sphinx_stardoc`: This rule invokes Stardoc to generate MyST-flavored
Markdown
that Sphinx can process
3. `sphinx_build_binary`: This rule defines the Sphinx executable with
any necessary
dependencies (e.g. Sphinx extensions, like MyST) to process the docs in
(1)
4. `readthedocs_install`: This rule does the necessary steps to build
the docs and
put them into the location the readthedocs build process expects. This
is basically
just `cp -r`, but its cleaner to hide it behind a `bazel run` command
than have
to put various shell in the readthedocs yaml config.
* Bump Bazel 6 requirement: 6.0.0 -> 6.20. This is necessary to support
bzlmod and Stardoc.
Work towards #1332, #1484
diff --git a/sphinxdocs/readthedocs_install.py b/sphinxdocs/readthedocs_install.py
new file mode 100644
index 0000000..9b1f2a8
--- /dev/null
+++ b/sphinxdocs/readthedocs_install.py
@@ -0,0 +1,27 @@
+import os
+import pathlib
+import shutil
+import sys
+
+from python import runfiles
+
+
+def main(args):
+ if not args:
+ raise ValueError("Empty args: expected paths to copy")
+
+ if not (install_to := os.environ.get("READTHEDOCS_OUTPUT")):
+ raise ValueError("READTHEDOCS_OUTPUT environment variable not set")
+
+ install_to = pathlib.Path(install_to)
+
+ rf = runfiles.Create()
+ for doc_dir_runfiles_path in args:
+ doc_dir_path = pathlib.Path(rf.Rlocation(doc_dir_runfiles_path))
+ dest = install_to / doc_dir_path.name
+ print(f"Copying {doc_dir_path} to {dest}")
+ shutil.copytree(src=doc_dir_path, dst=dest, dirs_exist_ok=True)
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))