# RV Launcher Repo `rv-launcher` zawiera narzędzie do pracy ze wspólnym workspace EDU. W pierwszej kolejności służy ono do zarządzania tokenami; pozostałe funkcje obejmują pracę z kartami pracy i uruchamianie środowiska kontenerowego. Właściwym skryptem CLI jest wykonywalny plik `rvctl.py`. To on implementuje zarządzanie tokenami, listowanie serii i kart, przygotowanie repo odpowiedzi i start kontenera. Publicznym entrypointem dla użytkownika jest krótki wrapper `rvctl`: ```bash ./rvctl ``` Wrapper uruchamia: ```bash python3 rvctl.py "$@" ``` `rvctl.py` można też uruchomić bezpośrednio: ```bash ./rvctl.py ``` Lokalne ścieżki i domyślne ustawienia są trzymane w `workspace.json`. Publiczny opis wspólnego workspace, czyli serie, karty i wersje repozytoriów, jest w osobnym repo `edu-workspace/workspace-info`. ## Co robi narzędzie `rvctl` porządkuje pracę w trzech obszarach. 1. Zarządzanie tokenami Narzędzie obsługuje lokalny store `tokens/tokens.json`, porównuje go z git remotes i potrafi synchronizować token w obie strony. Szczegóły modelu, format pliku i opis komend są w `doc/tokens.md`. 2. Listowanie i pobieranie kart pracy `rvctl` czyta serie i karty z `meta/workspace-info`, zadania z pobranych kart, pomaga wybrać materiał do pracy oraz przygotowuje remotes potrzebne do repo odpowiedzi. Docelowy model namespace `series`, `cards` i `tasks` jest w `doc/series.md`. 3. Uruchamianie środowiska programistycznego w kontenerach Dla wybranej karty i zadania `rvctl` uruchamia osobne profile kontenerów: `rv32i` dla Hazard3/RISC-V oraz `host` dla natywnego debugowania C. Oba profile opierają się na `nvim`, `tmux` i debuggerze. Model komend jest w `doc/containers.md`. ## Model katalogów Podstawowym miejscem pracy użytkownika jest workspace: ```bash ~/dev/workspace/rv ``` Najpierw utwórz tylko katalog bazowy workspace i wejdź do niego: ```bash mkdir -p ~/dev/workspace/rv cd ~/dev/workspace/rv ``` Po tym kroku workspace istnieje, ale nie ma jeszcze katalogów narzędzi, tokenów ani kart: ```text ~/dev/workspace/rv ``` Potem wybierz jedną z dwóch dróg startu. ### Bez `tokens.json` Ten wariant jest dla sytuacji, w której token jest podany w URL-u git remota, a plik `tokens.json` ma powstać dopiero lokalnie. Etap 1: utwórz katalog launchera i wejdź do niego: ```bash mkdir -p ~/dev/workspace/rv/tools/rv-launcher cd ~/dev/workspace/rv/tools/rv-launcher ``` Etap 2: utwórz puste repo, dodaj remote `r1` z tokenem, pobierz branch i ustaw lokalny `main`: ```bash git init 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 ``` `r1` jest nazwą remota, z którego startujemy. `--track` ustawia lokalny branch `main` tak, aby śledził `r1/main`, dzięki czemu późniejsze `git pull` i `git push` wiedzą, z którym branchem zdalnym pracują. Po tym kroku w workspace jest już repo launchera: ```text ~/dev/workspace/rv └── tools └── rv-launcher ``` Repo `workspace-info` nie jest częścią `tools`. `rvctl` pobierze je automatycznie do `meta/workspace-info` przy pierwszej komendzie zależnej od manifestu, na przykład `series list`. Etap 3: wczytaj token z remota do lokalnego store: ```bash cd ~/dev/workspace/rv/tools/rv-launcher ./rvctl tokens sync remote r1 ./rvctl tokens update r1 ``` `tokens sync remote r1` przepisuje token z URL-a remota `r1` do lokalnego store. `tokens update r1` odpytuje Gitea API i uzupełnia metadane tokena: ważność, zakresy oraz uprawnienia w organizacji i repo. `rvctl` sam tworzy katalog `~/dev/workspace/rv/tokens`, jeżeli jeszcze go nie ma. Plik `tokens.json` dostaje prawa `600`, a katalog store prawa `700`. Po tym kroku workspace ma już `tokens.json`: ```text ~/dev/workspace/rv ├── tools │ └── rv-launcher └── tokens └── tokens.json ``` Etap 4: sprawdź, czy git remote i lokalny store widzą ten sam token: ```bash ./rvctl tokens compare ``` Przykładowy wydruk: ```text tokens item server proto host org repo user remote token_ref token valid scope org repo ---- ------ ----- ------------------ --------- ----------- ---- ------ --------- ------------ ------- --------- ------ ------ 1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 * e59cc...13be forever wwwwwwwww +++++ ++++ ``` Najważniejsze pola: - `remote` - nazwa git remota, tutaj `r1` - `token_ref` - lokalna nazwa tokena i marker zgodności po prawej stronie - `*` - token w remote i w `tokens.json` jest zgodny - `S` - token jest tylko w `tokens.json`; to jest normalne w trybie store-only - `R` - token jest tylko w git remote - `token` - zamaskowany sekret; `rvctl` nie wypisuje całego tokena - `valid`, `scope`, `org`, `repo` - metadane i uprawnienia pobrane przez `tokens update` Pełny opis tabeli tokenów jest w `doc/tokens.md`. ### Z `tokens.json` Ten wariant jest dla sytuacji, w której masz już gotowy plik `tokens.json`. Etap 1: skopiuj token store do workspace: ```bash mkdir -p ~/dev/workspace/rv/tokens cd ~/dev/workspace/rv cp /ścieżka/do/tokens.json tokens/tokens.json chmod 600 tokens/tokens.json ``` Po tym kroku workspace ma store tokenów, ale nie ma jeszcze launchera: ```text ~/dev/workspace/rv └── tokens └── tokens.json ``` Etap 2: wejdź do katalogu narzędzi i sklonuj `rv-launcher`: ```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 ``` Po `git clone` workspace wygląda tak: ```text ~/dev/workspace/rv ├── tools │ └── rv-launcher └── tokens └── tokens.json ``` Etap 3: sprawdź store i wpisz credentials ze store do remota `r1`: ```bash ./rvctl tokens list store ./rvctl tokens sync store r1 ``` `tokens list store` sprawdza, czy skopiowany `tokens.json` zawiera wpis dla remota `r1`. `tokens sync store r1` bierze token ze store i wpisuje credentials do git remota `r1`, tak aby kolejne operacje Git mogły używać tego tokena. Jeżeli po `git clone` repo ma tylko remote `origin` wskazujący to samo repo, `rvctl` automatycznie przemianuje go na `r1`. `list store` powinien pokazać token ze store: ```text tokens item source kind server proto host org repo user remote token valid ---- ------ ---- ------ ----- ---------------- --------- ----------- ---- ------ ------------ ------- 1 store auth gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 e59cc...13be forever ``` `sync store r1` wpisuje credentials do git remota: ```text repo_root /home/user/dev/workspace/rv/tools/rv-launcher remote r1 renamed_from origin server http://77.90.8.171:3001 user u1 id r1 status updated url http://77.90.8.171:3001/edu-tools/rv-launcher.git ``` Etap 4: odśwież metadane tokena i porównaj store z remote: ```bash ./rvctl tokens update r1 ./rvctl tokens compare ``` `tokens update r1` odpytuje Gitea API dla tokena ze store i odświeża jego metadane: ważność, zakresy oraz uprawnienia w organizacji i repo. `tokens compare` sprawdza potem, czy store i git remote wskazują ten sam token. `compare` powinien pokazać `*` przy `r1`, jeżeli remote i `tokens.json` są zgodne: ```text tokens item server proto host org repo user remote token_ref token valid ---- ------ ----- ---------------- --------- ----------- ---- ------ --------- ------------ ------- 1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 * e59cc...13be forever ``` Etap 5: po operacjach Git możesz usunąć sekret z `.git/config`, zostawiając token tylko w store: ```bash ./rvctl tokens rm remote r1 ./rvctl tokens compare ``` Po usunięciu remota `compare` pokazuje marker `S`, czyli token jest tylko w store: ```text tokens item server proto host org repo user remote token_ref token valid ---- ------ ----- ---------------- --------- ----------- ---- ------ --------- ------------ ------- 1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 S e59cc...13be forever ``` ## Kolejny krok: serie i karty pracy Po konfiguracji tokenów następnym elementem jest publiczny manifest wspólnego workspace. `rvctl` szuka go lokalnie w: ```text ~/dev/workspace/rv/meta/workspace-info ``` Manifest zawiera listę serii, kart, repozytoriów źródłowych, repozytoriów odpowiedzi i branchy. Nie zawiera tokenów ani lokalnych plików ucznia. Nie musisz pobierać go ręcznie. Pierwsza komenda zależna od manifestu, na przykład `series list`, automatycznie sklonuje repo `edu-workspace/workspace-info`, jeżeli lokalnej kopii jeszcze nie ma: ```bash ./rvctl series list ``` Jeżeli chcesz jawnie odświeżyć istniejący manifest, użyj: ```bash ./rvctl workspace sync ``` Przed pobieraniem kart warto jeszcze sprawdzić stan tokenów: ```bash ./rvctl tokens compare ``` Przykładowy wynik: ```text fiz 3 0 inf 3 0 ``` Po wybraniu serii `inf` wylistuj karty: ```bash ./rvctl series cards list inf ``` Przykładowy wynik zawiera krótką nazwę karty, pełną nazwę repo, status i tytuł: ```text 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: ```bash ./rvctl series cards fetch inf bss ``` Karty trafiają do `series` w workspace: ```text ~/dev/workspace/rv ├── meta │ └── workspace-info ├── tools │ └── rv-launcher ├── tokens │ └── tokens.json └── series └── inf └── lab-rv32i-strlen-bss-data-stack ``` `rvctl` pracuje na kartach z `series_root`, czyli na katalogu `~/dev/workspace/rv/series`. Po pobraniu karty `rvctl` przygotowuje też remote odpowiedzi `r1a`. Remote powstaje z tokena `r1` i wskazuje na repo pracy: ```text answer_remote r1a answer_org c2025-1a-inf answer_repo lab-rv32i-strlen-bss-data-stack answer_url http://77.90.8.171:3001/c2025-1a-inf/lab-rv32i-strlen-bss-data-stack.git ``` 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`: ```bash ./rvctl tasks list ``` Przykładowy wynik: ```text inf bss task1_bss ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task1_bss.c inf bss task2_data ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task2_data.c inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task3_stack_unused.c inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks/task4_stack_strlen.c ``` Przełącz się na wybrane zadanie. `rvctl` bierze login ucznia ze store tokenów, tworzy branch pracy w formacie `Ta` i ustawia mu upstream na `r1a/`: ```bash ./rvctl tasks switch 4 ``` Dla użytkownika `u1` i zadania `task4_stack_strlen` branch będzie miał nazwę: ```text u1T4a ``` ## Dokumentacja - `doc/rvctl.md` - techniczna dokumentacja CLI: wszystkie komendy, argumenty i przełączniki - `doc/tokens.md` - model tokenów, format `tokens/tokens.json` i synchronizacja remote <-> store - `doc/series.md` - docelowy model komend dla serii i kart pracy - `doc/containers.md` - docelowy model komend dla środowisk kontenerowych - `doc/workspace.md` - krótki opis konfiguracji workspace README jest tylko mapą projektu. Szczegóły operacyjne trzymamy w `doc/`, żeby nie dublować instrukcji w kilku miejscach.