[mike@maginot]

This commit is contained in:
2026-08-10 20:13:52 +02:00
parent 659ab03652
commit d26a008763
4 changed files with 214 additions and 22 deletions
+54 -9
View File
@@ -73,6 +73,38 @@ entweder die alte Datei oder die neue, nie eine halbe.
Liegt das Binary irgendwo, wo der eigene Benutzer nicht schreiben darf
(`/usr/local/bin`), sagt `dx --update` das und tut nichts — dann `sudo`.
### Einmal am Tag von selbst
Ohne Zutun sieht `dx` einmal am Tag nach und sagt danach am Ende der Ausgabe auf
stderr Bescheid:
```
dx 2.1.9 is available, run 'dx --update'
```
Der Lauf im Vordergrund fasst dafür nie das Netz an. Er liest nur einen
Merkzettel — `~/Library/Caches/dx/update.json`, unter Linux
`~/.cache/dx/update.json` — und wenn der älter als einen Tag ist, startet er
nebenbei `dx --update-refresh`: denselben Läufer noch einmal, abgekoppelt, ohne
Ausgabe, nur zum Fragen. Auf dessen Antwort wartet niemand, sie steht beim
nächsten Aufruf im Merkzettel. `dx` bleibt damit genau so schnell wie vorher,
auch wenn der Server gerade schweigt.
Der Zeitstempel wandert weiter, *bevor* gefragt wird. Zwei gleichzeitige Läufe
starten deshalb nur eine Abfrage, und ein Server, der nicht antwortet, wird
morgen wieder gefragt und nicht bei jedem Aufruf. Lässt sich der Merkzettel
nicht schreiben, unterbleibt die Frage ganz — sonst hinge an einem
schreibgeschützten Cache-Verzeichnis ein Prozess je Aufruf.
Gefragt und gesagt wird nur, wenn stderr am Terminal hängt. In einer Pipe, in
einem Skript und unter cron ist Ruhe, und `DX_NO_UPDATE_CHECK=1` schaltet es
ganz ab.
Das kostet Platz: `net/http` samt TLS macht aus einem 1,8-MB-Binary eins von
6,2 MB. Für ein Werkzeug, das ohnehin auf der Platte liegt, ist das der Preis
dafür, sich selbst erneuern zu können — wer ihn nicht zahlen will, lässt
`selfupdate.go` weg.
## Wiederverwenden
`selfupdate.go` hängt an nichts im Rest des Programms und kommt mit der
@@ -81,18 +113,31 @@ oben anpassen —
```go
var selfUpdate = selfUpdater{
repo: "https://git.micw.org/mike/foo",
asset: "foo",
current: version,
verify: []string{"--version"},
repo: "https://git.micw.org/mike/foo",
asset: "foo",
current: version,
verify: []string{"--version"},
every: 24 * time.Hour,
quietEnv: "FOO_NO_UPDATE_CHECK",
}
```
— und `--update` und `--check-update` in die Optionen hängen. Alles Weitere in
der Datei heißt `selfUpdate…` oder `update…` und kollidiert deshalb nicht.
`verify` leer lassen, wenn das Programm keinen billigen Versionsaufruf hat; dann
entfällt der Probelauf. Erwartet wird eine Gitea-Instanz (getestet mit 1.27);
GitHub kennt dieselbe Route unter anderen Feldnamen und wird nicht bedient.
Dazu drei Zeilen im Optionenteil — `--update`, `--check-update` und das
versteckte `updateRefreshFlag` — und eine am Ende des Programms:
```go
if hint := selfUpdate.daily(); hint != "" {
fmt.Fprintln(os.Stderr, hint)
}
```
`daily` liefert nur den Text; wie er aussieht, entscheidet das Programm. Alles
Weitere in der Datei heißt `selfUpdate…` oder `update…` und kollidiert deshalb
nicht. `verify` leer lassen, wenn das Programm keinen billigen Versionsaufruf
hat, dann entfällt der Probelauf; `every: 0` schaltet die Nachschau von selbst
ab und lässt nur die beiden Optionen übrig. Erwartet wird eine Gitea-Instanz
(getestet mit 1.27); GitHub kennt dieselbe Route unter anderen Feldnamen und
wird nicht bedient.
## Optionen