summaryrefslogtreecommitdiff
path: root/docs/ext/docstrings.py
blob: cd019eed1ac39478d452a117c5c34750982837ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import itertools
import os

import jinja2
import six
import sphinx
import sphinx.ext.napoleon as napoleon
from sphinx.ext.napoleon.docstring import GoogleDocstring


def classref(value, short=True):
    tilde = '~' if short else ''
    return ':class:`%sgitlab.objects.%s`' % (tilde, value.__name__)


def setup(app):
    app.connect('autodoc-process-docstring', _process_docstring)
    app.connect('autodoc-skip-member', napoleon._skip_member)

    conf = napoleon.Config._config_values

    for name, (default, rebuild) in six.iteritems(conf):
        app.add_config_value(name, default, rebuild)
    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}


def _process_docstring(app, what, name, obj, options, lines):
    result_lines = lines
    docstring = GitlabDocstring(result_lines, app.config, app, what, name, obj,
                                options)
    result_lines = docstring.lines()
    lines[:] = result_lines[:]


class GitlabDocstring(GoogleDocstring):
    _j2_env = None

    def _build_j2_env(self):
        if self._j2_env is None:
            self._j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(
                os.path.dirname(__file__)), trim_blocks=False)
            self._j2_env.filters['classref'] = classref

        return self._j2_env

    def _build_manager_doc(self):
        env = self._build_j2_env()
        template = env.get_template('manager_tmpl.j2')
        output = template.render(cls=self._obj.obj_cls)

        return output.split('\n')

    def _build_object_doc(self):
        env = self._build_j2_env()
        template = env.get_template('object_tmpl.j2')
        output = template.render(obj=self._obj)

        return output.split('\n')

    def __init__(self, *args, **kwargs):
        super(GitlabDocstring, self).__init__(*args, **kwargs)

        if hasattr(self._obj, 'obj_cls') and self._obj.obj_cls is not None:
            self._parsed_lines = self._build_manager_doc()
        elif hasattr(self._obj, 'canUpdate') and self._obj.canUpdate:
            self._parsed_lines = self._build_object_doc()