#!/bin/sh # ============================================================================= # install.sh — installe (ou met à jour) la CLI hubdoc (binaire Go). # # curl -fsSL https://releases.sinoia.fr/hubdoc-cli/install.sh | sh # # Publié à la racine de releases.sinoia.fr/hubdoc-cli/ par le job CI # publish:release. Ce qu'il fait : # 1. détecte OS/arch (linux, darwin × amd64, arm64) ; # 2. télécharge le binaire ET son .sha256, VÉRIFIE l'empreinte ; # 3. installe par renommage atomique dans le dossier cible. # # Fail-closed sur l'empreinte : absente, illisible ou différente ⇒ rien n'est # installé. Elle protège d'un transfert corrompu ou d'une page d'erreur servie # en 200 ; elle vient du même serveur que le binaire, elle ne protège donc pas # d'un serveur compromis. # # Réglages (variables d'environnement) : # HUBDOC_VERSION version à installer (défaut : la dernière, latest/VERSION) # HUBDOC_INSTALL_DIR dossier cible (défaut : /usr/local/bin s'il est # inscriptible, sinon ~/.local/bin) # HUBDOC_RELEASES_URL source (défaut : https://releases.sinoia.fr/hubdoc-cli) # HUBDOC_SETUP posé par setup.sh, qui règle lui-même le PATH # # Mise à jour = relancer la même commande. Aucune mise à jour automatique. # ============================================================================= set -eu BASE="${HUBDOC_RELEASES_URL:-https://releases.sinoia.fr/hubdoc-cli}" BASE="${BASE%/}" say() { printf '%s\n' "$*" >&2; } die() { say "hubdoc install : $*"; exit 1; } need() { command -v "$1" >/dev/null 2>&1 || die "commande requise introuvable : $1"; } need curl need uname # --- plateforme -------------------------------------------------------------- case "$(uname -s)" in Linux) os=linux ;; Darwin) os=darwin ;; *) die "système non pris en charge : $(uname -s) (Windows : voir install.ps1)" ;; esac case "$(uname -m)" in x86_64 | amd64) arch=amd64 ;; arm64 | aarch64) arch=arm64 ;; *) die "architecture non prise en charge : $(uname -m)" ;; esac name="hubdoc-$os-$arch" # --- version ----------------------------------------------------------------- version="${HUBDOC_VERSION:-}" if [ -z "$version" ]; then version="$(curl -fsSL "$BASE/latest/VERSION" | tr -d ' \r\n')" || die "impossible de lire $BASE/latest/VERSION" fi case "$version" in '' | *[!0-9A-Za-z.+-]*) die "version invalide : '$version'" ;; esac # --- dossier cible ----------------------------------------------------------- dir="${HUBDOC_INSTALL_DIR:-}" if [ -z "$dir" ]; then if [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then dir=/usr/local/bin else dir="$HOME/.local/bin" fi fi mkdir -p "$dir" || die "impossible de créer $dir" # --- téléchargement + vérification ------------------------------------------ tmp="$(mktemp -d 2>/dev/null || mktemp -d -t hubdoc)" trap 'rm -rf "$tmp"' EXIT INT TERM say "hubdoc $version ($os/$arch) depuis $BASE" curl -fsSL "$BASE/$version/$name" -o "$tmp/$name" || die "téléchargement de $name impossible" curl -fsSL "$BASE/$version/$name.sha256" -o "$tmp/$name.sha256" || die "empreinte $name.sha256 introuvable : rien n'est installé" expected="$(awk 'NR == 1 { print $1 }' "$tmp/$name.sha256")" case "$expected" in *[!0-9a-f]* | '') die "empreinte illisible : rien n'est installé" ;; esac [ "${#expected}" -eq 64 ] || die "empreinte illisible : rien n'est installé" if command -v sha256sum >/dev/null 2>&1; then actual="$(sha256sum "$tmp/$name" | awk '{ print $1 }')" elif command -v shasum >/dev/null 2>&1; then actual="$(shasum -a 256 "$tmp/$name" | awk '{ print $1 }')" else die "ni sha256sum ni shasum : impossible de vérifier l'empreinte" fi [ "$actual" = "$expected" ] || die "empreinte différente (attendue $expected, obtenue $actual) : rien n'est installé" # --- installation atomique --------------------------------------------------- chmod 755 "$tmp/$name" cp "$tmp/$name" "$dir/.hubdoc.new.$$" || die "écriture impossible dans $dir (HUBDOC_INSTALL_DIR pour un autre dossier)" mv -f "$dir/.hubdoc.new.$$" "$dir/hubdoc" say "installé : $dir/hubdoc" # --- conseils ---------------------------------------------------------------- case ":$PATH:" in *":$dir:"*) ;; *) [ -n "${HUBDOC_SETUP:-}" ] || say "attention : $dir n'est pas dans le PATH ; ajouter : export PATH=\"$dir:\$PATH\"" ;; esac found="$(command -v hubdoc 2>/dev/null || true)" if [ -n "$found" ] && [ "$found" != "$dir/hubdoc" ]; then say "attention : un autre hubdoc passe avant dans le PATH : $found" say " (ancienne CLI npm @sinoia/hubdoc-tools ?) ; celui-ci est dans $dir" fi "$dir/hubdoc" version >/dev/null 2>&1 || say "attention : $dir/hubdoc ne s'exécute pas"