2023-07-07 22:01:55 +01:00
|
|
|
import ast
|
|
|
|
import sys
|
2023-09-30 08:59:17 +01:00
|
|
|
from pathlib import Path
|
2023-07-07 22:01:55 +01:00
|
|
|
|
|
|
|
"""
|
|
|
|
This program takes all the Machine class methods and prints its methods in
|
|
|
|
markdown-style. These can then be included in the NixOS test driver
|
|
|
|
markdown style, assuming the docstrings themselves are also in markdown.
|
|
|
|
|
|
|
|
These are included in the test driver documentation in the NixOS manual.
|
|
|
|
See https://nixos.org/manual/nixos/stable/#ssec-machine-objects
|
|
|
|
|
|
|
|
The python input looks like this:
|
|
|
|
|
|
|
|
```py
|
|
|
|
...
|
|
|
|
|
|
|
|
class Machine(...):
|
|
|
|
...
|
|
|
|
|
|
|
|
def some_function(self, param1, param2):
|
|
|
|
""
|
|
|
|
documentation string of some_function.
|
|
|
|
foo bar baz.
|
|
|
|
""
|
|
|
|
...
|
|
|
|
```
|
|
|
|
|
|
|
|
Output will be:
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
...
|
|
|
|
|
|
|
|
some_function(param1, param2)
|
|
|
|
|
|
|
|
: documentation string of some_function.
|
|
|
|
foo bar baz.
|
|
|
|
|
|
|
|
...
|
|
|
|
```
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2023-09-30 08:59:17 +01:00
|
|
|
def main() -> None:
|
|
|
|
if len(sys.argv) != 2:
|
|
|
|
print(f"Usage: {sys.argv[0]} <path-to-test-driver>")
|
|
|
|
sys.exit(1)
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 08:59:17 +01:00
|
|
|
module = ast.parse(Path(sys.argv[1]).read_text())
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 08:59:17 +01:00
|
|
|
class_definitions = (node for node in module.body if isinstance(node, ast.ClassDef))
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 08:59:17 +01:00
|
|
|
machine_class = next(filter(lambda x: x.name == "Machine", class_definitions))
|
|
|
|
assert machine_class is not None
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 08:59:17 +01:00
|
|
|
function_definitions = [
|
|
|
|
node for node in machine_class.body if isinstance(node, ast.FunctionDef)
|
|
|
|
]
|
|
|
|
function_definitions.sort(key=lambda x: x.name)
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 09:18:47 +01:00
|
|
|
for function in function_definitions:
|
|
|
|
docstr = ast.get_docstring(function)
|
2023-09-30 08:59:17 +01:00
|
|
|
if docstr is not None:
|
2023-09-30 09:18:47 +01:00
|
|
|
args = ", ".join(a.arg for a in function.args.args[1:])
|
2023-09-30 08:59:17 +01:00
|
|
|
args = f"({args})"
|
2023-07-07 22:01:55 +01:00
|
|
|
|
2023-09-30 09:18:47 +01:00
|
|
|
docstr = "\n".join(f" {line}" for line in docstr.strip().splitlines())
|
2023-09-30 08:59:17 +01:00
|
|
|
|
2023-09-30 09:18:47 +01:00
|
|
|
print(f"{function.name}{args}\n\n:{docstr[1:]}\n")
|
2023-09-30 08:59:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|