Add default series and card commands
This commit is contained in:
@@ -325,6 +325,7 @@ inf 3 0
|
||||
Po wybraniu serii `inf` wylistuj karty:
|
||||
|
||||
```bash
|
||||
./rvctl series use inf
|
||||
./rvctl series cards list inf
|
||||
```
|
||||
|
||||
@@ -335,12 +336,19 @@ bss lab-rv32i-strlen-bss-data-stack source rv32i-c / bss-data-stack
|
||||
```
|
||||
|
||||
Przykładowa karta `bss` odpowiada repo `lab-rv32i-strlen-bss-data-stack`.
|
||||
Pobierz ją do workspace:
|
||||
Ustaw ją jako domyślną i pobierz do workspace:
|
||||
|
||||
```bash
|
||||
./rvctl card use bss
|
||||
./rvctl series cards fetch inf bss
|
||||
```
|
||||
|
||||
Jeżeli chcesz jedną komendą ustawić serię i kartę, użyj:
|
||||
|
||||
```bash
|
||||
./rvctl card use inf bss
|
||||
```
|
||||
|
||||
Karty trafiają do `series` w workspace:
|
||||
|
||||
```text
|
||||
@@ -370,7 +378,7 @@ answer_url http://77.90.8.171:3001/c2025-1a-inf/lab-rv32i-strlen-bss-data-st
|
||||
```
|
||||
|
||||
Następnie wylistuj zadania w karcie. Skrót `tasks` działa na domyślnej serii i
|
||||
karcie z `workspace.json`, czyli tutaj na `inf bss`:
|
||||
karcie ustawionej w `workspace.json`, czyli tutaj na `inf bss`:
|
||||
|
||||
```bash
|
||||
./rvctl tasks list
|
||||
|
||||
@@ -211,8 +211,11 @@ Komendy:
|
||||
- `list-series`
|
||||
- `list-cards [series]`
|
||||
- `series list`
|
||||
- `series use SERIES`
|
||||
- `series show SERIES`
|
||||
- `series fetch SERIES [--dry-run]`
|
||||
- `card use CARD`
|
||||
- `card use SERIES CARD`
|
||||
- `series cards list SERIES`
|
||||
- `series cards show SERIES CARD`
|
||||
- `series cards fetch SERIES CARD`
|
||||
@@ -313,6 +316,30 @@ Przykład:
|
||||
./rvctl series list
|
||||
```
|
||||
|
||||
## `series use SERIES`
|
||||
|
||||
Ustawia `defaults.series` w `workspace.json`.
|
||||
|
||||
Argumenty:
|
||||
|
||||
- `SERIES`
|
||||
Id serii, na przykład `inf`.
|
||||
|
||||
Przykład:
|
||||
|
||||
```bash
|
||||
./rvctl series use inf
|
||||
```
|
||||
|
||||
Typowy wynik:
|
||||
|
||||
```text
|
||||
old_series<TAB>...
|
||||
series<TAB>inf
|
||||
status<TAB>updated|unchanged
|
||||
config<TAB>...
|
||||
```
|
||||
|
||||
## `series show SERIES`
|
||||
|
||||
Pokazuje szczegóły jednej serii.
|
||||
@@ -373,6 +400,38 @@ Przykład:
|
||||
./rvctl series cards list inf
|
||||
```
|
||||
|
||||
## `card use CARD`
|
||||
|
||||
Ustawia `defaults.card` w `workspace.json` dla aktualnie domyślnej serii.
|
||||
|
||||
Argumenty:
|
||||
|
||||
- `CARD`
|
||||
Pełna nazwa repo albo unikalny fragment, na przykład `bss`.
|
||||
|
||||
Przykład:
|
||||
|
||||
```bash
|
||||
./rvctl card use bss
|
||||
```
|
||||
|
||||
## `card use SERIES CARD`
|
||||
|
||||
Ustawia jednocześnie `defaults.series` i `defaults.card` w `workspace.json`.
|
||||
|
||||
Argumenty:
|
||||
|
||||
- `SERIES`
|
||||
Id serii, na przykład `inf`.
|
||||
- `CARD`
|
||||
Pełna nazwa repo albo unikalny fragment, na przykład `bss`.
|
||||
|
||||
Przykład:
|
||||
|
||||
```bash
|
||||
./rvctl card use inf bss
|
||||
```
|
||||
|
||||
## `series cards show SERIES CARD`
|
||||
|
||||
Pokazuje szczegóły jednej karty.
|
||||
|
||||
@@ -23,7 +23,9 @@ używa starego fallbacku przez `original_series_root`.
|
||||
```bash
|
||||
./rvctl tokens compare
|
||||
./rvctl series list
|
||||
./rvctl series use inf
|
||||
./rvctl series cards list inf
|
||||
./rvctl card use bss
|
||||
./rvctl series cards fetch inf bss
|
||||
./rvctl tasks list
|
||||
./rvctl tasks switch 1
|
||||
@@ -62,6 +64,15 @@ Pokazuje informacje o serii.
|
||||
./rvctl series show inf
|
||||
```
|
||||
|
||||
### `series use SERIES`
|
||||
|
||||
Ustawia domyślną serię w `workspace.json`. Po tej komendzie skróty kart i
|
||||
zadań mogą korzystać z tej serii bez podawania jej za każdym razem.
|
||||
|
||||
```bash
|
||||
./rvctl series use inf
|
||||
```
|
||||
|
||||
## Karty
|
||||
|
||||
### `series cards list SERIES`
|
||||
@@ -81,6 +92,31 @@ bss lab-rv32i-strlen-bss-data-stack source rv32i-c / bss-data-stack
|
||||
Pierwsza kolumna jest krótką nazwą karty. Pełna nazwa repo zostaje w drugiej
|
||||
kolumnie.
|
||||
|
||||
### `card use CARD`
|
||||
|
||||
Ustawia domyślną kartę w aktualnie domyślnej serii. Dla serii `inf`:
|
||||
|
||||
```bash
|
||||
./rvctl card use bss
|
||||
```
|
||||
|
||||
Komenda zapisuje `defaults.card` w `workspace.json`.
|
||||
|
||||
### `card use SERIES CARD`
|
||||
|
||||
Ustawia jednocześnie domyślną serię i domyślną kartę:
|
||||
|
||||
```bash
|
||||
./rvctl card use inf bss
|
||||
```
|
||||
|
||||
To jest odpowiednik:
|
||||
|
||||
```bash
|
||||
./rvctl series use inf
|
||||
./rvctl card use bss
|
||||
```
|
||||
|
||||
### `series cards fetch SERIES CARD`
|
||||
|
||||
Pobiera albo aktualizuje jedną kartę w workspace. `CARD` może być krótką nazwą
|
||||
|
||||
@@ -185,6 +185,40 @@ def load_config(config_path: Path) -> WorkspaceConfig:
|
||||
)
|
||||
|
||||
|
||||
def write_workspace_config(config: WorkspaceConfig, raw_config: dict) -> None:
|
||||
config.config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
temp_path = config.config_path.with_suffix(config.config_path.suffix + ".tmp")
|
||||
temp_path.write_text(json.dumps(raw_config, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
temp_path.replace(config.config_path)
|
||||
|
||||
|
||||
def update_config_defaults(config: WorkspaceConfig, updates: dict[str, str]) -> dict[str, str]:
|
||||
raw_config = json.loads(config.config_path.read_text(encoding="utf-8"))
|
||||
defaults = raw_config.get("defaults")
|
||||
if not isinstance(defaults, dict):
|
||||
defaults = {}
|
||||
raw_config["defaults"] = defaults
|
||||
|
||||
result: dict[str, str] = {}
|
||||
changed = False
|
||||
for key, value in updates.items():
|
||||
old_value = str(defaults.get(key, ""))
|
||||
if old_value != value:
|
||||
defaults[key] = value
|
||||
changed = True
|
||||
config.defaults[key] = value
|
||||
result[f"old_{key}"] = old_value
|
||||
result[key] = value
|
||||
|
||||
if changed:
|
||||
write_workspace_config(config, raw_config)
|
||||
result["status"] = "updated"
|
||||
else:
|
||||
result["status"] = "unchanged"
|
||||
result["config"] = str(config.config_path)
|
||||
return result
|
||||
|
||||
|
||||
def workspace_info_root(config: WorkspaceConfig) -> Path:
|
||||
return config.workspace_info_path.parent
|
||||
|
||||
@@ -3100,10 +3134,57 @@ def print_card_details(config: WorkspaceConfig, series_name: str, card_name: str
|
||||
print(f"tasks\t{' '.join(task_names(target_path))}")
|
||||
|
||||
|
||||
def available_series_hint(config: WorkspaceConfig) -> str:
|
||||
names = sorted(
|
||||
set(workspace_series_manifests(config))
|
||||
| {path.name for path in source_series_directories(config)}
|
||||
| {path.name for path in series_directories(config)}
|
||||
)
|
||||
return ", ".join(names)
|
||||
|
||||
|
||||
def use_series_default(config: WorkspaceConfig, series_name: str) -> dict[str, str]:
|
||||
series_id = slug_value(series_name, "series")
|
||||
if not series_exists(config, series_id):
|
||||
hint = available_series_hint(config)
|
||||
suffix = f" Available: {hint}" if hint else ""
|
||||
raise SystemExit(f"Missing series '{series_name}'.{suffix}")
|
||||
return update_config_defaults(config, {"series": series_id})
|
||||
|
||||
|
||||
def use_card_default(config: WorkspaceConfig, selector: list[str]) -> dict[str, str]:
|
||||
if len(selector) == 1:
|
||||
series_name = config.defaults.get("series")
|
||||
if not series_name:
|
||||
raise SystemExit("Missing default series. Use: ./rvctl series use inf")
|
||||
card_name = selector[0]
|
||||
updates_series = False
|
||||
elif len(selector) == 2:
|
||||
series_name = slug_value(selector[0], "series")
|
||||
card_name = selector[1]
|
||||
updates_series = True
|
||||
else:
|
||||
raise SystemExit("Use: ./rvctl card use <card> or ./rvctl card use <series> <card>")
|
||||
|
||||
if not series_exists(config, series_name):
|
||||
hint = available_series_hint(config)
|
||||
suffix = f" Available: {hint}" if hint else ""
|
||||
raise SystemExit(f"Missing series '{series_name}'.{suffix}")
|
||||
|
||||
card_info = resolve_card_info(config, series_name, card_name)
|
||||
updates = {"card": card_info.card_id}
|
||||
if updates_series:
|
||||
updates = {"series": series_name, "card": card_info.card_id}
|
||||
return update_config_defaults(config, updates)
|
||||
|
||||
|
||||
def run_series(config: WorkspaceConfig, args: argparse.Namespace) -> None:
|
||||
if args.series_command == "list":
|
||||
print_series(config)
|
||||
return
|
||||
if args.series_command == "use":
|
||||
print_key_values(use_series_default(config, args.series))
|
||||
return
|
||||
if args.series_command == "show":
|
||||
print_series_details(config, args.series)
|
||||
return
|
||||
@@ -3143,6 +3224,13 @@ def run_series(config: WorkspaceConfig, args: argparse.Namespace) -> None:
|
||||
raise SystemExit(f"Unsupported series cards tasks command: {args.tasks_command}")
|
||||
|
||||
|
||||
def run_card(config: WorkspaceConfig, args: argparse.Namespace) -> None:
|
||||
if args.card_command == "use":
|
||||
print_key_values(use_card_default(config, args.selector))
|
||||
return
|
||||
raise SystemExit(f"Unsupported card command: {args.card_command}")
|
||||
|
||||
|
||||
def resolve_task_command_selector(
|
||||
config: WorkspaceConfig,
|
||||
values: list[str],
|
||||
@@ -3736,7 +3824,8 @@ def print_main_overview(config_path: Path) -> None:
|
||||
[
|
||||
["show-config", "", "show resolved paths and Git defaults"],
|
||||
["workspace", "show|sync", "show or update meta/workspace-info"],
|
||||
["series", "list|cards|fetch|tasks", "work with series, cards and tasks"],
|
||||
["series", "list|use|cards|fetch|tasks", "work with series, cards and tasks"],
|
||||
["card", "use [series] card", "set the default card, optionally with the default series"],
|
||||
["tasks", "list|show|switch", "shortcut for tasks in the default card"],
|
||||
["env", "list|sync|build", "manage rv32i/host container environment"],
|
||||
["debug", "rv32i|host [selector]", "open nvim + gdb in the selected container profile"],
|
||||
@@ -3757,12 +3846,14 @@ def print_main_overview(config_path: Path) -> None:
|
||||
["1", "./rvctl tokens compare", "compare repo remotes with tokens.json"],
|
||||
["2", "./rvctl workspace sync", "clone or update workspace-info"],
|
||||
["3", "./rvctl series list", "choose a series"],
|
||||
["4", "./rvctl series cards list inf", "choose a card"],
|
||||
["5", "./rvctl series cards fetch inf bss", "fetch card and prepare r1a"],
|
||||
["6", "./rvctl tasks list", "list tasks from the default card"],
|
||||
["7", "./rvctl tasks switch 4", "switch to the answer branch for task 4"],
|
||||
["8", "./rvctl debug rv32i 4", "debug task 4 in RV32I/Hazard3"],
|
||||
["9", "./rvctl debug host 4", "debug task 4 natively in a host container"],
|
||||
["4", "./rvctl series use inf", "set the default series"],
|
||||
["5", "./rvctl series cards list inf", "choose a card"],
|
||||
["6", "./rvctl card use bss", "set the default card"],
|
||||
["7", "./rvctl series cards fetch inf bss", "fetch card and prepare r1a"],
|
||||
["8", "./rvctl tasks list", "list tasks from the default card"],
|
||||
["9", "./rvctl tasks switch 4", "switch to the answer branch for task 4"],
|
||||
["10", "./rvctl debug rv32i 4", "debug task 4 in RV32I/Hazard3"],
|
||||
["11", "./rvctl debug host 4", "debug task 4 natively in a host container"],
|
||||
],
|
||||
)
|
||||
print()
|
||||
@@ -3914,6 +4005,11 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
tasks_short_switch_parser.add_argument("--branch", help="Override the branch name.")
|
||||
tasks_short_switch_parser.add_argument("--dry-run", action="store_true", help="Print plan without switching branches.")
|
||||
|
||||
card_parser = subparsers.add_parser("card", help="Manage the default card selector.")
|
||||
card_subparsers = card_parser.add_subparsers(dest="card_command", required=True)
|
||||
card_use_parser = card_subparsers.add_parser("use", help="Set the default card, optionally with the default series.")
|
||||
card_use_parser.add_argument("selector", nargs="+", help="Use '<card>' or '<series> <card>', for example 'bss' or 'inf bss'.")
|
||||
|
||||
tmux_parser = subparsers.add_parser(
|
||||
"tmux-container",
|
||||
help="Create a tmux session with pane 0 running the container shell for a selected card.",
|
||||
@@ -3959,6 +4055,9 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
|
||||
series_subparsers.add_parser("list", help="List available series.")
|
||||
|
||||
series_use_parser = series_subparsers.add_parser("use", help="Set the default series.")
|
||||
series_use_parser.add_argument("series", help="Series id, for example 'inf'.")
|
||||
|
||||
series_show_parser = series_subparsers.add_parser("show", help="Show one series.")
|
||||
series_show_parser.add_argument("series", help="Series id, for example 'inf'.")
|
||||
|
||||
@@ -4138,7 +4237,7 @@ def main() -> int:
|
||||
parser = build_parser()
|
||||
args = parser.parse_args()
|
||||
config = load_config(args.config)
|
||||
if args.command in {"list-series", "list-cards", "series", "tasks", "tmux-container", "submission", "debug", "run", "shell"}:
|
||||
if args.command in {"list-series", "list-cards", "series", "card", "tasks", "tmux-container", "submission", "debug", "run", "shell"}:
|
||||
ensure_workspace_info(config)
|
||||
|
||||
if args.command == "show-config":
|
||||
@@ -4168,6 +4267,9 @@ def main() -> int:
|
||||
if args.command == "tasks":
|
||||
run_tasks(config, args)
|
||||
return 0
|
||||
if args.command == "card":
|
||||
run_card(config, args)
|
||||
return 0
|
||||
if args.command == "tmux-container":
|
||||
run_tmux_container(config, args)
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user