Files
upd/README.md
T

105 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# upd (Go)
A port of the Perl `upd` one directory up. Same command line, same config file,
same state and cache files - the two can be used interchangeably on the same
machine.
## Build
```sh
./build.sh
```
builds every platform into `./bin`, statically linked and stripped, and bumps
the patch version by 0.0.1 on each run. `version.txt` holds the version just
built; the same number goes into the binaries via `-ldflags -X main.version`,
so `upd --version` and the release tag always agree. One platform only:
```sh
PLATFORMS="linux/amd64" ./build.sh
```
The asset names in `./bin` - `upd-<goos>-<goarch>` - are exactly what
`--update` looks for in a release, so a release is `./bin` uploaded as it is.
A plain `go build -o ~/bin/upd .` still works; it just reports the fallback
version from `main.go`.
`go test ./...` runs the asset selection against the release JSON in
`../t/corpus`, the same corpus `t/select.t` uses, and fails if the two
implementations start disagreeing.
## Updating itself
upd installs itself the same way it installs everything else - same forge
layer, same CA fallback, same checksum check, same atomic replace:
```sh
upd --version # what is running
upd --check-update # look, change nothing
upd --update # download the newest release and replace the binary
```
`--update` replaces the file the running binary actually is, following a
symlink into `./bin` to the file behind it. It refuses before downloading if
that directory is not writable, and it runs the downloaded binary once with
`--version` before letting it take over, so a truncated file or one for the
wrong platform never replaces a working one. `--force` reinstalls the current
version, `--dry-run` says what it would do.
Beyond that, an ordinary run looks for a new release once a day, in the
background, and mentions it on stderr:
```
Note: upd 2.0.7 is available, run 'upd --update'.
```
The look never happens in the foreground - the run itself is never slowed down
or made to depend on the network - and never when stderr is not a terminal, so
cron and pipelines stay silent. `UPD_NO_UPDATE_CHECK=1` switches it off
altogether. The note lives in `~/.cache/upd/selfupdate.json`.
The mechanism is the one in `dx`; here it goes through upd's own machinery
instead of bringing its own HTTP client.
## Why a port
The Perl version needs curl or wget for HTTPS, which is exactly what breaks on
an older system: a curl linked against OpenSSL 1.0.x cannot complete a
handshake with a server that requires TLS 1.2, and there is nothing upd can do
about it beyond falling back to wget. The Go binary brings its own TLS stack,
so the transport question disappears - along with `--stderr` juggling, exit
code translation and the wget fallback.
## Certificates
Verification uses the system CA store. If that store does not know the issuer -
the usual case on a machine whose `ca-certificates` package predates Let's
Encrypt's ISRG roots - upd says so once and retries with the Mozilla CA list
embedded in `ca-bundle.pem`, so the binary stays self-sufficient. Refresh that
file with:
```sh
curl -o ca-bundle.pem https://curl.se/ca/cacert.pem
```
`--cacert FILE` (or `$UPD_CACERT`) replaces the system store, for a private CA.
`--insecure` skips verification altogether and warns on every run. Both switch
the automatic fallback off: an explicit choice stays the choice.
## Differences
| | Perl | Go |
|---|---|---|
| TLS | curl / wget / IO::Socket::SSL | built in |
| CA roots | whatever the system has | system, with the Mozilla list as fallback |
| `--cacert`, `--insecure` | – | yes |
| `tar`, `unzip` | external | in-process |
| `.gz`, `.bz2` | external | in-process |
| `.xz`, `.zst`, `.lz4`, `.7z` | external | external (unchanged) |
| Archive paths | trusted to `tar` | checked against traversal |
| `version-flag=` in the config file | overwritten by its own default | honoured |
Behaviour that deliberately stayed identical: asset scoring (same picks on the
whole corpus), the `--install` file-or-directory rule, state and cache file
layout, exit codes 0/1/2/10.