50 Punkte von xguru 2024-09-03 | 1 Kommentare | Auf WhatsApp teilen
  • 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

  • Um Befehle in der Form acme <command> auszuführen, einen Alias in .bashrc hinzufügen
    alias acme='just --justfile ~/acme/cli/justfile'  
    
  • Mit source ~/.bashrc oder exec bash den neuen Alias laden

Neue Recipes schreiben

Einfache Recipes

  • AWS-IAM-Benutzer-/Rolleninformationen abrufen
    @aws-id:  
      aws sts get-caller-identity  
    
    • Das Vereinfachen von Befehlen, an die sich niemand erinnern kann, ist vermutlich einer der wichtigsten Anwendungsfälle für eine interne CLI
    • Da angenommen wird, dass awscli plattformübergreifend funktioniert, läuft dieses Recipe unabhängig vom Aufrufort

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

  • Die Ermittlung der Ordnergröße wird für Windows und Linux jeweils separat implementiert
    [windows]  
    [no-cd]  
    get-folder-size path:  
      (Get-ChildItem "{{path}}" -Recurse -Force | Measure-Object -Property Length -Sum).Sum / 1MB  
    
    [linux]  
    [no-cd]  
    get-folder-size path:  
      du -sh {{path}}  
    

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

 
bus710 2024-09-03

Schon seit Längerem scheint das Design der internen DX im Unternehmen ein wichtiges Thema für Platform Engineering zu sein.