Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3. La synchro et le lockfile

C’est ici que tout s’éclaire. Tu as un haw.toml du chapitre précédent. Maintenant tu vas lancer haw sync pour cloner la flotte pour de vrai, lire le lockfile qui la fige sur des commits exacts, prouver qu’elle est reproductible et — délibérément — casser quelque chose pour voir haw détecter la dérive.

Tout se clone ici en HTTPS sans authentification, donc tu peux vraiment lancer chaque commande au fil de ta lecture. Garde ouvert l’espace de travail my-first-stack du chapitre 2.

Syncing and pinning a fleet to a lockfile

La synchro clone la flotte ; le lockfile la fige sur des commits exacts — toute l’astuce de la reproductibilité.

🎯 Dans ce chapitre, tu vas apprendre à…

  • Lancer haw sync pour cloner la flotte et générer haw.lock.
  • Lire la flotte avec haw tree et haw status, et comprendre chaque colonne.
  • Lire les vrais champs du lockfile — rev (le SHA résolu), source-rev et branch.
  • Resynchroniser et confirmer que c’est idempotent — le lock, pas la branche, fait désormais foi.
  • Provoquer une dérive exprès et la détecter avec haw verify (exit 3), puis restaurer.

La boucle de composition complète que tu vas lancer : sync clone la flotte, puis tree / status la lisent et le lock l’épingle.

🔄 1. Sync — tout cloner et écrire le lock

Une seule commande matérialise l’arbre :

haw sync

haw résout le rev de chaque dépôt en un commit exact, le clone et — parce qu’il n’y a pas encore de lockfile — en écrit un. Tu verras la progression par dépôt et un récapitulatif. Ensuite, jette un œil autour de toi :

$ ls
haw.lock   haw.toml   hello-world/   spoon-knife/

Les voilà : deux clones Git réels et complets, plus un haw.lock tout neuf. Pas de sous-modules, pas de liens symboliques — tu pourrais faire cd hello-world && git log et c’est juste du Git.

Astuce : haw sync est idempotent. Relance-le et, comme le lock épingle déjà des SHA exacts, haw s’assure simplement que ton arbre correspond — aucune surprise, sans risque à répéter dans les scripts et la CI.

🔍 2. Explorer la flotte

Maintenant les commandes de lecture. D’abord, la forme des choses :

haw tree
haw.toml
└─ site
   ├─ hello-world  master  (https://github.com/octocat/Hello-World.git)
   └─ spoon-knife  main  (https://github.com/octocat/Spoon-Knife.git)

Voilà ton arbre stack → dépôt : la stack site, les deux dépôts en dessous, chacun avec son rev déclaré et son origine.

Maintenant le bilan de santé :

haw status
REPO         BRANCH                   HEAD       DIRTY  DRIFT
hello-world  master                    7fd1a60b   -      -
spoon-knife  main                      d0dd1f61   -      -

Lis les colonnes de gauche à droite : le dépôt, la branche sur laquelle il se trouve, son SHA HEAD court, si l’arbre de travail a des changements non committés (DIRTY) et si HEAD diffère du SHA verrouillé (DRIFT). Pour l’instant tout est propre et synchronisé — les tirets signifient « tout va bien ».

Astuce : Dans un terminal, tout est codé par couleur — noms de dépôts en cyan, revs en jaune, vert pour propre, rouge pour la dérive. Redirige la sortie n’importe où et elle bascule automatiquement en texte brut (elle respecte NO_COLOR), donc c’est compatible avec les scripts par défaut.

🔒 3. Lire le lockfile

Ouvre haw.lock dans ton éditeur. Chaque dépôt est épinglé à un SHA complet de 40 caractères dans son champ rev — le commit exact, pas le nom de branche — tandis que source-rev consigne ce que tu as demandé et branch consigne la branche d’où vient ce SHA :

# extrait — tes SHA seront différents
[[repo]]
name = "hello-world"
url = "https://github.com/octocat/Hello-World.git"
path = "hello-world"
rev = "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"   # le commit résolu — voici l'épingle
source-rev = "master"                               # ce que tu as déclaré dans haw.toml
branch = "master"                                   # la branche d'où ce SHA a été résolu
groups = ["core"]

Voilà toute l’astuce de la reproductibilité. Ton manifeste disait « master » (une cible mouvante), mais le lock a figé le commit exact que master pointait au moment où tu as synchronisé — c’est le SHA qui est maintenant dans rev. source-rev se souvient de ton intention (master) et branch se souvient d’où ça venait, donc haw peut plus tard re-résoudre si tu le demandes. Committe haw.lock aux côtés de haw.toml, et quiconque clone et lance haw sync obtient précisément ces commits — pas ce que master se trouve être aujourd’hui.

Ne l’édite pas à la main. haw.lock est généré. Tu le committes, mais tu changes l’intention dans haw.toml et tu laisses haw lock / haw sync régénérer le lock.

♻️ 4. Prouve que c’est reproductible — relance sync

haw sync

Parce que le lock existe, haw synchronise vers les SHA épinglés, pas vers là où les branches ont bougé. Relance haw status et tu verras la même flotte propre. C’est tout l’intérêt de l’idempotence : le lock, pas la branche, est désormais la source de vérité.

🧭 5. Vois la dérive de tes propres yeux

La reproductibilité n’est utile que si tu peux détecter quand l’arbre s’écarte de la référence. Provoquons cela exprès. Déplace un dépôt vers un commit différent à la main :

cd hello-world
git checkout HEAD~1     # recule d'un commit — maintenant HEAD ≠ le SHA verrouillé
cd ..

Demande à haw ce qu’il en pense :

haw status
REPO         BRANCH                   HEAD       DIRTY  DRIFT
hello-world  (detached)                553c2077   -      YES
spoon-knife  main                      d0dd1f61   -      -

La voilà — DRIFT: YES sur hello-world. Faire un checkout d’un commit précis détache aussi HEAD (d’où (detached) dans la colonne BRANCH), et son HEAD ne correspond plus au SHA verrouillé. haw status l’a signalé, mais pour la CI tu veux une commande qui échoue en cas de dérive. C’est verify :

haw verify

verify vérifie que l’arbre sur disque correspond à haw.lock et sort avec le code 3 quand ce n’est pas le cas — un garde-fou de dérive propre et scriptable. Vérifie le code de sortie :

haw verify; echo "code de sortie : $?"
  ✗ hello-world  drift (head != lock)
verify failed: 1 repo(s) diverge from haw.lock
exit code: 3

Ce code de sortie 3 est ce sur quoi un pipeline CI se cale : « l’arbre a dérivé du lock — arrête le build. » (Quand tout correspond, verify affiche verified: tree matches haw.lock (2 repos) et sort avec 0.)

Wide-eyed, shocked reaction

haw verify détectant la dérive dans la CI juste avant une release.

Maintenant remets-le en place. haw sync restaure chaque dépôt à son SHA verrouillé :

haw sync
haw verify; echo "code de sortie : $?"
verified: tree matches haw.lock (2 repos)
exit code: 0

Propre à nouveau. Tu viens de voir la boucle complète : déclarer → synchroniser → épingler → détecter la dérive → restaurer.

Tu viens de faire la boucle fondamentale. Déclarer l’intention, l’épingler, détecter la dérive et restaurer la référence — les quatre mêmes mouvements passent à l’échelle de deux dépôts octocat à une flotte de cent dépôts.

🙌 À toi de jouer

Prouve que le lockfile est vraiment la source de vérité :

  • Ouvre haw.lock et trouve le SHA épinglé de chaque dépôt dans son champ rev. Confirme que c’est un commit de 40 caractères, pas un nom de branche, et que source-rev montre toujours ce que tu as déclaré.
  • Fais dériver un dépôt exprès (cd hello-world && git checkout HEAD~1 && cd ..), lance haw verify; echo $?, et confirme que tu obtiens le code de sortie 3.
  • Lance haw sync pour restaurer, puis haw verify; echo $? à nouveau — retour à exit 0. Cet aller-retour, c’est la garantie de reproductibilité.

✅ Récapitulatif

  • haw sync clone chaque dépôt et écrit haw.lock — de vrais clones Git, sans sous-modules/liens symboliques. C’est idempotent.
  • haw tree montre la forme stack→dépôt ; haw status montre branche/HEAD/dirty/drift par dépôt.
  • haw.lock épingle chaque dépôt à un SHA exact de 40 caractères dans rev, avec source-rev (ton intention déclarée) et branch à côté — committe-le pour des rebuilds identiques octet pour octet.
  • Drift = HEAD diffère du lock. haw status le signale ; haw verify sort avec le code 3 en cas de dérive (ton garde-fou CI). haw sync restaure la référence.

👉 La suite

Tu sais composer et épingler une flotte — maintenant vivons dedans. Découvre le cockpit qui pilote tout ça au clavier → 4. Le cockpit TUI.