mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-26 21:36:31 +02:00
add installation process and github workflow
This commit is contained in:
parent
6aea65ea02
commit
4712f5e0e3
8 changed files with 545 additions and 4 deletions
48
.github/workflows/ci.yml
vendored
Normal file
48
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
# Cancel in-progress runs when a new commit lands on the same branch /
|
||||
# pr, so we don't waste minutes on stale SHAs.
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: test (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: set up go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.23"
|
||||
cache: true
|
||||
|
||||
- name: go vet
|
||||
run: go vet ./...
|
||||
|
||||
- name: gofmt check
|
||||
# Windows' bash is mingw; gofmt outputs paths with slashes so the
|
||||
# diff check works there too. Skip on windows only if needed.
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
diff=$(gofmt -l .)
|
||||
if [ -n "$diff" ]; then
|
||||
echo "gofmt issues:"
|
||||
echo "$diff"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: go test
|
||||
run: go test -race ./...
|
||||
43
.github/workflows/release.yml
vendored
Normal file
43
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
permissions:
|
||||
# Needed for GoReleaser to create the GitHub Release and upload assets.
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# GoReleaser needs the full history to build a useful
|
||||
# changelog from commit messages.
|
||||
fetch-depth: 0
|
||||
|
||||
- name: set up go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.23"
|
||||
cache: true
|
||||
|
||||
- name: run goreleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --clean
|
||||
env:
|
||||
# Default token for the release itself (uploads artifacts,
|
||||
# creates the release page).
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Optional: PAT with `repo` scope for patriceckhart/homebrew-tap
|
||||
# so we can push a Formula/zot.rb update on every release.
|
||||
# Create the secret in repo settings → actions → secrets.
|
||||
# If unset, goreleaser skips the brew step (skip_upload: auto).
|
||||
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
||||
122
.goreleaser.yaml
Normal file
122
.goreleaser.yaml
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
# GoReleaser config — builds cross-platform binaries and GitHub Release
|
||||
# artifacts for zot.
|
||||
#
|
||||
# Triggered by pushing a tag like `v0.1.0`. The release workflow runs
|
||||
# `goreleaser release --clean`, which compiles every target, packs
|
||||
# them into `.tar.gz` (Unix) / `.zip` (Windows) archives, generates a
|
||||
# checksum file, and uploads everything to a GitHub Release.
|
||||
|
||||
version: 2
|
||||
|
||||
project_name: zot
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
|
||||
builds:
|
||||
- id: zot
|
||||
main: ./cmd/zot
|
||||
binary: zot
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos: [linux, darwin, windows]
|
||||
goarch: [amd64, arm64]
|
||||
# Windows/arm64 is shipped by Go but rarely used — skip to keep the
|
||||
# release artifact list tidy.
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X main.version={{.Version}}
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
|
||||
archives:
|
||||
- id: zot
|
||||
# Human-friendly name: zot_0.1.0_darwin_arm64.tar.gz
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
files:
|
||||
- LICENSE
|
||||
- README.md
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
algorithm: sha256
|
||||
|
||||
snapshot:
|
||||
# Used by `goreleaser release --snapshot`; lets contributors build
|
||||
# a local release without pushing a tag.
|
||||
version_template: "{{ incpatch .Version }}-next"
|
||||
|
||||
changelog:
|
||||
sort: asc
|
||||
use: github
|
||||
filters:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^chore:"
|
||||
- "^ci:"
|
||||
- "^test:"
|
||||
groups:
|
||||
- title: features
|
||||
regexp: "^.*feat[(\\w)]*:+.*$"
|
||||
order: 0
|
||||
- title: fixes
|
||||
regexp: "^.*fix[(\\w)]*:+.*$"
|
||||
order: 1
|
||||
- title: other
|
||||
order: 999
|
||||
|
||||
release:
|
||||
github:
|
||||
owner: patriceckhart
|
||||
name: zot
|
||||
draft: false
|
||||
prerelease: auto
|
||||
# Auto-generated release notes include the changelog groups above plus
|
||||
# an install snippet so the release page itself is a landing page.
|
||||
header: |
|
||||
## zot {{ .Tag }}
|
||||
|
||||
one-liner install:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/patriceckhart/zot/main/install.sh | bash
|
||||
```
|
||||
|
||||
homebrew:
|
||||
|
||||
```bash
|
||||
brew install patriceckhart/tap/zot
|
||||
```
|
||||
|
||||
or download a binary below, `chmod +x`, and drop it on your `$PATH`.
|
||||
|
||||
# Optional: publish a Homebrew formula to a tap repo on every release.
|
||||
# Requires the tap repo to exist at github.com/patriceckhart/homebrew-tap
|
||||
# and a PAT with `repo` scope exported as `HOMEBREW_TAP_TOKEN` in the
|
||||
# release workflow. Safe to leave enabled even before the tap exists;
|
||||
# goreleaser skips it when the token isn't set.
|
||||
brews:
|
||||
- repository:
|
||||
owner: patriceckhart
|
||||
name: homebrew-tap
|
||||
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
|
||||
name: zot
|
||||
homepage: https://github.com/patriceckhart/zot
|
||||
description: "lightweight coding agent harness — anthropic + openai, four tools, tui"
|
||||
license: MIT
|
||||
install: |
|
||||
bin.install "zot"
|
||||
test: |
|
||||
system "#{bin}/zot", "--help"
|
||||
# Only publish the formula when the token is actually set, so
|
||||
# ordinary tag pushes from forks don't explode.
|
||||
skip_upload: auto
|
||||
4
Makefile
4
Makefile
|
|
@ -1,4 +1,6 @@
|
|||
VERSION ?= dev
|
||||
# Local / untagged builds ship as 0.0.0. Release builds are driven by
|
||||
# goreleaser which overrides VERSION from the git tag.
|
||||
VERSION ?= 0.0.0
|
||||
LDFLAGS := -s -w -X main.version=$(VERSION)
|
||||
|
||||
.PHONY: build install test lint fmt clean release
|
||||
|
|
|
|||
34
README.md
34
README.md
|
|
@ -12,11 +12,39 @@ yet another coding agent harness, lightweight and written (vibe-slopped) in go.
|
|||
|
||||
## install
|
||||
|
||||
### one-liner (macos + linux)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/patriceckhart/zot/main/install.sh | bash
|
||||
```
|
||||
|
||||
detects your os/arch, downloads the latest release from github, verifies the sha256 against the release's `checksums.txt`, extracts the binary, and drops it in `/usr/local/bin`, `~/.local/bin`, or `~/bin` — whichever is writable first. pass a version or prefix to pin:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/patriceckhart/zot/main/install.sh | bash -s -- v0.0.1 ~/bin
|
||||
```
|
||||
|
||||
### one-liner (windows, powershell)
|
||||
|
||||
```powershell
|
||||
iwr -useb https://raw.githubusercontent.com/patriceckhart/zot/main/install.ps1 | iex
|
||||
```
|
||||
|
||||
drops `zot.exe` into `$HOME\bin` and adds it to the user PATH if missing. open a fresh terminal afterwards.
|
||||
|
||||
### homebrew (macos + linux)
|
||||
|
||||
```bash
|
||||
brew install patriceckhart/tap/zot
|
||||
```
|
||||
|
||||
### go install
|
||||
|
||||
```bash
|
||||
go install github.com/patriceckhart/zot/cmd/zot@latest
|
||||
```
|
||||
|
||||
or from source:
|
||||
### from source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/patriceckhart/zot
|
||||
|
|
@ -25,6 +53,10 @@ make build # produces ./bin/zot
|
|||
make install # into $GOPATH/bin
|
||||
```
|
||||
|
||||
### prebuilt binaries
|
||||
|
||||
every release on the [releases page](https://github.com/patriceckhart/zot/releases) ships archives for linux, macos, and windows on amd64 + arm64 (except windows/arm64), plus a `checksums.txt` file. download, verify, `chmod +x`, and drop on your `$PATH`.
|
||||
|
||||
## authenticate
|
||||
|
||||
the easiest way is to just run `zot` and type `/login`. the tui opens even without credentials and walks you through a browser-based login flow.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,33 @@ import (
|
|||
"github.com/patriceckhart/zot/internal/agent"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
// Injected at build time via -ldflags "-X main.version=... -X main.commit=... -X main.date=...".
|
||||
// See .goreleaser.yaml for the release build and the Makefile for
|
||||
// local builds. Defaults make `zot --version` print something sensible
|
||||
// when built without ldflags.
|
||||
var (
|
||||
// 0.0.0 is the pre-release placeholder for local / untagged
|
||||
// builds. The first published GitHub release will be tagged
|
||||
// v0.0.1; everything before that ships as 0.0.0 from source.
|
||||
version = "0.0.0"
|
||||
commit = ""
|
||||
date = ""
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := agent.Run(os.Args[1:], version); err != nil {
|
||||
v := version
|
||||
if commit != "" {
|
||||
short := commit
|
||||
if len(short) > 7 {
|
||||
short = short[:7]
|
||||
}
|
||||
v = v + " (" + short
|
||||
if date != "" {
|
||||
v = v + ", " + date
|
||||
}
|
||||
v = v + ")"
|
||||
}
|
||||
if err := agent.Run(os.Args[1:], v); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "zot:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
|
|||
115
install.ps1
Normal file
115
install.ps1
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# zot installer for Windows (PowerShell).
|
||||
#
|
||||
# Usage (in PowerShell):
|
||||
# iwr -useb https://raw.githubusercontent.com/patriceckhart/zot/main/install.ps1 | iex
|
||||
#
|
||||
# Or with arguments:
|
||||
# $env:ZOT_VERSION = "v0.0.1"
|
||||
# $env:ZOT_PREFIX = "$HOME\bin"
|
||||
# iwr -useb https://raw.githubusercontent.com/patriceckhart/zot/main/install.ps1 | iex
|
||||
#
|
||||
# Detects architecture, downloads the matching .zip from the GitHub
|
||||
# release, verifies the sha256 against checksums.txt, extracts zot.exe,
|
||||
# and moves it into $ZOT_PREFIX (defaults to $HOME\bin, added to PATH
|
||||
# via the User environment if missing).
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Version = $env:ZOT_VERSION,
|
||||
[string]$Prefix = $env:ZOT_PREFIX
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$owner = "patriceckhart"
|
||||
$repo = "zot"
|
||||
$binary = "zot"
|
||||
|
||||
if (-not $Version) { $Version = "latest" }
|
||||
if (-not $Prefix) { $Prefix = Join-Path $HOME "bin" }
|
||||
|
||||
function Msg($m) { Write-Host "==> $m" -ForegroundColor Cyan }
|
||||
function Warn($m) { Write-Warning $m }
|
||||
function Die($m) { Write-Error $m; exit 1 }
|
||||
|
||||
# ---- detect architecture ----
|
||||
|
||||
switch -wildcard ($env:PROCESSOR_ARCHITECTURE) {
|
||||
"AMD64" { $arch = "amd64" }
|
||||
"ARM64" { $arch = "arm64" }
|
||||
default { Die "unsupported arch: $($env:PROCESSOR_ARCHITECTURE)" }
|
||||
}
|
||||
|
||||
# ARM64 Windows isn't shipped (see .goreleaser.yaml ignore rule) — fall
|
||||
# back to amd64 which runs fine under ARM64 emulation.
|
||||
if ($arch -eq "arm64") {
|
||||
Warn "windows/arm64 is not published; falling back to amd64"
|
||||
$arch = "amd64"
|
||||
}
|
||||
|
||||
# ---- resolve version ----
|
||||
|
||||
if ($Version -eq "latest") {
|
||||
$resp = Invoke-WebRequest -UseBasicParsing -MaximumRedirection 5 `
|
||||
"https://github.com/$owner/$repo/releases/latest"
|
||||
if ($resp.BaseResponse.ResponseUri -match '/tag/([^/]+)') {
|
||||
$Version = $Matches[1]
|
||||
} else {
|
||||
Die "could not resolve latest version"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $Version.StartsWith("v")) { $Version = "v$Version" }
|
||||
$verNum = $Version.TrimStart("v")
|
||||
|
||||
# ---- download + verify + extract ----
|
||||
|
||||
$archive = "${binary}_${verNum}_windows_${arch}.zip"
|
||||
$baseUrl = "https://github.com/$owner/$repo/releases/download/$Version"
|
||||
$archiveUrl = "$baseUrl/$archive"
|
||||
$checksumUrl = "$baseUrl/checksums.txt"
|
||||
|
||||
$tmp = New-Item -ItemType Directory -Path (Join-Path $env:TEMP ("zot-install-" + [System.Guid]::NewGuid().ToString("N").Substring(0,8)))
|
||||
|
||||
try {
|
||||
Msg "downloading $archive"
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $archiveUrl -OutFile (Join-Path $tmp $archive)
|
||||
|
||||
Msg "verifying checksum"
|
||||
$checksums = Invoke-WebRequest -UseBasicParsing -Uri $checksumUrl | Select-Object -ExpandProperty Content
|
||||
$expected = ($checksums -split "`n" | Where-Object { $_ -match [regex]::Escape($archive) + "$" } | Select-Object -First 1)
|
||||
if (-not $expected) { Die "no checksum for $archive in checksums.txt" }
|
||||
$expectedHash = ($expected -split "\s+")[0]
|
||||
|
||||
$actualHash = (Get-FileHash -Path (Join-Path $tmp $archive) -Algorithm SHA256).Hash.ToLower()
|
||||
if ($expectedHash.ToLower() -ne $actualHash) {
|
||||
Die "checksum mismatch: expected $expectedHash, got $actualHash"
|
||||
}
|
||||
|
||||
Msg "extracting"
|
||||
Expand-Archive -Path (Join-Path $tmp $archive) -DestinationPath $tmp -Force
|
||||
|
||||
$exe = Join-Path $tmp "$binary.exe"
|
||||
if (-not (Test-Path $exe)) { Die "archive did not contain $binary.exe" }
|
||||
|
||||
Msg "installing to $Prefix\$binary.exe"
|
||||
New-Item -ItemType Directory -Path $Prefix -Force | Out-Null
|
||||
Copy-Item $exe (Join-Path $Prefix "$binary.exe") -Force
|
||||
|
||||
# ---- PATH hint ----
|
||||
|
||||
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
||||
$parts = $userPath -split ";" | Where-Object { $_ }
|
||||
if (-not ($parts -contains $Prefix)) {
|
||||
Warn "$Prefix is not on your user PATH"
|
||||
Warn "adding it for future sessions..."
|
||||
[Environment]::SetEnvironmentVariable("Path", ($userPath.TrimEnd(";") + ";" + $Prefix), "User")
|
||||
Warn "open a new terminal to pick up the change, or run:"
|
||||
Warn " `$env:Path = `"$Prefix;`$env:Path`""
|
||||
}
|
||||
|
||||
Msg "installed. run: zot --help"
|
||||
}
|
||||
finally {
|
||||
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
||||
}
|
||||
156
install.sh
Executable file
156
install.sh
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# zot installer.
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://raw.githubusercontent.com/patriceckhart/zot/main/install.sh | bash
|
||||
# curl -fsSL https://raw.githubusercontent.com/patriceckhart/zot/main/install.sh | bash -s -- v0.0.1 ~/bin
|
||||
#
|
||||
# Positional arguments:
|
||||
# $1 version — release tag (e.g. v0.0.1). Defaults to "latest".
|
||||
# $2 prefix — install directory. Defaults to the first writable
|
||||
# directory in: /usr/local/bin, $HOME/.local/bin,
|
||||
# $HOME/bin. Created if missing. Add it to your PATH
|
||||
# if it isn't already.
|
||||
#
|
||||
# Environment overrides:
|
||||
# ZOT_VERSION same as $1
|
||||
# ZOT_PREFIX same as $2
|
||||
#
|
||||
# The script detects your OS and architecture, downloads the matching
|
||||
# archive from the GitHub release, verifies the sha256 against the
|
||||
# release's checksums.txt, extracts the binary, and moves it into the
|
||||
# prefix directory. No sudo unless you explicitly pick a prefix that
|
||||
# needs it.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
OWNER="patriceckhart"
|
||||
REPO="zot"
|
||||
BINARY="zot"
|
||||
|
||||
VERSION="${1:-${ZOT_VERSION:-latest}}"
|
||||
PREFIX="${2:-${ZOT_PREFIX:-}}"
|
||||
|
||||
msg() { printf "\033[1m==>\033[0m %s\n" "$*"; }
|
||||
warn() { printf "\033[33mwarn:\033[0m %s\n" "$*" >&2; }
|
||||
die() { printf "\033[31merror:\033[0m %s\n" "$*" >&2; exit 1; }
|
||||
|
||||
command -v curl >/dev/null 2>&1 || die "curl is required"
|
||||
command -v tar >/dev/null 2>&1 || die "tar is required"
|
||||
|
||||
# ---- detect OS + arch ----
|
||||
|
||||
uname_s=$(uname -s)
|
||||
uname_m=$(uname -m)
|
||||
|
||||
case "$uname_s" in
|
||||
Linux) OS=linux ;;
|
||||
Darwin) OS=darwin ;;
|
||||
MINGW*|MSYS*|CYGWIN*)
|
||||
die "windows detected — use install.ps1 from powershell instead"
|
||||
;;
|
||||
*) die "unsupported os: $uname_s" ;;
|
||||
esac
|
||||
|
||||
case "$uname_m" in
|
||||
x86_64|amd64) ARCH=amd64 ;;
|
||||
arm64|aarch64) ARCH=arm64 ;;
|
||||
*) die "unsupported arch: $uname_m" ;;
|
||||
esac
|
||||
|
||||
# ---- resolve version ----
|
||||
|
||||
if [ "$VERSION" = "latest" ]; then
|
||||
# GitHub's /releases/latest endpoint redirects to /releases/tag/<tag>.
|
||||
# We follow the redirect and grab the tag from the final URL without
|
||||
# needing jq.
|
||||
VERSION=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
|
||||
"https://github.com/${OWNER}/${REPO}/releases/latest" \
|
||||
| sed -E 's|.*/tag/([^/]+).*|\1|')
|
||||
[ -n "$VERSION" ] || die "could not resolve latest version"
|
||||
fi
|
||||
|
||||
case "$VERSION" in v*) ;; *) VERSION="v$VERSION" ;; esac
|
||||
VER_NUM="${VERSION#v}"
|
||||
|
||||
# ---- pick an install prefix ----
|
||||
|
||||
pick_prefix() {
|
||||
local candidates=()
|
||||
[ -n "$PREFIX" ] && { echo "$PREFIX"; return; }
|
||||
candidates+=("/usr/local/bin")
|
||||
[ -n "${HOME:-}" ] && candidates+=("$HOME/.local/bin" "$HOME/bin")
|
||||
for d in "${candidates[@]}"; do
|
||||
if [ -d "$d" ] && [ -w "$d" ]; then
|
||||
echo "$d"
|
||||
return
|
||||
fi
|
||||
done
|
||||
# Nothing writable yet — create ~/.local/bin and use that.
|
||||
if [ -n "${HOME:-}" ]; then
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
echo "$HOME/.local/bin"
|
||||
return
|
||||
fi
|
||||
die "no writable install prefix found; pass one as the second argument"
|
||||
}
|
||||
|
||||
PREFIX=$(pick_prefix)
|
||||
mkdir -p "$PREFIX"
|
||||
|
||||
# ---- download + verify + extract ----
|
||||
|
||||
ARCHIVE="${BINARY}_${VER_NUM}_${OS}_${ARCH}.tar.gz"
|
||||
BASE_URL="https://github.com/${OWNER}/${REPO}/releases/download/${VERSION}"
|
||||
ARCHIVE_URL="${BASE_URL}/${ARCHIVE}"
|
||||
CHECKSUMS_URL="${BASE_URL}/checksums.txt"
|
||||
|
||||
TMP=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
|
||||
msg "downloading ${ARCHIVE}"
|
||||
curl -fsSL -o "$TMP/$ARCHIVE" "$ARCHIVE_URL" \
|
||||
|| die "download failed: $ARCHIVE_URL"
|
||||
|
||||
msg "verifying checksum"
|
||||
curl -fsSL -o "$TMP/checksums.txt" "$CHECKSUMS_URL" \
|
||||
|| die "download failed: $CHECKSUMS_URL"
|
||||
|
||||
expected=$(grep " ${ARCHIVE}\$" "$TMP/checksums.txt" | awk '{print $1}' || true)
|
||||
[ -n "$expected" ] || die "no checksum for $ARCHIVE in checksums.txt"
|
||||
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
actual=$(sha256sum "$TMP/$ARCHIVE" | awk '{print $1}')
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
actual=$(shasum -a 256 "$TMP/$ARCHIVE" | awk '{print $1}')
|
||||
else
|
||||
die "no sha256 tool found (sha256sum or shasum)"
|
||||
fi
|
||||
|
||||
[ "$expected" = "$actual" ] \
|
||||
|| die "checksum mismatch: expected $expected, got $actual"
|
||||
|
||||
msg "extracting"
|
||||
tar -xzf "$TMP/$ARCHIVE" -C "$TMP"
|
||||
|
||||
[ -f "$TMP/$BINARY" ] || die "archive did not contain a '$BINARY' binary"
|
||||
|
||||
msg "installing to $PREFIX/$BINARY"
|
||||
install -m 0755 "$TMP/$BINARY" "$PREFIX/$BINARY" 2>/dev/null \
|
||||
|| { cp "$TMP/$BINARY" "$PREFIX/$BINARY" && chmod 0755 "$PREFIX/$BINARY"; }
|
||||
|
||||
# ---- PATH hint ----
|
||||
|
||||
case ":$PATH:" in
|
||||
*":$PREFIX:"*) ;;
|
||||
*)
|
||||
warn "$PREFIX is not on your PATH"
|
||||
warn "add this to your shell rc file:"
|
||||
warn " export PATH=\"$PREFIX:\$PATH\""
|
||||
;;
|
||||
esac
|
||||
|
||||
msg "installed $("$PREFIX/$BINARY" --version 2>/dev/null || echo zot)"
|
||||
msg "run: zot (interactive tui)"
|
||||
msg "run: zot --help (all flags and subcommands)"
|
||||
Loading…
Add table
Reference in a new issue