-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmain.py
More file actions
102 lines (85 loc) · 3.12 KB
/
main.py
File metadata and controls
102 lines (85 loc) · 3.12 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python3
"""
Repo entrypoint.
All script CLIs under ./script/ are invoked through this dispatcher.
Individual scripts no longer have standalone `__main__` entrypoints.
"""
from __future__ import annotations
import argparse
import importlib
import sys
from pathlib import Path
from typing import Callable, Dict, List, Tuple
def _bootstrap_sys_path() -> Path:
repo_root = Path(__file__).resolve().parent
# Keep these at the front to avoid accidentally importing third-party modules
# with the same names as our local files.
add = [
repo_root,
repo_root / "script",
repo_root / "script" / "parsing",
repo_root / "script" / "postprocess",
repo_root / "script" / "visualization",
repo_root / "script" / "utils",
]
for p in reversed(add):
sp = str(p)
if sp not in sys.path:
sys.path.insert(0, sp)
return repo_root
def _run_module_main(module_name: str, argv: List[str]) -> int:
mod = importlib.import_module(module_name)
fn = getattr(mod, "main", None)
if not callable(fn):
raise SystemExit(f"[main] module has no callable main(): {module_name}")
old_argv = sys.argv[:]
sys.argv = [module_name] + list(argv)
try:
rc = fn()
if rc is None:
return 0
if isinstance(rc, int):
return rc
return 0
except SystemExit as e:
# Respect sub-command argparse behavior.
code = e.code
if code is None:
return 0
if isinstance(code, int):
return code
return 1
finally:
sys.argv = old_argv
def main() -> int:
_bootstrap_sys_path()
commands: Dict[str, Tuple[str, str]] = {
# Top-level
"compile": ("script.lpsb_compiler", "main"),
"verify-failures": ("script.verify_failures", "main"),
# parsing/
"parse-mcid": ("script.parsing.parse_lpsb_mcid", "main"),
"build-doc-tree": ("script.parsing.build_doc_tree", "main"),
# postprocess/
"fix-split-headings": ("script.postprocess.fix_split_headings", "main"),
"merge-split-paragraphs": ("script.postprocess.merge_split_paragraphs", "main"),
"fix-crosspage-mcid": ("script.postprocess.fix_crosspage_mcid", "main"),
"compute-order-map": ("script.postprocess.compute_order_map", "main"),
"inject-structtree": ("script.postprocess.inject_structtree", "main"),
# visualization/
"visualize-mcid": ("script.visualization.visualize_mcid", "main"),
"visualize-annotations": ("script.visualization.visualize_annotations", "main"),
}
ap = argparse.ArgumentParser(description="LPSB unified entrypoint")
sp = ap.add_subparsers(dest="cmd", required=True)
for name in sorted(commands.keys()):
sp.add_parser(
name,
help=f"Run {commands[name][0]}.main()",
add_help=False, # pass -h/--help to underlying script
)
args, rest = ap.parse_known_args()
modname, _fn = commands[str(args.cmd)]
return _run_module_main(modname, list(rest))
if __name__ == "__main__":
raise SystemExit(main())