File: cli_usage.py

package info (click to toggle)
python-uvicorn 0.32.0-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,636 kB
  • sloc: python: 8,853; sh: 100; makefile: 13
file content (70 lines) | stat: -rw-r--r-- 1,979 bytes parent folder | download
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
"""
Look for a marker comment in docs pages, and place the output of
`$ uvicorn --help` there. Pass `--check` to ensure the content is in sync.
"""

from __future__ import annotations

import argparse
import subprocess
import sys
from pathlib import Path


def _get_usage_lines() -> list[str]:
    res = subprocess.run(["uvicorn", "--help"], stdout=subprocess.PIPE)
    help_text = res.stdout.decode("utf-8")
    return ["```", "$ uvicorn --help", *help_text.splitlines(), "```"]


def _find_next_codefence_lineno(lines: list[str], after: int) -> int:
    return next(lineno for lineno, line in enumerate(lines[after:], after) if line == "```")


def _get_insert_location(lines: list[str]) -> tuple[int, int]:
    marker = lines.index("<!-- :cli_usage: -->")
    start = marker + 1

    if lines[start] == "```":
        # Already generated.
        # <!-- :cli_usage: -->
        # ```   <- start
        # [...]
        # ```   <- end
        next_codefence = _find_next_codefence_lineno(lines, after=start + 1)
        end = next_codefence + 1
    else:
        # Not generated yet.
        end = start

    return start, end


def _generate_cli_usage(path: Path, check: bool = False) -> int:
    content = path.read_text()

    lines = content.splitlines()
    usage_lines = _get_usage_lines()
    start, end = _get_insert_location(lines)
    lines = lines[:start] + usage_lines + lines[end:]
    output = "\n".join(lines) + "\n"

    if check:
        if content == output:
            return 0
        print(f"ERROR: CLI usage in {path} is out of sync. Run scripts/lint to fix.")
        return 1

    path.write_text(output)
    return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--check", action="store_true")
    args = parser.parse_args()
    paths = [Path("docs", "index.md"), Path("docs", "deployment.md")]
    rv = 0
    for path in paths:
        rv |= _generate_cli_usage(path, check=args.check)
    sys.exit(rv)