#!/bin/sh # diting installer — the one-liner entry point: # curl -fsSL https://raw.githubusercontent.com/yinnho/diting/main/install.sh | sh # # Downloads the release binary for the running OS/arch, verifies its sha256 # against the release-published checksum, installs to a bin dir, and finishes # with `diting doctor` so a broken environment says so immediately. # # Env overrides (namespaced and legacy spellings both accepted): # DITING_VERSION / VERSION pin a release (e.g. v0.9.0); default: latest # DITING_BIN_DIR / PREFIX install target; default: /usr/local/bin # if writable, else ~/.local/bin # DITING_GH_PROXY prefix mirror for github.com downloads, # for networks where GitHub is slow/blocked # (e.g. https://ghfast.top/ — third-party) set -eu repo="yinnho/diting" say() { printf '%s\n' "$*" >&2; } # ---- platform → release target ------------------------------------------- os=$(uname -s) arch=$(uname -m) case "$os" in Darwin) vendor="apple-darwin" ;; Linux) vendor="unknown-linux-gnu" ;; # git-bash / MSYS / Cygwin on Windows (uname -s is MINGW64_NT-... there) MINGW*|MSYS*|CYGWIN*) vendor="pc-windows-msvc" ;; *) say "unsupported OS: $os (macOS, Linux, and Windows git-bash only)"; exit 1 ;; esac case "$arch" in x86_64|amd64) cpu="x86_64" ;; aarch64|arm64) cpu="aarch64" ;; *) say "unsupported arch: $arch"; exit 1 ;; esac target="${cpu}-${vendor}" # Linux arm64 ships as one static musl build (no libc dependency). if [ "$target" = "aarch64-unknown-linux-gnu" ]; then target="aarch64-unknown-linux-musl" fi case "$target" in aarch64-apple-darwin|x86_64-apple-darwin|x86_64-unknown-linux-gnu|x86_64-pc-windows-msvc|aarch64-unknown-linux-musl) ;; *) say "no prebuilt binary for $target"; exit 1 ;; esac # ---- version --------------------------------------------------------------- version="${DITING_VERSION:-${VERSION:-}}" if [ -z "$version" ]; then version=$(curl -fsSL --connect-timeout 10 "https://api.github.com/repos/$repo/releases/latest" \ | sed -n 's/.*"tag_name": *"\(v[^"]*\)".*/\1/p' | head -1) [ -n "$version" ] || { say "could not resolve latest release (api.github.com unreachable?) — pin one: DITING_VERSION=v0.9.0 sh install.sh"; exit 1; } fi # The git tag carries the v, asset names never do (scripts/release_lib.sh). version="v${version#v}" asset="diting-${version#v}-${target}.tar.gz" say ">> diting $version for $target" # ---- download + verify ----------------------------------------------------- gh="https://github.com/$repo/releases/download/${version}" base="${DITING_GH_PROXY:-}$gh" tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT fetch() { curl -fsSL --retry 2 --connect-timeout 15 -o "$2" "$1"; } if ! fetch "$base/$asset" "$tmp/$asset"; then say "" say "download failed from $gh" say "if GitHub is slow/blocked on your network, retry through a mirror:" say " DITING_GH_PROXY=https://ghfast.top/ sh -c 'curl -fsSL | sh'" say "(mirrors are third-party)" exit 1 fi fetch "$base/$asset.sha256" "$tmp/$asset.sha256" if command -v sha256sum >/dev/null 2>&1; then (cd "$tmp" && grep " $asset\$" "$asset.sha256" | sha256sum -c -) elif command -v shasum >/dev/null 2>&1; then want=$(awk '{print $1}' "$tmp/$asset.sha256") got=$(shasum -a 256 "$tmp/$asset" | awk '{print $1}') [ "$want" = "$got" ] || { say "sha256 mismatch: expected $want, got $got"; exit 1; } else say ">> [warn] no sha256 tool found — skipping integrity check" fi say ">> sha256 ok" # ---- install --------------------------------------------------------------- bindir="${DITING_BIN_DIR:-${PREFIX:-}}" if [ -z "$bindir" ]; then # git-bash /usr/local/bin lives inside the Git install dir and is not on # PATH — the per-user bin is the sane default there. if [ "$vendor" = "pc-windows-msvc" ]; then bindir="$HOME/.local/bin" elif [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then bindir=/usr/local/bin else bindir="$HOME/.local/bin" fi fi mkdir -p "$bindir" # tarballs are one directory deep: diting-vX.Y.Z-target/diting[.exe] bin=diting if [ "$vendor" = "pc-windows-msvc" ]; then bin=diting.exe; fi tar -xzf "$tmp/$asset" -C "$tmp" src=$(find "$tmp" -mindepth 2 -maxdepth 2 -name "$bin" -type f | head -1) [ -n "$src" ] || { say "binary not found inside $asset"; exit 1; } install -m 0755 "$src" "$bindir/$bin" 2>/dev/null || { cp "$src" "$bindir/$bin" && chmod 0755 "$bindir/$bin"; } say ">> installed: $bindir/$bin" # ---- doctor ---------------------------------------------------------------- if "$bindir/$bin" doctor; then : else say ">> installed, but doctor reported a problem above (often just egress" say " being firewalled — set DITING_PROXY if you need a proxy)." fi say "" say " start a server: $bindir/$bin # HTTP API on 0.0.0.0:8089" say " try it: curl -sS -X POST http://127.0.0.1:8089/fetch \\" say " -H 'Content-Type: application/json' \\" say " -d '{\"url\":\"https://example.com\"}'" say " guide: https://github.com/$repo/blob/main/SKILL.md" case ":$PATH:" in *":$bindir:"*) ;; *) say "" say " [note] $bindir is not on your PATH — add it to use 'diting' directly:" say " echo 'export PATH=\"$bindir:\$PATH\"' >> ~/.zshrc (or ~/.bashrc)" ;; esac