From c2eb11218496d04c358027855b12357a82b9f424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Fran=C3=A7oise?= Date: Fri, 11 Dec 2015 14:51:31 +0100 Subject: [PATCH] Include terminology definition from docstring As of now, the glossary defined in our documentation reflects the current state of the codebase. In order to avoid any discrepancy between the codebase and each definition, the objective here is to gather both in a single place and link it into the rst documentation via a custom directive. Also re-aligned the requirements with liberty for doc. DocImpact Change-Id: I9ca50f8d3c32b4690ee240e13dec0cb7eeedcc2c --- doc/source/conf.py | 3 +- setup.cfg | 1 + test-requirements.txt | 8 ++-- watcher/doc.py | 86 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 watcher/doc.py diff --git a/doc/source/conf.py b/doc/source/conf.py index ba380eb8c..acf2da8f7 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -28,7 +28,8 @@ extensions = [ 'sphinxcontrib.httpdomain', 'sphinxcontrib.pecanwsme.rest', 'wsmeext.sphinxext', - 'oslosphinx' + 'oslosphinx', + 'watcher.doc', ] wsme_protocols = ['restjson'] diff --git a/setup.cfg b/setup.cfg index 2e658cfd7..d39ce79d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -48,6 +48,7 @@ watcher_strategies = [build_sphinx] source-dir = doc/source build-dir = doc/build +fresh_env = 1 all_files = 1 [upload_sphinx] diff --git a/test-requirements.txt b/test-requirements.txt index 0075f0492..4faca21a0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,19 +2,19 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking<0.11,>=0.10 coverage>=3.6 discover -python-subunit>=0.0.18 +hacking>=0.10.2,<0.11 +mock>=1.2 oslotest>=1.10.0 # Apache-2.0 +python-subunit>=0.0.18 testrepository>=0.0.18 testscenarios>=0.4 testtools>=1.4.0 -mock>=1.2 # Doc requirements +oslosphinx>=2.5.0 # Apache-2.0 sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 -oslosphinx>=2.5.0 # Apache-2.0 sphinxcontrib-pecanwsme>=0.8 # For PyPI distribution diff --git a/watcher/doc.py b/watcher/doc.py new file mode 100644 index 000000000..0d1a1c5a8 --- /dev/null +++ b/watcher/doc.py @@ -0,0 +1,86 @@ +# -*- encoding: utf-8 -*- +# Copyright (c) 2015 b<>com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import unicode_literals + +import importlib + +from docutils import nodes +from docutils.parsers import rst +from docutils import statemachine as sm + +from watcher.version import version_info + +import textwrap + + +class WatcherTerm(rst.Directive): + """Directive to import an RST formatted docstring into the Watcher glossary + + How to use it + ------------- + + # inside your .py file + class DocumentedObject(object): + '''My *.rst* docstring''' + + + # Inside your .rst file + .. watcher-term:: import.path.to.your.DocumentedObject + + This directive will then import the docstring and then interprete it. + """ + + # You need to put an import path as an argument for this directive to work + required_arguments = 1 + + def add_textblock(self, textblock, *lineno): + for line in textblock.splitlines(): + self.add_line(line) + + def add_line(self, line, *lineno): + """Append one line of generated reST to the output.""" + self.result.append(line, rst.directives.unchanged, *lineno) + + def run(self): + self.result = sm.ViewList() + + cls_path = self.arguments[0] + + try: + module_name, obj_name = cls_path.rsplit(".", 1) + module = importlib.import_module(module_name) + cls = getattr(module, obj_name) + except Exception as exc: + raise self.error(exc) + + self.add_class_docstring(cls) + + node = nodes.paragraph() + node.document = self.state.document + self.state.nested_parse(self.result, 0, node) + return node.children + + def add_class_docstring(self, cls): + # Added 4 spaces to align the first line with the rest of the text + # to be able to dedent it correctly + cls_docstring = textwrap.dedent("%s%s" % (" " * 4, cls.__doc__)) + self.add_textblock(cls_docstring) + + +def setup(app): + app.add_directive('watcher-term', WatcherTerm) + return {'version': version_info.version_string()}