Projet

grab

Outil en ligne de commande qui pioche des outils individuels dans un monorepo pour les installer dans n'importe quel projet, sans sous-module ni copier-coller

Technologies utilisées

BashGit

Détails du projet

À propos du projet

Tout le monde traîne un dossier de scripts utiles recopiés de projet en projet. Avec le temps, ils divergent : une correction est appliquée à un endroit et nulle part ailleurs, et on ne sait plus quelle version est la bonne.

grab règle ça avec une seule règle : le monorepo fait foi, et chaque projet ne récupère que ce dont il a besoin.

En pratique, un mélange entre npm install et git sparse-checkout.

Ce qu'il apporte

  • Pas de sous-module, pas de vendoring à maintenir
  • Clone partiel (--filter=blob:none et sparse-checkout) : seul l'outil demandé est téléchargé
  • Manifeste par projet (.grabfile) : quelqu'un qui clone le projet lance grab install et obtient les mêmes outils
  • Épinglage possible sur une branche ou un tag, outil par outil
  • Hooks : un outil peut embarquer un post-grab.sh qui termine son installation, par exemple déplacer un .devcontainer/ à la racine du projet
  • Publication : grab publish . envoie un outil développé dans son coin vers le monorepo, sans copier-coller

Comment ça marche

grab init git@github.com:moi/tools.git   # une fois par projet
grab add stripe-cli                      # récupère un outil
grab add docker-utils @v2.1              # épinglé sur un tag
grab exec stripe-cli listen              # l'exécute

À l'ajout, le script clone le monorepo en sparse-checkout dans un cache local, n'y matérialise que le dossier demandé, le recopie dans .grab/tools/, l'inscrit au .grabfile et ajoute .grab/ au .gitignore. Le cache et les outils restent donc hors du dépôt du projet.

Détails qui comptent

Deux pièges m'ont occupé plus longtemps que le reste. grab publish . lancé depuis un dossier déjà géré par grab recopiait son propre cache dans le monorepo : la publication passe donc par un clone jetable, jamais par le cache du projet. Et les dossiers .git imbriqués sont retirés à la copie, sans quoi on publie un dépôt dans un dépôt.

Les hooks demandent confirmation avant de s'exécuter, puisqu'ils viennent du monorepo et touchent le projet : --hook et --no-hook permettent de trancher une fois pour toutes.

Bilan

Un script bash d'un seul fichier, sans dépendance au-delà de git. C'est exactement le genre d'outil que grab sert à distribuer : il se distribue lui-même.

Expérience : Personnel