Ich habe einen Haufen Projekte in vielen Git Repositorys.
Da kommt es regelmäßig vor, dass ich Befehle in mehreren davon ausführen will.
Zum Beispiel ein git fetch
in allen Git Repos oder ein cargo doc
in allen Rust Projekten, wenn eine neue Rust Version herauskam.
Das habe ich bisher mit fd
/ find
und lustigen Bash Funktionen / Aliase realisiert.
Aus meiner Sicht funktionierte aber nur so mäßig gut.
Dafür habe ich jetzt ein kleines CLI Tool gebaut, welches auch mehr meiner Bedürfnisse abdeckt und auch noch deutlich schneller ist.
Wie benutze ich es?
Angenommen ich will in allen Node.js Projekten in Unterordnern npm test
aufrufen.
Dafür muss ich eine Eigenschaft von einem Ordner kennen, der ein Node.js Projekt beinhaltet.
Ich nehme dafür an, dass eine Datei namens package.json
darin existiert.
Und das wäre dann der Befehl mit project-below
:
project-below --file=package.json npm test
Wenn ich häufiger einen Befehl in Node.js Projekten ausführen will, kann ich mir den vorderen Teil in einen Alias packen und so verkürzen:
alias npmBelow='project-below --file=package.json npm'
npmBelow test
Mit diesem Alias kann ich auch andere Befehle wie npm install
in allen Unterordnern ausführen:
npmBelow install
So kann ich ganz unterschiedliche Arten von Projekten realisieren, indem ich die passenden Optionen für diese nutze:
alias gitBelow='project-below --directory=.git git'
gitBelow fetch
alias cargoBelow='project-below --file=Cargo.toml cargo'
cargoBelow check
alias pioBelow='project-below --file=platformio.ini pio'
pioBelow run
alias dotnetBelow='project-below --file="*.sln" dotnet'
dotnetBelow test
Das coole dabei, damit funktioniert auch Autovervollständigung von Befehlen.
Ich kann gitBelow stat<Tab>
benutzen und es wird automatisch in gitBelow status
vervollständigt.
Etwas das mit meinen vorherigen Funktionen mittels find
/ fd
nicht funktionierte.
Was habe ich vorher benutzt?
Bevor ich mein eigenes Tool dafür gebaut habe, habe ich mir mit kleinen Bash (bzw. in meinem Fall Zsh) Funktionen beholfen.
Wie man generell schnell nach Dateien oder Dateiinhalten sucht, habe ich bereits in diesem Post mal beschrieben.
gitBelow
war beispielsweise über find
realisiert:
gitBelow() {
find . -name ".git" -type d -print -execdir git --no-pager $@ \;
}
Das funktionierte ganz passabel, bot aber keine Autovervollständigung.
npmBelow
ist aber so (zumindest mir bekannt) nicht generell möglich.
Wenn man annimmt, das ein Unterordner mit einer package.json
ein Ordner ist, in dem man einen Befehl ausführen will, dann findet find
eine ganze Menge im node_modules
Ordner, was nicht gerade weiterhilft.
fd
beachtet ignore Dateien (wie .gitignore
) und versteckte Ordner, findet hier also die package.json
der Dependencies nicht.
Allerdings kann (und will) fd
aber keine Befehle in einen Unterordner ausführen, sondern nur den Pfad zum Treffer übergeben.
Für Tools wie git
welches ein -C
mitbringt, um beliebige Ordner anzunehmen, kein Problem, kann aber zum Beispiel npm
nicht.
Hier kann man dann zum Beispiel eine Bash starten, welche zuerst mit cd
in den Ordner wechselt.
Was auch immer ich hier tue, die Lösung wird spezifischer und komplizierter zu bauen.
Das würde für Unübersichtlichkeit in meinen Aliasen sorgen, die ich gar nicht erst haben will.
Und das Anpassen von einem Skript auf zum Beispiel eine andere Programmiersprache wäre nervig.
So kam es zu meinem eigenen, kleinen Tool, welches diese Anforderungen erfüllt.
Fazit
Das Tool funktioniert für mich nun schon seit ein paar Tagen und verrichtet erfolgreich seinen Dienst.
Auch zeigt es mir noch mal mehr auf, wie langsam find
im Vergleich zu fd
ist (project-below
verwendet intern denselben Filewalker wie fd
und ripgrep
).
Meine Bash Funktion mittels find
hat für meine 100+ Git Repos (gitBelow status
zum Beispiel) mehrere Sekunden gebraucht.
project-below
mit demselben Befehl braucht keine 100 ms.
Der Quellcode ist auf GitHub zu finden. Dort kann man auch die fertig kompilierten Executables herunterladen. Vermutlich werde ich das Tool demnächst auch im AUR bereitstellen.
Hast du Projekte die mit dem Tool noch nicht (so einfach) umsetzbar sind? Dann kontaktier mich gern dazu (über einen der Wege unten im Footer). Ich bin auch neugierig, was für das Tool noch hilfreich wäre, um für mehr Fälle eingesetzt werden zu können.
Ansonsten hoffe ich, dass es nicht nur mir im Alltag weiter helfen kann. Wenn du Beispiele hast, wofür es noch hilfreich ist, füg diese gern im Readme über einen Pull Request hinzu!