Statistics
| Branch: | Tag: | Revision:

root / lib / build / sphinx_ext.py @ dac59ac5

History | View | Annotate | Download (4 kB)

1 5f43f393 Michael Hanselmann
#
2 5f43f393 Michael Hanselmann
#
3 5f43f393 Michael Hanselmann
4 5f43f393 Michael Hanselmann
# Copyright (C) 2011 Google Inc.
5 5f43f393 Michael Hanselmann
#
6 5f43f393 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 5f43f393 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 5f43f393 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 5f43f393 Michael Hanselmann
# (at your option) any later version.
10 5f43f393 Michael Hanselmann
#
11 5f43f393 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 5f43f393 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 5f43f393 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 5f43f393 Michael Hanselmann
# General Public License for more details.
15 5f43f393 Michael Hanselmann
#
16 5f43f393 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 5f43f393 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 5f43f393 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 5f43f393 Michael Hanselmann
# 02110-1301, USA.
20 5f43f393 Michael Hanselmann
21 5f43f393 Michael Hanselmann
22 5f43f393 Michael Hanselmann
"""Sphinx extension for building opcode documentation.
23 5f43f393 Michael Hanselmann

24 5f43f393 Michael Hanselmann
"""
25 5f43f393 Michael Hanselmann
26 5f43f393 Michael Hanselmann
import operator
27 5f43f393 Michael Hanselmann
from cStringIO import StringIO
28 5f43f393 Michael Hanselmann
29 dac59ac5 Michael Hanselmann
import docutils.statemachine
30 5f43f393 Michael Hanselmann
31 dac59ac5 Michael Hanselmann
import sphinx.errors
32 dac59ac5 Michael Hanselmann
import sphinx.util.compat
33 5f43f393 Michael Hanselmann
34 5f43f393 Michael Hanselmann
from ganeti import utils
35 5f43f393 Michael Hanselmann
from ganeti import opcodes
36 5f43f393 Michael Hanselmann
from ganeti import ht
37 5f43f393 Michael Hanselmann
38 5f43f393 Michael Hanselmann
39 5f43f393 Michael Hanselmann
COMMON_PARAM_NAMES = map(operator.itemgetter(0), opcodes.OpCode.OP_PARAMS)
40 5f43f393 Michael Hanselmann
41 5f43f393 Michael Hanselmann
42 dac59ac5 Michael Hanselmann
class OpcodeError(sphinx.errors.SphinxError):
43 5f43f393 Michael Hanselmann
  category = "Opcode error"
44 5f43f393 Michael Hanselmann
45 5f43f393 Michael Hanselmann
46 5f43f393 Michael Hanselmann
def _SplitOption(text):
47 5f43f393 Michael Hanselmann
  """Split simple option list.
48 5f43f393 Michael Hanselmann

49 5f43f393 Michael Hanselmann
  @type text: string
50 5f43f393 Michael Hanselmann
  @param text: Options, e.g. "foo, bar, baz"
51 5f43f393 Michael Hanselmann

52 5f43f393 Michael Hanselmann
  """
53 5f43f393 Michael Hanselmann
  return [i.strip(",").strip() for i in text.split()]
54 5f43f393 Michael Hanselmann
55 5f43f393 Michael Hanselmann
56 5f43f393 Michael Hanselmann
def _ParseAlias(text):
57 5f43f393 Michael Hanselmann
  """Parse simple assignment option.
58 5f43f393 Michael Hanselmann

59 5f43f393 Michael Hanselmann
  @type text: string
60 5f43f393 Michael Hanselmann
  @param text: Assignments, e.g. "foo=bar, hello=world"
61 5f43f393 Michael Hanselmann
  @rtype: dict
62 5f43f393 Michael Hanselmann

63 5f43f393 Michael Hanselmann
  """
64 5f43f393 Michael Hanselmann
  result = {}
65 5f43f393 Michael Hanselmann
66 5f43f393 Michael Hanselmann
  for part in _SplitOption(text):
67 5f43f393 Michael Hanselmann
    if "=" not in part:
68 5f43f393 Michael Hanselmann
      raise OpcodeError("Invalid option format, missing equal sign")
69 5f43f393 Michael Hanselmann
70 5f43f393 Michael Hanselmann
    (name, value) = part.split("=", 1)
71 5f43f393 Michael Hanselmann
72 5f43f393 Michael Hanselmann
    result[name.strip()] = value.strip()
73 5f43f393 Michael Hanselmann
74 5f43f393 Michael Hanselmann
  return result
75 5f43f393 Michael Hanselmann
76 5f43f393 Michael Hanselmann
77 5f43f393 Michael Hanselmann
def _BuildOpcodeParams(op_id, include, exclude, alias):
78 5f43f393 Michael Hanselmann
  """Build opcode parameter documentation.
79 5f43f393 Michael Hanselmann

80 5f43f393 Michael Hanselmann
  @type op_id: string
81 5f43f393 Michael Hanselmann
  @param op_id: Opcode ID
82 5f43f393 Michael Hanselmann

83 5f43f393 Michael Hanselmann
  """
84 5f43f393 Michael Hanselmann
  op_cls = opcodes.OP_MAPPING[op_id]
85 5f43f393 Michael Hanselmann
86 5f43f393 Michael Hanselmann
  params_with_alias = \
87 5f43f393 Michael Hanselmann
    utils.NiceSort([(alias.get(name, name), name, default, test, doc)
88 5f43f393 Michael Hanselmann
                    for (name, default, test, doc) in op_cls.GetAllParams()],
89 5f43f393 Michael Hanselmann
                   key=operator.itemgetter(0))
90 5f43f393 Michael Hanselmann
91 5f43f393 Michael Hanselmann
  for (rapi_name, name, default, test, doc) in params_with_alias:
92 5f43f393 Michael Hanselmann
    # Hide common parameters if not explicitely included
93 5f43f393 Michael Hanselmann
    if (name in COMMON_PARAM_NAMES and
94 5f43f393 Michael Hanselmann
        (not include or name not in include)):
95 5f43f393 Michael Hanselmann
      continue
96 5f43f393 Michael Hanselmann
    if exclude is not None and name in exclude:
97 5f43f393 Michael Hanselmann
      continue
98 5f43f393 Michael Hanselmann
    if include is not None and name not in include:
99 5f43f393 Michael Hanselmann
      continue
100 5f43f393 Michael Hanselmann
101 5f43f393 Michael Hanselmann
    has_default = default is not ht.NoDefault
102 5f43f393 Michael Hanselmann
    has_test = not (test is None or test is ht.NoType)
103 5f43f393 Michael Hanselmann
104 5f43f393 Michael Hanselmann
    buf = StringIO()
105 5f43f393 Michael Hanselmann
    buf.write("``%s``" % rapi_name)
106 5f43f393 Michael Hanselmann
    if has_default or has_test:
107 5f43f393 Michael Hanselmann
      buf.write(" (")
108 5f43f393 Michael Hanselmann
      if has_default:
109 5f43f393 Michael Hanselmann
        buf.write("defaults to ``%s``" % default)
110 5f43f393 Michael Hanselmann
        if has_test:
111 5f43f393 Michael Hanselmann
          buf.write(", ")
112 5f43f393 Michael Hanselmann
      if has_test:
113 5f43f393 Michael Hanselmann
        buf.write("must be ``%s``" % test)
114 5f43f393 Michael Hanselmann
      buf.write(")")
115 5f43f393 Michael Hanselmann
    yield buf.getvalue()
116 5f43f393 Michael Hanselmann
117 5f43f393 Michael Hanselmann
    # Add text
118 5f43f393 Michael Hanselmann
    for line in doc.splitlines():
119 5f43f393 Michael Hanselmann
      yield "  %s" % line
120 5f43f393 Michael Hanselmann
121 5f43f393 Michael Hanselmann
122 dac59ac5 Michael Hanselmann
class OpcodeParams(sphinx.util.compat.Directive):
123 5f43f393 Michael Hanselmann
  """Custom directive for opcode parameters.
124 5f43f393 Michael Hanselmann

125 5f43f393 Michael Hanselmann
  See also <http://docutils.sourceforge.net/docs/howto/rst-directives.html>.
126 5f43f393 Michael Hanselmann

127 5f43f393 Michael Hanselmann
  """
128 5f43f393 Michael Hanselmann
  has_content = False
129 5f43f393 Michael Hanselmann
  required_arguments = 1
130 5f43f393 Michael Hanselmann
  optional_arguments = 0
131 5f43f393 Michael Hanselmann
  final_argument_whitespace = False
132 5f43f393 Michael Hanselmann
  option_spec = dict(include=_SplitOption, exclude=_SplitOption,
133 5f43f393 Michael Hanselmann
                     alias=_ParseAlias)
134 5f43f393 Michael Hanselmann
135 5f43f393 Michael Hanselmann
  def run(self):
136 5f43f393 Michael Hanselmann
    op_id = self.arguments[0]
137 5f43f393 Michael Hanselmann
    include = self.options.get("include", None)
138 5f43f393 Michael Hanselmann
    exclude = self.options.get("exclude", None)
139 5f43f393 Michael Hanselmann
    alias = self.options.get("alias", {})
140 5f43f393 Michael Hanselmann
141 5f43f393 Michael Hanselmann
    tab_width = 2
142 5f43f393 Michael Hanselmann
    path = op_id
143 5f43f393 Michael Hanselmann
    include_text = "\n".join(_BuildOpcodeParams(op_id, include, exclude, alias))
144 5f43f393 Michael Hanselmann
145 5f43f393 Michael Hanselmann
    # Inject into state machine
146 dac59ac5 Michael Hanselmann
    include_lines = docutils.statemachine.string2lines(include_text, tab_width,
147 dac59ac5 Michael Hanselmann
                                                       convert_whitespace=1)
148 5f43f393 Michael Hanselmann
    self.state_machine.insert_input(include_lines, path)
149 5f43f393 Michael Hanselmann
150 5f43f393 Michael Hanselmann
    return []
151 5f43f393 Michael Hanselmann
152 5f43f393 Michael Hanselmann
153 5f43f393 Michael Hanselmann
def setup(app):
154 5f43f393 Michael Hanselmann
  """Sphinx extension callback.
155 5f43f393 Michael Hanselmann

156 5f43f393 Michael Hanselmann
  """
157 5f43f393 Michael Hanselmann
  app.add_directive("opcode_params", OpcodeParams)