-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathgenerate_command_docs.py
93 lines (69 loc) · 2.44 KB
/
generate_command_docs.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
89
90
91
92
93
"""This module generates reference docs for pebble CLI commands."""
import logging
import subprocess
import typing
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
def get_all_commands() -> typing.List[str]:
process = subprocess.run(
["go", "run", "../cmd/pebble", "help", "--all"],
text=True,
capture_output=True,
check=True,
)
return sorted(
line.split(maxsplit=1)[0]
for line in process.stdout.splitlines()
if line.startswith(" ")
)
def get_command_help_output(cmd: str) -> str:
# Set a fixed terminal line columns so that the output won't be
# affected by the actual terminal width.
cmd = f"stty cols 80; {cmd}"
return subprocess.run(
cmd,
shell=True,
text=True,
capture_output=True,
check=True,
).stdout
class Markers:
def __init__(self, cmd: str):
self.start = f"<!-- START AUTOMATED OUTPUT FOR {cmd} -->"
self.end = f"<!-- END AUTOMATED OUTPUT FOR {cmd} -->"
def generate_example(cmd: str, markers: Markers) -> str:
args = ["help"] if cmd == "help" else [cmd, "--help"]
help_cmd_str = " ".join(["pebble"] + args)
go_run_cmd = " ".join(["go", "run", "../cmd/pebble"] + args)
help_output = get_command_help_output(go_run_cmd).strip()
return f"""\
{markers.start}
```{{terminal}}
:input: {help_cmd_str}
{help_output}
```
{markers.end}"""
def insert_example(text: str, markers: Markers, example: str) -> str:
start_pos = text.find(markers.start)
end_pos = text.find(markers.end) + len(markers.end)
return text[:start_pos] + example + text[end_pos:]
def process_commands(cmds: typing.List[str]):
file_path = "reference/cli-commands.md"
with open(file_path, "r") as file:
text = file.read()
for cmd in cmds:
logger.info(f"Generating help output for '{cmd}'")
markers = Markers(cmd)
if markers.start not in text or markers.end not in text:
logging.error(f"Missing marker for '{cmd}' in {file_path}. Aborting doc generation")
raise RuntimeError(f"Missing marker for '{cmd}' in {file_path}")
example = generate_example(cmd, markers)
text = insert_example(text, markers, example)
with open(file_path, "w") as file:
file.write(text)
def main():
cmds = get_all_commands()
process_commands(cmds)
logger.info("Done!")
if __name__ == "__main__":
main()