Skip to content

Commit 4eb3e25

Browse files
committed
Add plugin
This is mostly based on the extension submitted as a pull request for Sphinx [1]. [1] sphinx-doc/sphinx#4101 Signed-off-by: Stephen Finucane <[email protected]>
1 parent a8e1bde commit 4eb3e25

File tree

8 files changed

+131
-2
lines changed

8 files changed

+131
-2
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pbr
2+
Sphinx>=1.6.0

sphinxcontrib/apidoc/__init__.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@
1010

1111
import pbr.version
1212

13+
from sphinxcontrib.apidoc import ext
1314

14-
__version__ = pbr.version.VersionInfo(
15-
'apidoc').version_string()
15+
__version__ = pbr.version.VersionInfo('apidoc').version_string()
16+
17+
if False:
18+
# For type annotation
19+
from typing import Any, Dict # noqa
20+
from sphinx.application import Sphinx # noqa
21+
22+
23+
def setup(app):
24+
# type: (Sphinx) -> Dict[unicode, Any]
25+
app.setup_extension('sphinx.ext.autodoc') # We need autodoc to function
26+
27+
app.connect('builder-inited', ext.builder_inited)
28+
app.add_config_value('apidoc_module_dir', None, 'env', [str])
29+
app.add_config_value('apidoc_output_dir', 'api', 'env', [str])
30+
app.add_config_value('apidoc_excluded_modules', [], 'env', [[str]])
31+
32+
return {'version': __version__, 'parallel_read_safe': True}

sphinxcontrib/apidoc/ext.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
sphinxcontrib.apidoc.ext
3+
~~~~~~~~~~~~~~~~~~~~~~~~
4+
5+
A Sphinx extension for running 'sphinx-apidoc' on each build.
6+
7+
:copyright: Copyright 2018 by Stephen Finucane <[email protected]>
8+
:license: BSD, see LICENSE for details.
9+
"""
10+
11+
from os import path
12+
13+
from sphinx.util import logging
14+
15+
try:
16+
from sphinx.ext import apidoc # Sphinx >= 1.7
17+
except ImportError:
18+
from sphinx import apidoc # Sphinx < 1.7
19+
20+
if False:
21+
# For type annotation
22+
from sphinx.application import Sphinx # noqa
23+
24+
logger = logging.getLogger(__name__)
25+
26+
27+
def builder_inited(app):
28+
# type: (Sphinx) -> None
29+
module_dir = app.config.apidoc_module_dir
30+
output_dir = path.join(app.srcdir, app.config.apidoc_output_dir)
31+
excludes = app.config.apidoc_excluded_modules
32+
33+
if not module_dir:
34+
logger.warning("No 'apidoc_module_dir' specified; skipping API doc "
35+
"generation")
36+
return
37+
38+
# if the path is relative, make it relative to the 'conf.py' directory
39+
if not path.isabs(module_dir):
40+
module_dir = path.abspath(path.join(app.srcdir, module_dir))
41+
42+
excludes = [path.abspath(path.join(module_dir, exc)) for exc in excludes]
43+
44+
# refactor this module so that we can call 'recurse_tree' like a sane
45+
# person - at present there is way too much passing around of the
46+
# 'optparse.Value' instance returned by 'optparse.parse_args'
47+
cmd = ['--force', '-o', output_dir, module_dir]
48+
if excludes:
49+
cmd += excludes
50+
51+
apidoc.main(cmd)

sphinxcontrib/apidoc/tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,16 @@
66
:license: BSD, see LICENSE for details.
77
"""
88

9+
import os
10+
11+
import pytest
12+
from sphinx.testing.path import path
13+
914
pytest_plugins = 'sphinx.testing.fixtures'
15+
16+
collect_ignore = ['roots']
17+
18+
19+
@pytest.fixture(scope='session')
20+
def rootdir():
21+
return path(os.path.dirname(__file__) or '.').abspath() / 'roots'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from os import * # noqa
2+
3+
4+
class Foo:
5+
def __init__(self):
6+
pass
7+
8+
def bar(self):
9+
pass
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import os
4+
import sys
5+
6+
sys.path.insert(0, os.path.abspath('./'))
7+
8+
extensions = ['sphinxcontrib.apidoc']
9+
master_doc = 'index'
10+
11+
apidoc_module_dir = '.'
12+
apidoc_excluded_modules = ['conf.py']
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apidoc
2+
======
3+
4+
.. toctree::
5+
6+
api/modules
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
test_apidoc
4+
~~~~~~~~~~~
5+
6+
Test the sphinxcontrib.apidoc module.
7+
8+
:copyright: Copyright 2018 by Stephen Finucane <[email protected]>.
9+
:license: BSD, see LICENSE for details.
10+
"""
11+
12+
import pytest
13+
14+
15+
@pytest.mark.sphinx('html', testroot='apidoc')
16+
def test_apidoc_extension(app, status, warning):
17+
app.builder.build_all()
18+
assert (app.outdir / 'api').isdir()
19+
assert (app.outdir / 'api' / 'modules.html').exists()
20+
assert (app.outdir / 'api' / 'apidoc_dummy_module.html').exists()
21+
assert not (app.outdir / 'api' / 'conf.html').exists()

0 commit comments

Comments
 (0)