sphinx-contrib / sphinxcontrib-versioning

Sphinx extension that allows building versioned docs for self-hosting.
https://sphinxcontrib-versioning.readthedocs.io/en/latest/
MIT License
125 stars 81 forks source link

Using the same environment for every build seems to break autodoc? #38

Open njsmith opened 7 years ago

njsmith commented 7 years ago

I was looking at migrating from RTD to sphinxcontrib-versioning, but my project makes extensive use of autodoc, and I was running into problems due to this. RTD always sets up a fresh virtualenv, installs the project into it, and then uses that virtualenv to do the build, so the version of the project that autodoc sees always matches the version of the docs being built.

It looks like sphinxcontrib-versioning doesn't have any way to do this currently – it always builds all the docs in the same environment. Is that correct? Would it be possible to do a fresh-virtualenv-per-build approach instead?

Robpol86 commented 7 years ago

That's correct. I've realized the shortcoming after I finalized the design of the project so it was too late for me to implement that method.

I believe the fresh-venv-per-build approach would require significant code change. However I'd like to accomplish that one day.

futursolo commented 7 years ago

I also have this problem when I was working on a project where setup.py and sphinx-build (docs/conf.py) are responsible for version number generation.

Can we add a --pre-command option to sphinxcontrib-versioning to solve this problem?

njsmith commented 7 years ago

From a quick look, I'm guessing the challenge is that currently sphinxcontrib-versioning doesn't run the sphinx-build command directly as a subprocess, but rather imports Sphinx, modifies some stuff to apply it's magic, and then calls the build code. To do this with separate virtualenvs per build would require that sphinxcontrib-versioning have some way to inject its code into those virtualenvs. Which is a bit tricky.

It looks like rtd solves this by having a rtd Sphinx extension that they pip install into each virtualenv. I guess the challenge then is that you have two different projects (the builder and the extension) that you have to distribute separately and keep in sync. Alternatively I think it might be possible to factor out the necessary code into a separate file inside sphinxcontrib-versioning, and then do some PYTHONPATH manipulation or something to make just that file visible to the individual virtualenvs.

njsmith commented 7 years ago

Actually, instead of messing with PYTHONPATH, what I'd probably do is factor the sphinx hackery into its own file, and write that file so that if you do python mybuild.py that directly runs sphinx-build with hacks applied. Then to run a build I'd set up a virtualenv, and do venv/bin/python path/to/mybuild.py. That gives us a simple way to get code to execute inside the virtualenv, and it also lets us dodge the problem of how to convince sphinx-build to load our code. (RTD patches the conf.py file to add their extension, which I guess works but isn't the most robust or simple thing.)

dmtucker commented 4 years ago

I stumbled across this issue awhile back and end up creating verdoc to build Git references that may have completely different docs-building recipes (Sphinx or not, which is why it's its own project instead of a PR here). That allows docs deps to change over time (even backwards-incompatibly).

Maybe that could help here? ATM, only Tox is supported for building (e.g. tox -e docs -- $dest), but it was made to accommodate other builders.

yukw777 commented 4 years ago

I'm guessing this won't be fixed any time soon? any workarounds?

yukw777 commented 4 years ago

I ended up using this: https://github.com/readthedocs/sphinx-autoapi. It doesn't have this problem b/c it doesn't actually import and execute the code.

KinWaiCheuk commented 3 years ago

But the autoapi does not generate one page per function/class, instead it is one page per module. Am I missing anything here? If it is possible, I would still like to stick with autodoc and sphinx-versioning. So there is still no fix and workaround until now?

KinWaiCheuk commented 3 years ago

I managed to find a hack to do it. Say you have two release v1.0 and v2.0 on GitHub. Then you do a git checkout v1.0, and build the html with sphinx-versioning build <your source location> output1. Similarly, do git checkout v2.0, and build the html with sphinx-versioning build <your source location> output2.

Then you will have two output folders like this:

output1 ├── index.html ├── master ├── v1.0 └── v2.0

output2 ├── index.html ├── master ├── v1.0 └── v2.0

I am omitting other unimportant files here.

Now, we just need to delete that v1.0 folder under output2 and move the v1.0 folder from output1 to output2. Then you will have a perfectly working autodoc generated documentation together with a working versioning.

Of course, the drawback for this is that the build time would increase exponentially as you have more versions and you need to manually build so many versions. But still works as a quick fix. Maybe we can write a script to do this for us so that we do not need to build them manually?