1import ast
2import sys
3from pathlib import Path
4
5"""
6This program takes all the Machine class methods and prints its methods in
7markdown-style. These can then be included in the NixOS test driver
8markdown style, assuming the docstrings themselves are also in markdown.
9
10These are included in the test driver documentation in the NixOS manual.
11See https://nixos.org/manual/nixos/stable/#ssec-machine-objects
12
13The python input looks like this:
14
15```py
16...
17
18class Machine(...):
19 ...
20
21 def some_function(self, param1, param2):
22 ""
23 documentation string of some_function.
24 foo bar baz.
25 ""
26 ...
27```
28
29Output will be:
30
31```markdown
32...
33
34some_function(param1, param2)
35
36: documentation string of some_function.
37 foo bar baz.
38
39...
40```
41
42"""
43
44
45def main() -> None:
46 if len(sys.argv) != 2:
47 print(f"Usage: {sys.argv[0]} <path-to-test-driver>")
48 sys.exit(1)
49
50 module = ast.parse(Path(sys.argv[1]).read_text())
51
52 class_definitions = (node for node in module.body if isinstance(node, ast.ClassDef))
53
54 machine_class = next(filter(lambda x: x.name == "Machine", class_definitions))
55 assert machine_class is not None
56
57 function_definitions = [
58 node for node in machine_class.body if isinstance(node, ast.FunctionDef)
59 ]
60 function_definitions.sort(key=lambda x: x.name)
61
62 for function in function_definitions:
63 docstr = ast.get_docstring(function)
64 if docstr is not None:
65 args = ", ".join(a.arg for a in function.args.args[1:])
66 args = f"({args})"
67
68 docstr = "\n".join(f" {line}" for line in docstr.strip().splitlines())
69
70 print(f"{function.name}{args}\n\n:{docstr[1:]}\n")
71
72
73if __name__ == "__main__":
74 main()