Support directory tasks in cards

This commit is contained in:
mpabi
2026-04-29 20:03:42 +02:00
parent b3be495afb
commit cb1fc4d450
4 changed files with 49 additions and 24 deletions
+4 -4
View File
@@ -351,10 +351,10 @@ karcie z `workspace.json`, czyli tutaj na `inf bss`:
Przykładowy wynik: Przykładowy wynik:
```text ```text
inf bss task1_bss ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task1_bss ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task1_bss.s
inf bss task2_data ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task2_data ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task2_data.s
inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task3_stack_unused.s
inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task4_stack_strlen.s
``` ```
Przełącz się na wybrane zadanie. `rvctl` bierze login ucznia ze store tokenów, Przełącz się na wybrane zadanie. `rvctl` bierze login ucznia ze store tokenów,
+2 -1
View File
@@ -431,7 +431,8 @@ Przykład:
## `series cards tasks list SERIES CARD` ## `series cards tasks list SERIES CARD`
Listuje zadania z `src/tasks` pobranej karty. Listuje zadania pobranej karty. `rvctl` rozpoznaje pliki lub katalogi `task*`
w `src/tasks`, a także katalogi `task*` bezpośrednio w korzeniu karty.
Argumenty: Argumenty:
+6 -4
View File
@@ -131,6 +131,8 @@ Do codziennej pracy z domyślną kartą można używać krótszego namespace `ta
### `series cards tasks list SERIES CARD` ### `series cards tasks list SERIES CARD`
Listuje zadania dostępne w konkretnej karcie. Listuje zadania dostępne w konkretnej karcie.
`rvctl` rozpoznaje zadania zapisane jako pliki lub katalogi `task*` w
`src/tasks`, a także katalogi `task*` bezpośrednio w korzeniu karty.
```bash ```bash
./rvctl series cards tasks list inf bss ./rvctl series cards tasks list inf bss
@@ -145,10 +147,10 @@ Skrót dla domyślnej karty:
Przykładowy wynik: Przykładowy wynik:
```text ```text
inf bss task1_bss ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task1_bss ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task1_bss.s
inf bss task2_data ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task2_data ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task2_data.s
inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task3_stack_unused.s
inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task4_stack_strlen.s
``` ```
### `series cards tasks show SERIES CARD TASK` ### `series cards tasks show SERIES CARD TASK`
+37 -15
View File
@@ -53,6 +53,12 @@ class WorkspaceConfig:
git: GitConfig git: GitConfig
@dataclass(frozen=True)
class TaskEntry:
name: str
path: Path
SCOPE_FIELDS = [ SCOPE_FIELDS = [
("a", "activitypub"), ("a", "activitypub"),
("A", "admin"), ("A", "admin"),
@@ -2623,16 +2629,31 @@ def print_key_values(values: dict[str, str]) -> None:
print(f"{key}\t{value}") print(f"{key}\t{value}")
def task_names(card_path: Path) -> list[str]: def task_name_from_path(path: Path) -> str:
if path.is_file():
return path.stem
return path.name
def task_entries(card_path: Path) -> list[TaskEntry]:
entries: dict[str, TaskEntry] = {}
task_root = card_path / "src" / "tasks" task_root = card_path / "src" / "tasks"
if not task_root.is_dir(): if task_root.is_dir():
return [] for path in sorted(task_root.iterdir()):
names = { name = task_name_from_path(path)
path.stem if (path.is_file() or path.is_dir()) and name.startswith("task"):
for path in task_root.iterdir() entries[name] = TaskEntry(name=name, path=path)
if path.is_file() and path.stem.startswith("task")
} for path in sorted(card_path.iterdir()):
return sorted(names) name = task_name_from_path(path)
if (path.is_file() or path.is_dir()) and name.startswith("task"):
entries.setdefault(name, TaskEntry(name=name, path=path))
return [entries[name] for name in sorted(entries)]
def task_names(card_path: Path) -> list[str]:
return [entry.name for entry in task_entries(card_path)]
def task_branch_part(task_name: str) -> str: def task_branch_part(task_name: str) -> str:
@@ -2733,22 +2754,23 @@ def set_branch_upstream(repo_path: Path, branch_name: str, remote_name: str, dry
def print_card_tasks(config: WorkspaceConfig, series_name: str, card_name: str) -> None: def print_card_tasks(config: WorkspaceConfig, series_name: str, card_name: str) -> None:
card_path = resolve_workspace_card_path(config, series_name, card_name) card_path = resolve_workspace_card_path(config, series_name, card_name)
for task_name in task_names(card_path): for entry in task_entries(card_path):
print(f"{series_name}\t{card_label_from_repo_name(card_path.name)}\t{task_name}\t{card_path / 'src' / 'tasks'}") print(f"{series_name}\t{card_label_from_repo_name(card_path.name)}\t{entry.name}\t{entry.path}")
def print_card_task(config: WorkspaceConfig, series_name: str, card_name: str, task_name: str) -> None: def print_card_task(config: WorkspaceConfig, series_name: str, card_name: str, task_name: str) -> None:
card_path = resolve_workspace_card_path(config, series_name, card_name) card_path = resolve_workspace_card_path(config, series_name, card_name)
matches = [name for name in task_names(card_path) if name == task_name or task_name in name] matches = [entry for entry in task_entries(card_path) if entry.name == task_name or task_name in entry.name]
if not matches: if not matches:
raise SystemExit(f"Missing task '{task_name}' in card: {card_path}") raise SystemExit(f"Missing task '{task_name}' in card: {card_path}")
if len(matches) > 1: if len(matches) > 1:
raise SystemExit(f"Ambiguous task '{task_name}'. Matches: {', '.join(matches)}") raise SystemExit(f"Ambiguous task '{task_name}'. Matches: {', '.join(entry.name for entry in matches)}")
task_entry = matches[0]
print(f"series\t{series_name}") print(f"series\t{series_name}")
print(f"card\t{card_label_from_repo_name(card_path.name)}") print(f"card\t{card_label_from_repo_name(card_path.name)}")
print(f"task\t{matches[0]}") print(f"task\t{task_entry.name}")
print(f"card_path\t{card_path}") print(f"card_path\t{card_path}")
print(f"task_root\t{card_path / 'src' / 'tasks'}") print(f"task_path\t{task_entry.path}")
def switch_card_task( def switch_card_task(