/
prep.py
executable file
·95 lines (73 loc) · 2.51 KB
/
prep.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python3.11
import importlib
import signal
import sys
from pathlib import Path
from typing import Any, Sequence, Tuple
import conf
from common import Action, Cmd, p
def main(argv: Sequence[str]) -> Tuple[int | None, str | Exception | None]:
if len(argv) == 1:
p(f"Usage: {argv[0]} <path> [<command> [<args>]]")
return None, None
path = argv[1]
prepfile = Path(path, ".prep")
if not prepfile.exists():
return 1, f"no .prep file at path: {path}"
err = conf.load(prepfile)
if err is not None:
return 1, err
if not conf.symbols() and not conf.actions():
return 1, "empty prepfile?"
cmd = argv[2] if len(argv) > 2 else None
cmds: dict[str, Cmd] = {
"st": ActionCmd(Action("st")),
"gc": ActionCmd(Action("gc")),
}
cmds |= {name: ActionCmd(action) for name, action in conf.actions().items()}
if cmd is None:
p("Available commands:")
p(list_cmds(cmds))
return None, None
if cmd not in cmds:
p(f"Unknown command: {cmd}")
return 1, None
if isinstance(cmds[cmd], ActionCmd):
return cmds[cmd].run(*argv[3:], path=path, symbols=conf.symbols())
raise NotImplementedError
class ActionCmd:
def __init__(self, action: Action):
assert action is not None
self._action = action
@property
def action(self) -> Action:
return self._action
def run(self, *args: str, **kwargs: Any) -> Tuple[int | None, str | Exception | None]:
mod_name = self._action.using if self._action.using else "generic"
try:
mod = importlib.import_module("actions." + mod_name)
except (ImportError, ModuleNotFoundError) as e:
return 2, e
mod_cmd, err = mod.getcmd(self._action.name)
if err is not None:
return 2, err
ret, err = mod_cmd.run(*args, **kwargs)
return ret, err
def list_cmds(cmds: dict[str, Cmd]) -> str:
def s(name: str, cmd: Cmd) -> str:
if isinstance(cmd, ActionCmd) and cmd.action.using:
return "\t" + name + f"\t({cmd.action.using})"
return "\t" + name
return "\n".join(s(name, cmd) for name, cmd in cmds.items())
if __name__ == "__main__":
try:
if sys.platform != "win32":
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
ret, err = main(sys.argv)
if err is not None:
p("Error:", err)
if ret:
exit(ret)
except KeyboardInterrupt:
p()
sys.stderr.close()