-
Notifications
You must be signed in to change notification settings - Fork 290
/
_sphinx.py
88 lines (63 loc) · 2.31 KB
/
_sphinx.py
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Copyright Hybrid Logic Ltd. See LICENSE file for details.
"""
Sphinx extension to add a ``task`` directive
This directive allows sharing code between documentation and provisioning code.
.. code-block:: rest
.. task:: name_of_task
``name_of_task`` must the name of a task in ``flocker.provision._tasks``,
without the ``task_`` prefix. A task must take a single runner argument.
"""
from inspect import getsourcefile
from docutils.parsers.rst import Directive
from docutils import nodes
from docutils.statemachine import StringList
from . import _tasks as tasks
from ._install import Run, Sudo, Comment
def run(command):
return [command.command]
def sudo(command):
return ["sudo %s" % (command.command,)]
def comment(command):
return ["# %s" % (command.comment)]
HANDLERS = {
Run: run,
Sudo: sudo,
Comment: comment,
}
class TaskDirective(Directive):
"""
Implementation of the C{task} directive.
"""
required_arguments = 1
option_spec = {
'prompt': str
}
def run(self):
task = getattr(tasks, 'task_%s' % (self.arguments[0],))
prompt = self.options.get('prompt', '$')
commands = task()
lines = ['.. prompt:: bash %s' % (prompt,), '']
for command in commands:
try:
handler = HANDLERS[type(command)]
except KeyError:
raise self.error("task: %s not supported"
% (type(command).__name__,))
lines += [' %s' % (line,) for line in handler(command)]
# The following three lines record (some?) of the dependencies of the
# directive, so automatic regeneration happens. Specifically, it
# records this file, and the file where the task is declared.
task_file = getsourcefile(task)
tasks_file = getsourcefile(tasks)
self.state.document.settings.record_dependencies.add(task_file)
self.state.document.settings.record_dependencies.add(tasks_file)
self.state.document.settings.record_dependencies.add(__file__)
node = nodes.Element()
text = StringList(lines)
self.state.nested_parse(text, self.content_offset, node)
return node.children
def setup(app):
"""
Entry point for sphinx extension.
"""
app.add_directive('task', TaskDirective)