diff options
author | Gauvain Pocentek <gauvain.pocentek@objectif-libre.com> | 2016-01-31 22:02:32 +0100 |
---|---|---|
committer | Gauvain Pocentek <gauvain.pocentek@objectif-libre.com> | 2016-01-31 22:02:32 +0100 |
commit | a2eca72246ab40a0d96f6389c99e3a0b54e9342e (patch) | |
tree | bbce2cd1784893f7474e79c179bbe78671ac152b | |
parent | 770dd4b3fee1fe9f4e40a144777afb6030992149 (diff) | |
download | gitlab-a2eca72246ab40a0d96f6389c99e3a0b54e9342e.tar.gz |
Automatic doc generation for BaseManager classes
Provide a sphinx extension that parses the required/optioanl attributes
and add infoo to the class docstring.
-rw-r--r-- | docs/conf.py | 8 | ||||
-rw-r--r-- | docs/ext/__init__.py | 0 | ||||
-rw-r--r-- | docs/ext/docstrings.py | 75 | ||||
-rw-r--r-- | docs/ext/template.j2 | 21 | ||||
-rw-r--r-- | test-requirements.txt | 4 |
5 files changed, 100 insertions, 8 deletions
diff --git a/docs/conf.py b/docs/conf.py index bbf3c67..c5c1fad 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,15 +21,11 @@ import sys import sphinx sys.path.append('../') +sys.path.append(os.path.dirname(__file__)) import gitlab on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if sphinx.version_info < (1,3,): - napoleon_version = "sphinxcontrib.napoleon" -else: - napoleon_version = "sphinx.ext.napoleon" - # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -44,7 +40,7 @@ sys.path.insert(0, os.path.abspath('..')) # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', napoleon_version, + 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'ext.docstrings' ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/ext/__init__.py b/docs/ext/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/ext/__init__.py diff --git a/docs/ext/docstrings.py b/docs/ext/docstrings.py new file mode 100644 index 0000000..4724fc5 --- /dev/null +++ b/docs/ext/docstrings.py @@ -0,0 +1,75 @@ +import itertools +import os + +import jinja2 +import six +import sphinx +import sphinx.ext.napoleon as napoleon +from sphinx.ext.napoleon.docstring import GoogleDocstring + + +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): + def _build_doc(self): + cls = self._obj.obj_cls + md_create_list = list(itertools.chain(cls.requiredUrlAttrs, + cls.requiredCreateAttrs)) + opt_create_list = cls.optionalCreateAttrs + + md_create_keys = opt_create_keys = "None" + if md_create_list: + md_create_keys = "%s" % ", ".join(['``%s``' % i for i in + md_create_list]) + if opt_create_list: + opt_create_keys = "%s" % ", ".join(['``%s``' % i for i in + opt_create_list]) + + md_update_list = list(itertools.chain(cls.requiredUrlAttrs, + cls.requiredUpdateAttrs)) + opt_update_list = cls.optionalUpdateAttrs + + md_update_keys = opt_update_keys = "None" + if md_update_list: + md_update_keys = "%s" % ", ".join(['``%s``' % i for i in + md_update_list]) + if opt_update_list: + opt_update_keys = "%s" % ", ".join(['``%s``' % i for i in + opt_update_list]) + + tmpl_file = os.path.join(os.path.dirname(__file__), 'template.j2') + with open(tmpl_file) as fd: + template = jinja2.Template(fd.read(), trim_blocks=False) + output = template.render(filename=tmpl_file, + cls=cls, + md_create_keys=md_create_keys, + opt_create_keys=opt_create_keys, + md_update_keys=md_update_keys, + opt_update_keys=opt_update_keys) + + return output.split('\n') + + def __init__(self, *args, **kwargs): + super(GitlabDocstring, self).__init__(*args, **kwargs) + + if not hasattr(self._obj, 'obj_cls') or self._obj.obj_cls is None: + return + + self._parsed_lines = self._build_doc() diff --git a/docs/ext/template.j2 b/docs/ext/template.j2 new file mode 100644 index 0000000..980a7ed --- /dev/null +++ b/docs/ext/template.j2 @@ -0,0 +1,21 @@ +Manager for :class:`gitlab.objects.{{ cls.__name__ }}` objects. + +Available actions for this class: + +{% if cls.canList %}- Objects listing{%endif%} +{% if cls.canGet %}- Unique object retrieval{%endif%} +{% if cls.canCreate %}- Object creation{%endif%} +{% if cls.canUpdate %}- Object update{%endif%} +{% if cls.canDelete %}- Object deletion{%endif%} + +{% if cls.canCreate %} +Mandatory arguments for object creation: {{ md_create_keys }} + +Optional arguments for object creation: {{ opt_create_keys }} +{% endif %} + +{% if cls.canUpdate %} +Mandatory arguments for object update: {{ md_create_keys }} + +Optional arguments for object update: {{ opt_create_keys }} +{% endif %} diff --git a/test-requirements.txt b/test-requirements.txt index 87b1721..fead9f9 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,6 +2,6 @@ discover testrepository hacking>=0.9.2,<0.10 httmock +jinja2 mock -sphinx>=1.1.2,!=1.2.0,<1.3 -sphinxcontrib-napoleon +sphinx>=1.3 |