Cu ceva timp în urmă, am decis să învăț puțin Rust. Am cumpărat o carte, am deschis-o luni mai târziu și am început un mic proiect secundar: portarea pachetului meu R saperlipopette la terminal scriind un CLI cu Rust. Apoi mi-am pierdut aburul și am renunțat la proiect. Acum, predarea mai multor Git cu saperlipopette mă face să fac același lucru în afara lui R, pentru a ajunge la mai mulți cursanți. Și între timp, deși am sentimente contradictorii despre asta, mi-am dat seama că utilizarea unui LLM, în special Claude Code (Opus 4.6), m-ar ajuta să-mi trec CLI peste linia de sosire!
Ce avea deja CLI-ul meu
Proiectul CLI avea deja câteva exerciții, toate „Oh rahat, Git!” exerciții de la saperlipopette. Avea un nume prost: ohcrabgit, un joc de cuvinte bazat pe „Oh crap, Git!” iar pe sigla lui Rust fiind un crab. Cu siguranță nu este ceva ce doriți să introduceți într-un terminal din nou și din nou.
Interfața sa a fost următoarea:
- Ați crea un exercițiu într-un folder tastând o comandă în terminal.
- Apoi ai deschide acel folder și ai citi fișierul
instructions.txtsă știi ce să faci, apoi dosarultip.txtîn cazul în care ai nevoie de indicii.
Acea interfață am vrut să o păstrez, pentru că este destul de simplă și ar funcționa indiferent de ce folosesc oamenii de obicei pentru a lucra cu Git. Cu siguranță folosesc Git undeva unde pot citi fișiere text.
Avea o infrastructură internă: de exemplu, un fișier numit git.rs care avea unele funcții de utilitate precum init_playground sau create_branch. A folosit Rust crate git2 în special, pentru aspectele Git.
Fiecare linie fusese scrisă cu minuțiozitate de mine, cu ajutorul unui motor de căutare și a mesajelor de eroare utile de la compilator. 😅
Ce mi-am dorit pentru CLI
Nu mai eram atât de interesat să scriu eu însumi codul Rust. Poate într-o zi asta va fi relevant pentru munca mea, dar nu este acum. Am vrut să dezvolt CLI pentru ca acesta să se potrivească cu caracteristicile lui saperlipopette: mai multe exerciții și traduceri ale instrucțiunilor/sfaturilor în franceză și spaniolă. Cu acel produs final, ar trebui să pot preda aceleași ateliere ca înainte, dar folosind CLI în loc de saperlipopette dacă publicul meu nu ar fi doar utilizatori R.
De asemenea, am vrut să îmbunătățesc formatarea ajutorului și instrucțiunile de instalare.
Proiectul a mers bine! Am un abonament Claude Code, îl sun pe Claude de la terminal, din cadrul Positron IDE. Rețineți că am atins limita de frecvență a unei sesiuni chiar înainte de a veni timpul pentru cursul meu de Pilates, așa că nu a fost prea rău să aștept. 🧘
Iată ce a fost produs în codul sursă zut și revizuit de mine, începătorul Rust, deci nu foarte profund:
- Îmbunătățiri ale formatării ajutorului. Am respins șirurile ANSI din cod și am cerut culori mai accesibile (nu sunt sigur că sunt cea mai bună alegere). Angajează-te.
- Am ales un nume mai bun pentru CLI, cuvântul blestemat francez „zut” („darn”). Claude a făcut redenumirea peste tot, ceea ce a fost mai ales leneș din partea mea. Angajează-te.
- Instrucțiunile de instalare urmează să ruleze
cargo install --git https://github.com/maelle/zutsugestie de Claude, deoarece publicul pentru instrumentul meu ar trebui să fie în mare parte dezvoltatori. Cred că voi vedea care sunt punctele dureroase când oamenii încearcă să-l instaleze pe diferite platforme… Commit. - CLI-ul oferă acum instrucțiuni și sfaturi în diferite limbi, în funcție de localitatea sistemului, de o variabilă de mediu sau de un indicator. Am cerut ca localitatea sistemului să fie implicită. În același flux de lucru, Claude a adăugat mai multe teste unitare, pe care nici măcar nu le-am cerut, și teste de integrare, pe care le-am cerut după ce am văzut că folderul de teste era gol. Angajează-te
- Toate exercițiile noi de la saperlipopette au fost portate pe zut în franceză, engleză și spaniolă și au fost clasificate în rezultatul de ajutor, precum și în documente (care în prezent este… README). Am încercat să le rulez, ceea ce duc la mici ajustări (linii goale la sfârșitul fișierelor) și ajustări mai mari (de exemplu, exercițiul git bisect din saperlipopette vă permite să rulați un script R, dar trebuia să devină un script shell pentru ca acesta să aibă sens în zut). Angajează-te.
- O remediere a erorilor, deoarece zut a funcționat doar… din folderul care conține sursa acestuia. 🤦 Angajați-vă.
Starea de zut
Pentru a instala zut:
cargo install --git https://github.com/maelle/zut
Pentru a vizualiza ajutor:
zut --help
a cărui ieșire este:
Create example Git messes to solve, inspired by https://ohshitgit.com/ Usage: zut(TARGET). In the exercise folder, open instructions.txt. Arguments: Name of the exercise Possible values: - time-machine: Oh shit, I did something terribly wrong, please tell me git has a magic time machine!?! - small-change: Oh shit, I committed and immediately realized I need to make one small change! - latest-message: Oh shit, I need to change the message on my last commit! - committed-to-main: Oh shit, I accidentally committed something to main that should have been on a brand new branch! - committed-to-wrong: Oh shit, I accidentally committed to the wrong branch! - undo-commit: Oh shit, I need to undo a commit from like 5 commits ago! - undo-file: Oh shit, I need to undo my changes to a file! - split-changes: Hey I'd like to split these changes to the same file into several commits! - clean-dir: Hey, how do I remove all my debugging left-over stuff at once? - conflict: Hey I'd like to see what merge conflicts look like! - rebase-i: Hey I'd like to make my commits in a branch look informative and smart! (interactive rebase) - reset: Hey I'd like to restart from scratch and reorganize my commits! (git reset --mixed) - bisect: Hey I'd like to find which commit introduced a bug! - log-deleted-file: I want to find which commit deleted a file! - log-deleted-line: I want to find which commit deleted a line! - revparse: I want to understand ancestry references like HEAD~5 and HEAD^^! - blame: I want to find who added a specific line and when! - worktree: I need to see what the project looked like at a certain version! (TARGET) Where to create the exercise directory. Default: temporary directory (default: tempdir) Options: --lang Language (default: auto-detected from system locale) (possible values: en, fr, es) -h, --help Print help (see a summary with '-h') -V, --version Print version Examples: zut small-change creates the small-change exercise folder in a temporary folder. zut latest-message .. creates the latest-message exercise folder in the parent of the current folder. Categories: Oh shit, Git!: time-machine, small-change, latest-message, committed-to-main, committed-to-wrong, undo-commit, undo-file Clean history: split-changes, clean-dir, conflict, rebase-i, reset Use history: bisect, log-deleted-file, log-deleted-line, revparse, blame, worktree
Pentru a crea exercițiul de mașină a timpului într-un folder temporar:
zut time-machine
Calea către folder este imprimată pe ecran, astfel încât să o puteți deschide, citi instructions.txt acolo și începeți să lucrați: în acea provocare a git reset --hard prea multe au fost rulate, așa că aveți nevoie git reflog pentru a salva un comis important.
Pentru a crea exercițiul de blamare într-un folder deasupra celui actual, în franceză:
zut blame .. --lang fr
În această provocare, trebuie să găsiți cine a comis o anumită linie într-un script. Dr Jekyll sau domnul Hyde? git blame va ajuta!
Nu în ultimul rând, dacă încercați să creați un exercițiu undeva unde există:
zut blame .. --lang fr
primesti:
Exercise folder already exists: ../exo-blame — delete it or choose a different target.
Concluzie: munca viitoare
Folosirea Claude Code m-a ajutat să port caracteristicile pachetului saperlipopette R la zut CLI. Următorii pași sunt ca eu să folosesc de fapt zut mai mult dincolo de testele pe care le-am făcut, pentru a prinde alte probleme. Să spunem că trebuie să predau din nou „Îmbunătățiți-vă fără durere istoria Git”, aș face toate exercițiile din nou la rând. Aș face asta în limbajul uman al atelierului.
De asemenea, aș putea îmbunătăți codul CLI pe baza feedback-ului utilizatorului și, să zicem, a feedback-ului de la Claude Code utilizând abilitățile post-dev/critical-code-reviewer (mulțumesc lui Mo pentru că mi-a spus despre asta!). Documentația ar putea folosi și ceva de lucru, în comparație cu saperlipopette, dar ca însoțitor la ateliere ar putea fi ok.
Pachetul saperlipopette în sine a fost trimis la rOpenSci software-ul peer-review, așa că mă aștept să se schimbe în bine. Când trebuie să port aceste modificări, în funcție de ceea ce sunt, aș putea recurge din nou la Claude Code.
