# RV Launcher Launcher do workspace `rv`. - `workspace.json` trzyma sciezki repo oryginalnych, workspace i tools - `rvctl.py` zawiera implementacje CLI - `rvctl` listuje serie i karty - szczegolowy opis CLI jest w `doc/rvctl.md` - model tokenow i synchronizacji repo <-> store jest w `doc/tokens.md` ## Model katalogow Repo oryginalne trzymamy poza workspace: ```bash ~/dev/edu/repos/rv ``` Workspace sluzy do klonow roboczych i cwiczen: ```bash ~/dev/workspace/rv ``` Typowy uklad: ```text ~/dev/edu/repos/rv/rv-launcher ~/dev/edu/repos/rv/rv32i-hazard3-env ~/dev/edu/repos/rv/series// ~/dev/workspace/rv/tools/rv-launcher ~/dev/workspace/rv/tools/rv32i-hazard3-env ~/dev/workspace/rv/series// ``` Launcher szuka `rv32i-hazard3-env` najpierw w workspace, a jesli nie znajdzie klona roboczego, moze uzyc repo oryginalnego z `~/dev/edu/repos/rv`. Karty pracy tez sa rozdzielone: - `~/dev/edu/repos/rv/series/...` to checkouty zrodlowe, nad ktorymi pracujemy - `~/dev/workspace/rv/series/...` to klony testowe pobierane z Gitea Launcher wykonuje `list-series`, `list-cards`, `submission` i `tmux-container` na kartach z workspace, nie na repo zrodlowych. ## Przygotowanie katalogu Repo treningowe launchera trzymaj pod: ```bash ~/dev/workspace/rv/tools/rv-launcher ``` Bootstrap bez `git clone`: ```bash mkdir -p ~/dev/workspace/rv/tools mkdir -p ~/dev/workspace/rv/tools/rv-launcher cd ~/dev/workspace/rv/tools/rv-launcher git init ``` Glowne pliki CLI: ```bash ./rvctl rvctl.py ``` `rvctl` jest jedynym publicznym entrypointem. `rvctl.py` jest implementacja uruchamiana przez wrapper i nie wymaga osobnego wywolywania przez ucznia. Uruchomienie bez argumentow pokazuje tabelaryczny skrot komend: ```bash ./rvctl ./rvctl tokens ``` ## Autoryzacja Masz dwie drogi. ### Droga 1: remote `r1` z tokenem w URL To jest wariant dydaktyczny, jesli uczen ma cwiczyc reczne dodawanie remota z tokenem do konkretnego zdalnego endpointu. Jesli launcher zobaczy URL w formacie `http://LOGIN:TOKEN@...`, mozesz zapisac ten token lokalnie komenda `tokens sync remote r1`. Przyklad: ```bash git remote add r1 http://u1:TOKEN@77.90.8.171:3001/edu-tools/rv-launcher.git git fetch r1 main git switch --track -c main r1/main ``` ### Droga 2: lokalny `tokens/tokens.json` To jest wariant alternatywny, wygodniejszy wtedy, gdy launcher ma sam wykonywac `clone`, `fetch` i `push`, albo gdy uzytkownik po zajeciach chce pracowac juz na wlasnych repo bez wpisywania tokena do kazdego remota. Przed operacjami wymagajacymi autoryzacji dodaj lokalny token do: ```bash ~/dev/workspace/rv/tokens/tokens.json ``` Minimalny format: ```json { "version": 3, "tokens": [ { "id": "r1", "value": "TU_WSTAW_TOKEN", "server": { "type": "gitea", "endpoint": "http://77.90.8.171:3001", "scheme": "http", "host": "77.90.8.171", "port": 3001 }, "user": "u1", "org": "edu-tools", "repo": "rv-launcher" } ] } ``` Pelny schemat pliku jest w `doc/tokens.schema.json`. Plik powinien byc lokalny, niewersjonowany i miec prawa `600`. Przyklad: ```bash mkdir -p ~/dev/workspace/rv/tokens chmod 700 ~/dev/workspace/rv/tokens chmod 600 ~/dev/workspace/rv/tokens/tokens.json ``` Jesli token jest trzymany tylko w `tokens/tokens.json`, remote `r1` moze byc zapisany bez sekretu: ```bash git remote add r1 http://77.90.8.171:3001/edu-tools/rv-launcher.git ``` Podstawowe komendy tokenow: ```bash ./rvctl tokens scan ./rvctl tokens compare ./rvctl tokens list store ./rvctl tokens list remote ./rvctl tokens sync remote r1 ./rvctl tokens update r1 ./rvctl tokens sync store r1 ./rvctl tokens remove store r1 ./rvctl tokens remove remote r1 ./rvctl tokens add r1 ./rvctl tokens read ./rvctl tokens stats --repo ~/dev/workspace/rv/series/inf/03 ``` `tokens scan` wypisuje diagnostyczny skan git remotes i niczego nie zapisuje: pokazuje URL-e typu `auth`, `plain` i `unsupported`. `tokens compare` wypisuje tabele `tokens` i niczego nie zapisuje: jeden wiersz na logiczny remote tokena. `tokens list store|remote|both` wypisuje jedno zrodlo bez porownywania. `tokens.json` synchronizujemy z repo `rv-launcher`; remotes kart pracy i odpowiedzi sa generowane jako pochodne tego ustawienia. `token_ref` laczy nazwe tokena z markerem po prawej stronie: `*` oznacza, ze remote i `tokens.json` sa zgodne, `R` oznacza token tylko w remote, a `S` token tylko w `tokens.json`. Kolumny `scope`, `org` i `repo` sa maskami uprawnien; bez zgodnego wpisu maja wartosc `?????????`, `?????` albo `????`. Zapis z remote do `tokens.json` robi `tokens sync remote r1`. Odczyt `valid` i uprawnien z API robi `tokens update r1`. Zapis z `tokens.json` do remota robi `tokens sync store r1`. Usuniecie wpisu robi `tokens remove store r1`, a usuniecie git remota `tokens remove remote r1`. Kolumna `valid` oznacza, czy token zostal zaakceptowany przez API teraz. Jesli przy tokenie w `tokens.json` zapiszesz `expires_at`, `valid` moze pokazac date wygasniecia; bez daty poprawny token pokazuje `forever`. ## Fetch i switch Domyslna galaz launchera to `main`. Wariant preferowany przez `r1`: ```bash git fetch r1 main git switch --track -c main r1/main git pull --ff-only r1 main ``` Jesli repo bylo sklonowane klasycznie i pracujesz przez `origin`, odpowiednikiem jest: ```bash git fetch origin main git switch main git pull --ff-only origin main ``` Jesli chcesz wejsc na inna galaz, na przyklad `feat/x`, uzyj: ```bash git fetch r1 feat/x git switch --track -c feat/x r1/feat/x ``` Wariant przez `origin`: ```bash git fetch origin feat/x git switch --track -c feat/x origin/feat/x ``` ## Repo odpowiedzi kart pracy Model pracy kart jest taki: - `r1` wskazuje repo z materialem z `edu-inf` - `a1` wskazuje wspolne repo odpowiedzi w `zsl-inf` - kazdy uczen wysyla swoja prace na branch o nazwie swojego nicku Repo odpowiedzi nie zawiera nicku w nazwie. Launcher buduje je w formacie: ```text zsl-inf/-- ``` Przyklad: ```text zsl-inf/lab-rv32i-strlen-bss-data-stack-4i-2026-04-26 ``` Przyklad planu dla ucznia `u1`: ```bash ./rvctl submission inf 03 --class 4i --nick u1 ``` Przyklad konfiguracji remote'ow w repo karty: ```bash ./rvctl submission inf 03 --class 4i --nick u1 --apply ``` Launcher wtedy: - czyta URL zrodlowego repo z `origin` aktualnej karty i ustawia go jako `r1` - bierze basename tego repo z `edu-inf` i z niego buduje nazwe repo odpowiedzi - wylicza repo odpowiedzi w `zsl-inf` i ustawia je jako `a1` - proponuje branch ucznia, na przyklad `u1` Typowy wynik to: ```text source_repo edu-inf/lab-rv32i-strlen-bss-data-stack source_remote r1 answer_remote a1 answer_repo zsl-inf/lab-rv32i-strlen-bss-data-stack-4i-2026-04-26 student_branch u1 ``` ## Wariant alternatywny: `git clone` Jesli celem nie jest cwiczenie `remote add` i `fetch`, repo treningowe mozna tez sklonowac klasycznie: ```bash mkdir -p ~/dev/workspace/rv/tools cd ~/dev/workspace/rv/tools git clone http://77.90.8.171:3001/edu-tools/rv-launcher.git cd rv-launcher ``` ## Podstawowe komendy Przyklady: ```bash ./rvctl ./rvctl show-config ./rvctl list-series ./rvctl list-cards inf ./rvctl tokens ./rvctl submission inf 03 --class 4i --nick u1 ./rvctl tmux-container inf 03 --dry-run ./rvctl tmux-container inf 03 --session rv-inf03 --attach ``` Skrypt nie trzyma listy kart w JSON-ie. Czyta `series/*/*` z `series_root`.