ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
work_just.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# SPDX-License-Identifier: MIT
3# Copyright (c) 2026 Brighton Sikarskie
4"""Exact-argv adapter for the deliberately non-variadic Just facade."""
5
6from __future__ import annotations
7
8import subprocess
9import sys
10from collections.abc import Callable
11from pathlib import Path
12from typing import NoReturn
13
14Adapter = Callable[[list[str]], list[str]]
15PLAN_ARGC = 3
16START_ARGC = 4
17STATUS_ARGC = 1
18PHASE_ARGC = 2
19BOARD_MOVE_ARGC = 3
20
21
22def fail(message: str) -> NoReturn:
23 """Raise one consistently constructed adapter error."""
24 error = ValueError(message)
25 raise error
26
27
28def _optional(flag: str, value: str) -> list[str]:
29 """Return one optional flag/value pair without shell reconstruction."""
30 return [] if not value else [flag, value]
31
32
33def _doctor(argv: list[str]) -> list[str]:
34 """Translate the zero-argument doctor shape."""
35 if argv:
36 fail("doctor takes no Just arguments")
37 return ["doctor"]
38
39
40def _plan(argv: list[str]) -> list[str]:
41 """Translate one explicit plan output mode."""
42 if len(argv) != PLAN_ARGC:
43 fail("plan requires notes, mode, and output slots")
44 notes, mode, output = argv
45 result = ["plan", notes]
46 modes = {"summary": "--summary", "commands": "--emit-commands"}
47 if mode in modes:
48 result.append(modes[mode])
49 elif mode == "json":
50 if not output:
51 fail("JSON output path is empty")
52 result.extend(["--json", output])
53 elif mode != "default":
54 fail("unknown plan output mode")
55 return result
56
57
58def _start(argv: list[str]) -> list[str]:
59 """Translate the fixed start preview/execute shape."""
60 if len(argv) != START_ARGC:
61 fail("start requires identifier, ref, root, and execute slots")
62 identifier, ref, root, execute = argv
63 result = ["start", identifier, "--ref", ref, *_optional("--ws-root", root)]
64 if execute == "true":
65 result.append("--execute")
66 elif execute != "false":
67 fail("invalid execute value")
68 return result
69
70
71def _status(argv: list[str]) -> list[str]:
72 """Translate the fixed status shape."""
73 if len(argv) != STATUS_ARGC:
74 fail("status requires one root slot")
75 return ["status", *_optional("--ws-root", argv[0])]
76
77
78def _phase(action: str, argv: list[str]) -> list[str]:
79 """Translate ready or landed without a generic flag tail."""
80 if len(argv) != PHASE_ARGC:
81 fail(f"{action} requires identifier and root slots")
82 result = [action, argv[0], *_optional("--ws-root", argv[1])]
83 if action == "ready":
84 result.append("--run-ci")
85 return result
86
87
88def build_argv(argv: list[str]) -> list[str]:
89 """Translate one fixed Just recipe shape into the public CLI argv."""
90 if not argv:
91 fail("missing Just action")
92 if argv[0] == "board":
93 if len(argv) > 1:
94 fail("board takes no arguments")
95 return ["board"]
96 if len(argv) != BOARD_MOVE_ARGC:
97 fail("board_move requires issue_number and status")
98 return ["board_move", argv[1], argv[2]]
99 action, values = argv[0], argv[1:]
100 adapters: dict[str, Adapter] = {
101 "doctor": _doctor,
102 "plan": _plan,
103 "start": _start,
104 "status": _status,
105 "ready": lambda items: _phase("ready", items),
106 "landed": lambda items: _phase("landed", items),
107 }
108 adapter = adapters.get(action)
109 if adapter is None:
110 fail(f"invalid Just action: {action}")
111 return adapter(values)
112
113
114def main(argv: list[str]) -> int:
115 """Run isolated Python with the exact translated argv."""
116 try:
117 translated = build_argv(argv)
118 except ValueError as exc:
119 print(f"work Just adapter: {exc}", file=sys.stderr)
120 return 2
121 if translated[0] == "board":
122 entrypoint = Path(__file__).resolve().with_name("work_board.py")
123 result = subprocess.run( # noqa: S603
124 ["/usr/bin/python3", "-I", str(entrypoint)], check=False
125 )
126 return result.returncode
127
128 if translated[0] == "board_move":
129 entrypoint = Path(__file__).resolve().with_name("work_board_move.py")
130 result = subprocess.run( # noqa: S603
131 ["/usr/bin/python3", "-I", str(entrypoint), translated[1], translated[2]], check=False
132 )
133 return result.returncode
134
135 entrypoint = Path(__file__).resolve().with_name("work.py")
136 result = subprocess.run( # noqa: S603 -- fixed interpreter, entrypoint, and data argv
137 ["/usr/bin/python3", "-I", str(entrypoint), *translated], check=False
138 )
139 return result.returncode
140
141
142if __name__ == "__main__":
143 raise SystemExit(main(sys.argv[1:]))
void main(void)
The application entry point Reset_Handler hands control to.
Definition main.c:298