2Some helper functions for generating the README files in this repo.
3In particular, it can take a list of scripts as a Python object, and
4create an HTML definition list that describes them in a human-readable way.
6Here Cog is Ned Batchelder's file generation tool, described here:
7https://nedbatchelder.com/code/cog
11from pathlib import Path
13from typing import TypedDict
18class ScriptWithName(TypedDict):
23class ScriptWithVariants(TypedDict):
28class ScriptWithUsage(TypedDict):
33Script = ScriptWithName | ScriptWithUsage | ScriptWithVariants
36def outl(s: str, indent: int = 0):
37 cog.outl(textwrap.indent(s, prefix=" " * indent))
40def create_description_table(
42 scripts: list[Script],
43 repo_name: str = "alexwlchan/scripts",
44 primary_branch: str = "main",
45 ignore_files: set[str] | None = None,
47 documented_files = set()
49 if ignore_files is None:
52 folder = Path(folder_name)
54 for f in ignore_files:
55 if not (folder / f).exists():
56 raise ValueError(f"Ignoring non-existing file {f!r}")
60 for i, s in enumerate(scripts, start=1):
62 variants = [s["name"]]
64 variants = s["variants"]
66 variants = [s["usage"].split()[0]]
68 outl("<dt>", indent=2)
70 for index, v in enumerate(variants, start=1):
74 assert path.exists(), path
76 documented_files.add(name)
79 f'<a href="https://github.com/{repo_name}/blob/{primary_branch}/{folder_name}/{name}">',
88 outl(f"<code>{usage}</code>", indent=6)
89 outl("</a>", indent=4)
91 if index != len(variants):
94 outl("</dt>", indent=2)
96 outl("<dd>", indent=2)
97 outl(textwrap.dedent(s["description"]).strip(), indent=4)
98 outl("</dd>", indent=2)
100 if i != len(scripts):
105 # Now check there isn't anything in the folder which should have
106 # been documented, but isn't.
107 undocumented_files = set()
109 for f in os.listdir(folder_name):
110 if os.path.isdir(folder / f):
113 if f in {"README.md", "requirements.in", "requirements.txt"}:
116 if f.startswith(("test_", "_", ".")):
119 if f.endswith((".png", ".db")):
122 if f in ignore_files:
125 if f not in documented_files:
126 undocumented_files.add(f)
128 if undocumented_files:
130 f"Not all files in {folder_name} are documented: {undocumented_files}"