PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/config/makerestdoc.py

https://bitbucket.org/pypy/pypy/
Python | 227 lines | 220 code | 7 blank | 0 comment | 7 complexity | 48b451e2ff641ce9c5383a910aeacc9d MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from pypy.tool.rest.rst import Rest, Paragraph, Strong, ListItem, Title, Link
  3. from pypy.tool.rest.rst import Directive, Text
  4. from rpython.config.config import ChoiceOption, BoolOption, StrOption, IntOption
  5. from rpython.config.config import FloatOption, OptionDescription, Option, Config
  6. from rpython.config.config import ArbitraryOption, DEFAULT_OPTION_NAME
  7. from rpython.config.config import _getnegation
  8. configdocdir = py.path.local(__file__).dirpath().dirpath().join("doc", "config")
  9. def get_fullpath(opt, path):
  10. if path:
  11. return "%s.%s" % (path, opt._name)
  12. else:
  13. return opt._name
  14. def get_cmdline(cmdline, fullpath):
  15. if cmdline is DEFAULT_OPTION_NAME:
  16. return '--%s' % (fullpath.replace('.', '-'),)
  17. else:
  18. return cmdline
  19. class __extend__(Option):
  20. def make_rest_doc(self, path=""):
  21. fullpath = get_fullpath(self, path)
  22. result = Rest(
  23. Title(fullpath, abovechar="=", belowchar="="),
  24. ListItem(Strong("name:"), self._name),
  25. ListItem(Strong("description:"), self.doc))
  26. if self.cmdline is not None:
  27. cmdline = get_cmdline(self.cmdline, fullpath)
  28. result.add(ListItem(Strong("command-line:"), cmdline))
  29. return result
  30. class __extend__(ChoiceOption):
  31. def make_rest_doc(self, path=""):
  32. content = super(ChoiceOption, self).make_rest_doc(path)
  33. content.add(ListItem(Strong("option type:"), "choice option"))
  34. content.add(ListItem(Strong("possible values:"),
  35. *[ListItem(str(val)) for val in self.values]))
  36. if self.default is not None:
  37. content.add(ListItem(Strong("default:"), str(self.default)))
  38. requirements = []
  39. for val in self.values:
  40. if val not in self._requires:
  41. continue
  42. req = self._requires[val]
  43. requirements.append(ListItem("value '%s' requires:" % (val, ),
  44. *[ListItem(Link(opt, opt + ".html"),
  45. "to be set to '%s'" % (rval, ))
  46. for (opt, rval) in req]))
  47. if requirements:
  48. content.add(ListItem(Strong("requirements:"), *requirements))
  49. return content
  50. class __extend__(BoolOption):
  51. def make_rest_doc(self, path=""):
  52. content = super(BoolOption, self).make_rest_doc(path)
  53. fullpath = get_fullpath(self, path)
  54. if self.negation and self.cmdline is not None:
  55. if self.cmdline is DEFAULT_OPTION_NAME:
  56. cmdline = '--%s' % (fullpath.replace('.', '-'),)
  57. else:
  58. cmdline = self.cmdline
  59. neg_cmdline = ["--" + _getnegation(argname.lstrip("-"))
  60. for argname in cmdline.split()
  61. if argname.startswith("--")][0]
  62. content.add(ListItem(Strong("command-line for negation:"),
  63. neg_cmdline))
  64. content.add(ListItem(Strong("option type:"), "boolean option"))
  65. if self.default is not None:
  66. content.add(ListItem(Strong("default:"), str(self.default)))
  67. if self._requires is not None:
  68. requirements = [ListItem(Link(opt, opt + ".html"),
  69. "must be set to '%s'" % (rval, ))
  70. for (opt, rval) in self._requires]
  71. if requirements:
  72. content.add(ListItem(Strong("requirements:"), *requirements))
  73. if self._suggests is not None:
  74. suggestions = [ListItem(Link(opt, opt + ".html"),
  75. "should be set to '%s'" % (rval, ))
  76. for (opt, rval) in self._suggests]
  77. if suggestions:
  78. content.add(ListItem(Strong("suggestions:"), *suggestions))
  79. return content
  80. class __extend__(IntOption):
  81. def make_rest_doc(self, path=""):
  82. content = super(IntOption, self).make_rest_doc(path)
  83. content.add(ListItem(Strong("option type:"), "integer option"))
  84. if self.default is not None:
  85. content.add(ListItem(Strong("default:"), str(self.default)))
  86. return content
  87. class __extend__(FloatOption):
  88. def make_rest_doc(self, path=""):
  89. content = super(FloatOption, self).make_rest_doc(path)
  90. content.add(ListItem(Strong("option type:"), "float option"))
  91. if self.default is not None:
  92. content.add(ListItem(Strong("default:"), str(self.default)))
  93. return content
  94. class __extend__(StrOption):
  95. def make_rest_doc(self, path=""):
  96. content = super(StrOption, self).make_rest_doc(path)
  97. content.add(ListItem(Strong("option type:"), "string option"))
  98. if self.default is not None:
  99. content.add(ListItem(Strong("default:"), str(self.default)))
  100. return content
  101. class __extend__(ArbitraryOption):
  102. def make_rest_doc(self, path=""):
  103. content = super(ArbitraryOption, self).make_rest_doc(path)
  104. content.add(ListItem(Strong("option type:"),
  105. "arbitrary option (mostly internal)"))
  106. if self.default is not None:
  107. content.add(ListItem(Strong("default:"), str(self.default)))
  108. elif self.defaultfactory is not None:
  109. content.add(ListItem(Strong("factory for the default value:"),
  110. str(self.defaultfactory)))
  111. return content
  112. class __extend__(OptionDescription):
  113. def make_rest_doc(self, path=""):
  114. fullpath = get_fullpath(self, path)
  115. content = Rest(
  116. Title(fullpath, abovechar="=", belowchar="="))
  117. toctree = []
  118. for child in self._children:
  119. subpath = fullpath + "." + child._name
  120. toctree.append(subpath)
  121. content.add(Directive("toctree", *toctree, **{'maxdepth': 4}))
  122. content.join(
  123. ListItem(Strong("name:"), self._name),
  124. ListItem(Strong("description:"), self.doc))
  125. return content
  126. def _get_section_header(cmdline, fullpath, subdescr):
  127. # XXX: pypy specific hack
  128. txtfile = configdocdir.join(fullpath + ".txt")
  129. if not txtfile.check():
  130. print txtfile, "not found"
  131. return ""
  132. content = txtfile.read()
  133. if ".. internal" in content:
  134. return "Internal Options"
  135. return ""
  136. def make_cmdline_overview(descr, title=True):
  137. content = Rest()
  138. if title:
  139. content.add(
  140. Title("Overview of Command Line Options for '%s'" % (descr._name, ),
  141. abovechar="=", belowchar="="))
  142. cmdlines = []
  143. config = Config(descr)
  144. for path in config.getpaths(include_groups=False):
  145. subconf, step = config._cfgimpl_get_home_by_path(path)
  146. fullpath = (descr._name + "." + path)
  147. subdescr = getattr(subconf._cfgimpl_descr, step)
  148. cmdline = get_cmdline(subdescr.cmdline, fullpath)
  149. if cmdline is not None:
  150. header = _get_section_header(cmdline, fullpath, subdescr)
  151. cmdlines.append((header, cmdline, fullpath, subdescr))
  152. cmdlines.sort(key=lambda x: (x[0], x[1].strip("-")))
  153. currheader = ""
  154. curr = content
  155. for header, cmdline, fullpath, subdescr in cmdlines:
  156. if header != currheader:
  157. content.add(Title(header, abovechar="", belowchar="="))
  158. curr = content.add(Paragraph())
  159. currheader = header
  160. curr.add(ListItem(Link(cmdline + ":", fullpath + ".html"),
  161. Text(subdescr.doc)))
  162. return content
  163. def register_config_role(docdir):
  164. """ register a :config: ReST link role for use in documentation. """
  165. try:
  166. from docutils.parsers.rst import directives, states, roles
  167. from pypy.tool.rest.directive import register_linkrole
  168. except ImportError:
  169. return
  170. # enable :config: link role
  171. def config_role(name, rawtext, text, lineno, inliner, options={},
  172. content=[]):
  173. from docutils import nodes
  174. from pypy.config.pypyoption import get_pypy_config
  175. from pypy.config.makerestdoc import get_cmdline
  176. txt = docdir.join("config", text + ".rst")
  177. html = docdir.join("config", text + ".html")
  178. assert txt.check()
  179. assert name == "config"
  180. sourcedir = py.path.local(inliner.document.settings._source).dirpath()
  181. curr = sourcedir
  182. prefix = ""
  183. while 1:
  184. relative = str(html.relto(curr))
  185. if relative:
  186. break
  187. curr = curr.dirpath()
  188. prefix += "../"
  189. config = get_pypy_config()
  190. # begin horror
  191. h, n = config._cfgimpl_get_home_by_path(text)
  192. opt = getattr(h._cfgimpl_descr, n)
  193. # end horror
  194. cmdline = get_cmdline(opt.cmdline, text)
  195. if cmdline is not None:
  196. shortest_long_option = 'X'*1000
  197. for cmd in cmdline.split():
  198. if cmd.startswith('--') and len(cmd) < len(shortest_long_option):
  199. shortest_long_option = cmd
  200. text = shortest_long_option
  201. target = prefix + relative
  202. reference_node = nodes.reference(rawtext, text, name=text, refuri=target)
  203. return [reference_node], []
  204. config_role.content = True
  205. config_role.options = {}
  206. return config_role