Hi, is there a recipe / best practice for generati...
# general
p
Hi, is there a recipe / best practice for generating Sphinx documentation including apidoc with pants? Outside of pants, I would have to create a venv with Sphinx and run
sphinx-build
and
sphinx-apidoc
within it. Can this be written as a pants target?
👀 1
c
Hi! Generating documentation is a feature that would be great to have in Pants. Currently however, there’s no builtin support for doc tools in Pants. It shouldn’t be too difficult to add a new plugin for sphinx support, once some familiarity with how the Pants plugin API works.
p
Ok, good to know. I have an idea of how it would look like from the user perspective but unfortunately I'm not knowledgable enough (yet) to implement a proof of concept. One pattern that I came across quite often is "have command X run in a predefined venv". If you have any idea how this would be possible, it would be very helpful.
c
There’s an
./pants export
goal that creates a venv with your deps in it, that might be useful.
👍 1
There’s quite a few threads in slack on that goal (as it was recently added to Pants, it is still evolving) for more details, use cases and examples.
p
I'll take a look into that, thanks!
c
You’re welcome 🙂
p
I found a crude workaround. It's not elegant, but it works. I wrote a python script that calls Sphinx directly, almost like a shell script would do. Using this, pants can build a venv for it to execute:
Copy code
# docs/build_doc.py

from pathlib import Path
import shutil

from sphinx.cmd.build import main as sphinx_build_main
from sphinx.ext.apidoc import main as sphinx_apidoc_main


def _stringify(iterable):
    return [str(item) for item in iterable]


def main():
    docs_dir = Path("docs")
    build_dir = docs_dir / "build"
    source_dir = docs_dir / "source"
    all_opts = ["-d", build_dir / "doctrees", source_dir]

    shutil.rmtree(build_dir, ignore_errors=True)
    shutil.rmtree(source_dir / "_apidoc", ignore_errors=True)

    sphinx_apidoc_main(_stringify(["-o", source_dir / "_apidoc", "."]))
    sphinx_apidoc_main(_stringify(["-o", source_dir / "_apidoc", "source/mypkg"]))
    sphinx_build_main(_stringify(["-b", "html", *all_opts, build_dir / "html"]))


if __name__ == '__main__':
    main()
Copy code
# docs/BUILD
pex_binary(
    name="build_doc",
    entry_point="build_doc.py",
    dependencies=["//:poetry"],  # Depend on all external dependencies
)

python_sources()
It needs to depend on everything because Sphinx actually imports the code to be documented. There is a solution with mocks, but didn't work for me, so I opted to have pants create a venv with all dependencies. With those files, the documentation can be built using
./pants run docs:build_doc
. Maybe it can be useful to other people until there is native support.
h
FYI this is something @hundreds-father-404 and @ancient-vegetable-10556 may be looking at soon, for the initial purpose of generating Pants's own docs at pantsbuild.org.
❤️ 1
a
Thank you so much @purple-umbrella-89891!
w
a recent thread on the topic: https://pantsbuild.slack.com/archives/C046T6T9U/p1649176870827779 … should have turned it into a ticket last time round.
h
https://pantsbuild.slack.com/archives/C046T6T9U/p1652485359479119 I want to have Sphinx for personal use, gonna see how far I can get on a weekend project
👍 2