-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmklinks.py
executable file
·79 lines (57 loc) · 2.27 KB
/
mklinks.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
#! /usr/bin/env python
"Create/update symlinks"
__author__ = "Paresh Adhia"
__copyright__ = "Copyright 2018-2019, Paresh Adhia"
__version__ = "0.1.0"
import sys
from argparse import ArgumentTypeError
from pathlib import Path
from tomllib import load
from typing import Any, Iterable, cast
type Schedule = dict[str, Schedule | list[str]]
def main(docs_dir: Path) -> None:
"script entry-point"
lib = {p.stem: p for d in docs_dir.iterdir() for p in d.resolve().rglob("*.md") if p.is_file()}
schedules = (d for d in docs_dir.rglob("*.toml"))
for s in schedules:
fill_schedule(s, lib)
def fill_schedule(schedule_file: Path, lib: dict[str, Path]):
with schedule_file.open("rb") as f:
schedule = cast(Schedule, load(f))
def iterpath(o: Schedule, parent: Path) -> Iterable[tuple[Path, Path | None]]:
for k, v in o.items():
if isinstance(v, list):
yield from ((parent / k / f"{x}.md", lib.get(x)) for x in v)
else:
yield from iterpath(v, parent / str(k))
links = dict(iterpath(schedule, schedule_file.parent / schedule_file.stem))
for d in {k.parent for k, v in links.items() if v is not None}:
d.mkdir(parents=True, exist_ok=True)
for link, base in links.items():
if base is None:
print(f"No song file found for '{link}'", file=sys.stderr)
else:
if link.is_symlink():
if link.samefile(base):
continue
link.unlink()
link.symlink_to(base)
def getargs():
"script arguments; accept list paths to scan toc and root of library -- both optional"
import argparse
def existing_path(v: str) -> Path:
p = Path(v)
if not p.exists():
raise ArgumentTypeError(f"'{v}' is not an existing path")
return p.absolute()
def mk_default(p: Path) -> dict[str, Any]:
return {"default": p} if p.exists() else {"required": True}
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--docs-dir", **mk_default(Path.cwd() / "docs"), type=existing_path, help="Docs root directory (default: ./docs)"
)
return parser.parse_args()
def cli():
main(**getargs().__dict__)
if __name__ == "__main__":
cli()