- Eine nützliche Methode für Entwicklungsteams, Wissen in der Organisation zu sammeln und zu bewahren, besteht darin, eine Sammlung nützlicher Snippets, Skripte oder Workflows laufend zu erweitern
- Deshalb entstehen in vielen Repositories Dinge wie Makefiles oder bash-Skripte
- Aber wie geht man mit Dingen um wie der Installation nützlicher Tools im gesamten Unternehmen, dem Erzeugen von Boilerplate-Code oder dem Ausführen komplexer AWS-Befehle, an die sich niemand erinnern kann?
- Einige Unternehmen wie Slack oder Shopify haben eine eigene interne CLI
- Das moderne Terminal Warp bietet Funktionen, mit denen sich Workflows dokumentieren und teilen lassen
- Eine interne CLI für die Organisation lässt sich leicht erstellen. Als Beispiel wird eine CLI für eine Firma namens acme gebaut
Anforderungen an das CLI-Design
- Ein gemeinsamer Einstiegspunkt, über den sich Befehle überall mit
acme <command> ausführen lassen
- Alle Entwickler können
acme <command> von überall aus ausführen, um einen Befehl auszulösen, ohne zuerst in ein bestimmtes Repository wechseln zu müssen
- Entwickler sollen leicht neue Befehle beitragen können
- Neue Versionen sollen sich einfach mit
acme update verteilen lassen
- Plattformübergreifende Unterstützung (z. B. verwendet
acme download something unter Linux curl und unter Windows Invoke-WebRequest)
- Mit
acme list soll eine Liste verfügbarer Befehle mit kurzen Beschreibungen angezeigt werden
Das Projekt mit just starten
- just ist ein Tool ähnlich wie
make, aber auf die Ausführung von Befehlen spezialisiert
- Es unterstützt mehrere Plattformen und kann auch plattformspezifische Befehle ausführen
- Andere Optionen sind Slacks
magic-cli (ein guter Einstieg, wenn man Ruby gut kennt) oder make
Das Projekt einrichten
just installieren. Den Anweisungen hier folgen
- Den Ordner
~/acme/cli erstellen und im Root die folgende justfile hinzufügen:
default:
just --list
# Arch und OS-Namen anzeigen
os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
- In der
just-Dokumentation werden Befehle als „recipes“ bezeichnet
- Wenn
just ohne Recipe ausgeführt wird, läuft das erste Recipe in der justfile. Üblicherweise heißt dieses erste Recipe default
$ just
just --list
Available recipes:
default
os-info # Show arch and os name
- Das
default-Recipe führt just list aus. Es zeigt alle Recipes und Kommentare an
- Das
default-Recipe sollte besser ausgeblendet werden
- Beim Ausführen eines Recipes wird jeder Befehl vor der Ausführung ausgegeben. Mit dem Präfix
@ lässt sich diese Ausgabe unterdrücken. Ähnlich wie im Makefile
[private]
@default:
just --list
# Arch und OS-Namen anzeigen
@os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
Einen acme-Alias erstellen
Neue Recipes schreiben
Einfache Recipes
Plattformspezifische Recipes
- Snippets mit Tools wie
systemd sollen nur Entwicklern angezeigt werden, die Linux-Maschinen verwenden
- Mit dem Attribut
[linux] wird das Recipe nur unter Linux sichtbar
[linux]
@list-systemd-services:
systemctl list-units --type=service
Plattformübergreifende Recipes
Skript-Recipes
- In ein Recipe lässt sich ein vollständiges Skript einbetten
- Recipes, die mit einem Shebang (
#!) beginnen, werden in einer separaten Datei gespeichert und ausgeführt
- Das ist nützlich, wenn ein Workflow etwas komplexere Logik benötigt, etwa Kontrollfluss (if-else, Schleifen), das Speichern und Verarbeiten von Variablen usw.
# Say hello world in sh
hello-world-sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
- Das bedeutet, dass man Programmiersprachen mit leistungsfähigen Scripting-Funktionen nutzen kann. Manche Aufgaben lassen sich in Python einfacher lösen als in Bash
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#!/usr/bin/env python3
import PIL.Image
image = PIL.Image.open("{{path}}")
factor = 0.5
image = image.resize((round(image.width * factor), round(image.height * factor)))
image.save("{{path}}.s50.jpg")
- Nicht jeder Entwickler hat Python auf dem Rechner installiert, und selbst dann ist
pillow möglicherweise nicht vorhanden. Mit nix lässt sich ein Skript inklusive Abhängigkeiten ausführen:
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.pillow
import PIL.Image
...
Recipes verteilen
- Statt einen eigenen Deployment-Mechanismus zu bauen, wird
git verwendet
- Ein Repository auf GitHub erstellen und den bisherigen Stand pushen
$ git init
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin git@github.com:acme/cli.git
$ git push -u origin main
- Jetzt kann jeder mit Zugriff auf dieses Repository per PR Änderungen beitragen
- Mit dem Recipe
acme update wird git pull automatisiert
# Update the Acme CLI
@update:
git fetch
git checkout main
Dokumentation
- Für den Erfolg interner Tools ist Adoption sehr wichtig, und ein gutes Benutzerhandbuch ist essenziell, damit neue Nutzer das Tool installieren und erkunden können
- Im
README die Installation und Verwendung dokumentieren
# Acme CLI
## Prerequisites
`just`: Install just [here](https://github.com/casey/just/blob/master/README.md#installation)
## Installation
Clone this repo:
...
Set up the `acme` alias:
...
## Usage
List all available recipes:
...
- Jetzt kann jeder Entwickler bei Acme Corp es verwenden!
- Eine Nachricht im internen Slack posten, damit alle es ausprobieren, und jeder kann eigene Snippets beitragen
Zusätzliche Funktionen
- Completion ist ein Mechanismus, der beim Drücken der TAB-Taste Unterbefehle, Dateipfade, Optionen usw. automatisch vervollständigt
- Die meisten Shells bieten diese Funktion, und die meisten wichtigen CLI-Tools erklären, wie sich Completion installieren lässt
- Die meisten gängigen CLI-Frameworks wie Click für Python, Cobra für Golang oder clap für Rust können Completion automatisch erzeugen
just kann Completion erzeugen, indem just --completion <shell> ausgeführt wird
1 Kommentare
Schon seit Längerem scheint das Design der internen DX im Unternehmen ein wichtiges Thema für Platform Engineering zu sein.