Add default series and card commands
This commit is contained in:
@@ -325,6 +325,7 @@ inf 3 0
|
|||||||
Po wybraniu serii `inf` wylistuj karty:
|
Po wybraniu serii `inf` wylistuj karty:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
./rvctl series use inf
|
||||||
./rvctl series cards list 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`.
|
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
|
```bash
|
||||||
|
./rvctl card use bss
|
||||||
./rvctl series cards fetch inf 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:
|
Karty trafiają do `series` w workspace:
|
||||||
|
|
||||||
```text
|
```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
|
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
|
```bash
|
||||||
./rvctl tasks list
|
./rvctl tasks list
|
||||||
|
|||||||
@@ -211,8 +211,11 @@ Komendy:
|
|||||||
- `list-series`
|
- `list-series`
|
||||||
- `list-cards [series]`
|
- `list-cards [series]`
|
||||||
- `series list`
|
- `series list`
|
||||||
|
- `series use SERIES`
|
||||||
- `series show SERIES`
|
- `series show SERIES`
|
||||||
- `series fetch SERIES [--dry-run]`
|
- `series fetch SERIES [--dry-run]`
|
||||||
|
- `card use CARD`
|
||||||
|
- `card use SERIES CARD`
|
||||||
- `series cards list SERIES`
|
- `series cards list SERIES`
|
||||||
- `series cards show SERIES CARD`
|
- `series cards show SERIES CARD`
|
||||||
- `series cards fetch SERIES CARD`
|
- `series cards fetch SERIES CARD`
|
||||||
@@ -313,6 +316,30 @@ Przykład:
|
|||||||
./rvctl series list
|
./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`
|
## `series show SERIES`
|
||||||
|
|
||||||
Pokazuje szczegóły jednej serii.
|
Pokazuje szczegóły jednej serii.
|
||||||
@@ -373,6 +400,38 @@ Przykład:
|
|||||||
./rvctl series cards list inf
|
./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`
|
## `series cards show SERIES CARD`
|
||||||
|
|
||||||
Pokazuje szczegóły jednej karty.
|
Pokazuje szczegóły jednej karty.
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ używa starego fallbacku przez `original_series_root`.
|
|||||||
```bash
|
```bash
|
||||||
./rvctl tokens compare
|
./rvctl tokens compare
|
||||||
./rvctl series list
|
./rvctl series list
|
||||||
|
./rvctl series use inf
|
||||||
./rvctl series cards list inf
|
./rvctl series cards list inf
|
||||||
|
./rvctl card use bss
|
||||||
./rvctl series cards fetch inf bss
|
./rvctl series cards fetch inf bss
|
||||||
./rvctl tasks list
|
./rvctl tasks list
|
||||||
./rvctl tasks switch 1
|
./rvctl tasks switch 1
|
||||||
@@ -62,6 +64,15 @@ Pokazuje informacje o serii.
|
|||||||
./rvctl series show inf
|
./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
|
## Karty
|
||||||
|
|
||||||
### `series cards list SERIES`
|
### `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
|
Pierwsza kolumna jest krótką nazwą karty. Pełna nazwa repo zostaje w drugiej
|
||||||
kolumnie.
|
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`
|
### `series cards fetch SERIES CARD`
|
||||||
|
|
||||||
Pobiera albo aktualizuje jedną kartę w workspace. `CARD` może być krótką nazwą
|
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:
|
def workspace_info_root(config: WorkspaceConfig) -> Path:
|
||||||
return config.workspace_info_path.parent
|
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))}")
|
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:
|
def run_series(config: WorkspaceConfig, args: argparse.Namespace) -> None:
|
||||||
if args.series_command == "list":
|
if args.series_command == "list":
|
||||||
print_series(config)
|
print_series(config)
|
||||||
return
|
return
|
||||||
|
if args.series_command == "use":
|
||||||
|
print_key_values(use_series_default(config, args.series))
|
||||||
|
return
|
||||||
if args.series_command == "show":
|
if args.series_command == "show":
|
||||||
print_series_details(config, args.series)
|
print_series_details(config, args.series)
|
||||||
return
|
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}")
|
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(
|
def resolve_task_command_selector(
|
||||||
config: WorkspaceConfig,
|
config: WorkspaceConfig,
|
||||||
values: list[str],
|
values: list[str],
|
||||||
@@ -3736,7 +3824,8 @@ def print_main_overview(config_path: Path) -> None:
|
|||||||
[
|
[
|
||||||
["show-config", "", "show resolved paths and Git defaults"],
|
["show-config", "", "show resolved paths and Git defaults"],
|
||||||
["workspace", "show|sync", "show or update meta/workspace-info"],
|
["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"],
|
["tasks", "list|show|switch", "shortcut for tasks in the default card"],
|
||||||
["env", "list|sync|build", "manage rv32i/host container environment"],
|
["env", "list|sync|build", "manage rv32i/host container environment"],
|
||||||
["debug", "rv32i|host [selector]", "open nvim + gdb in the selected container profile"],
|
["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"],
|
["1", "./rvctl tokens compare", "compare repo remotes with tokens.json"],
|
||||||
["2", "./rvctl workspace sync", "clone or update workspace-info"],
|
["2", "./rvctl workspace sync", "clone or update workspace-info"],
|
||||||
["3", "./rvctl series list", "choose a series"],
|
["3", "./rvctl series list", "choose a series"],
|
||||||
["4", "./rvctl series cards list inf", "choose a card"],
|
["4", "./rvctl series use inf", "set the default series"],
|
||||||
["5", "./rvctl series cards fetch inf bss", "fetch card and prepare r1a"],
|
["5", "./rvctl series cards list inf", "choose a card"],
|
||||||
["6", "./rvctl tasks list", "list tasks from the default card"],
|
["6", "./rvctl card use bss", "set the default card"],
|
||||||
["7", "./rvctl tasks switch 4", "switch to the answer branch for task 4"],
|
["7", "./rvctl series cards fetch inf bss", "fetch card and prepare r1a"],
|
||||||
["8", "./rvctl debug rv32i 4", "debug task 4 in RV32I/Hazard3"],
|
["8", "./rvctl tasks list", "list tasks from the default card"],
|
||||||
["9", "./rvctl debug host 4", "debug task 4 natively in a host container"],
|
["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()
|
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("--branch", help="Override the branch name.")
|
||||||
tasks_short_switch_parser.add_argument("--dry-run", action="store_true", help="Print plan without switching branches.")
|
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_parser = subparsers.add_parser(
|
||||||
"tmux-container",
|
"tmux-container",
|
||||||
help="Create a tmux session with pane 0 running the container shell for a selected card.",
|
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_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 = series_subparsers.add_parser("show", help="Show one series.")
|
||||||
series_show_parser.add_argument("series", help="Series id, for example 'inf'.")
|
series_show_parser.add_argument("series", help="Series id, for example 'inf'.")
|
||||||
|
|
||||||
@@ -4138,7 +4237,7 @@ def main() -> int:
|
|||||||
parser = build_parser()
|
parser = build_parser()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
config = load_config(args.config)
|
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)
|
ensure_workspace_info(config)
|
||||||
|
|
||||||
if args.command == "show-config":
|
if args.command == "show-config":
|
||||||
@@ -4168,6 +4267,9 @@ def main() -> int:
|
|||||||
if args.command == "tasks":
|
if args.command == "tasks":
|
||||||
run_tasks(config, args)
|
run_tasks(config, args)
|
||||||
return 0
|
return 0
|
||||||
|
if args.command == "card":
|
||||||
|
run_card(config, args)
|
||||||
|
return 0
|
||||||
if args.command == "tmux-container":
|
if args.command == "tmux-container":
|
||||||
run_tmux_container(config, args)
|
run_tmux_container(config, args)
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
Reference in New Issue
Block a user