#!/usr/bin/env bash # # DeepWorkPlan Vim — self-contained installer for release v0.7.0. # # Published at : https://deepworkplan.com/vim/install.sh # and as the install.sh asset (with SHA256SUMS) of each # release: https://github.com/DailybotHQ/deepworkplan-vim/releases # Repository : https://github.com/DailybotHQ/deepworkplan-vim # License : GPL-3.0 (the configuration it installs is GPL-3.0) # # Usage — download, verify, then run: # curl -fsSL -o install.sh https://deepworkplan.com/vim/install.sh # curl -fsSL -o install.sh.sha256 https://deepworkplan.com/vim/install.sh.sha256 # shasum -a 256 -c install.sh.sha256 # Linux: sha256sum -c install.sh.sha256 # bash install.sh [options] # bash install.sh --help lists them # Run it from a terminal: it asks before touching an existing config. # For a check from a second origin, compare the hash with the install.sh # line of SHA256SUMS on the GitHub release (release tags are immutable). # # Images and CI (non-root, no terminal) — one step after the download: # bash install.sh --version 0.7.0 --nvim 0.12.5 --skip-packages --strict # # What it does, in order: # 1. Preflight — detects OS and package manager; installs git, curl, and # a Lua interpreter if any are missing (none with --skip-packages). # 2. Version — this script's release, or the one --version / --ref asks # for (X.Y.Z, vX.Y.Z, latest, '>=X.Y.Z' — stable tags only). # 3. Neovim — with --nvim X.Y.Z, the official release tarball into # ~/.local/opt/nvim-vX.Y.Z (linked as ~/.local/bin/nvim), verified # against the sha256 Neovim publishes. # 4. Consent — an existing, foreign Neovim config is NEVER overwritten. # Interactively you are asked before it is moved to # ~/.config/previous-deepworkplan-vim; without a terminal the script # stops with instructions unless --yes says to move it aside. # 5. Clones (or updates, on re-run) the repository into ~/.config/nvim. # 6. Runs the repository's own `lua install.lua` (system packages, # pckr.nvim, font — it owns every step, this wrapper owns none). # 7. Bootstraps plugins headlessly and checks them — every plugin and # pckr at the commit the release pins in pckr/lockfile.lua (0.5.1+); # empty clones are moved aside and installed again (--strict: any # failure, missing or empty plugin, or plugin away from its pin is an # error). # # Options (each with an environment twin; a flag beats every env value): # --version DWP_VIM_VERSION X.Y.Z, vX.Y.Z, latest or '>=X.Y.Z' # --ref DWP_VIM_REF tag, branch or commit (main follows main) # --dir DWP_VIM_DIR destination (default ~/.config/nvim) # --skip-packages DWP_VIM_SKIP_PACKAGES=1 install no system package # --nvim DWP_VIM_NVIM install that Neovim release, verified # --strict DWP_VIM_STRICT=1 fail on a failed or incomplete bootstrap, # or a plugin away from its locked commit # --yes DWP_VIM_YES=1 move a foreign config aside unattended # -h, --help # Other environment: # DWP_VIM_SOURCE repository URL or a local path (offline, mirrors) # DWP_VIM_BOOTSTRAP_TIMEOUT seconds for the headless plugin install (900) # GITHUB_TOKEN optional: authenticates --nvim's release lookup # (then removed from the environment of the run) # # Windows: use winget plus Git Bash, or run the steps above inside WSL, # where they work as-is: # winget install -e --id Neovim.Neovim --accept-package-agreements --accept-source-agreements # git clone --branch v0.7.0 https://github.com/DailybotHQ/deepworkplan-vim.git "$LOCALAPPDATA/nvim" # cd "$LOCALAPPDATA/nvim" && lua install.lua # set -euo pipefail # The whole script is one function, called on the last line: bash parses # all of it before running anything. When the download is piped into bash # the script arrives on stdin, so nothing it runs may read stdin — and no # half-downloaded script can run partially. main() { REPO_URL="https://github.com/DailybotHQ/deepworkplan-vim.git" # The release this script belongs to: with no version or ref requested it # installs exactly that tag. RELEASE_REF="v0.7.0" say() { printf '%s\n' "$*"; } die() { printf 'install.sh: %s\n' "$*" >&2; exit 1; } usage() { cat <<'USAGE' DeepWorkPlan Vim installer Usage: bash install.sh [options] Version (pick one; the default is this script's own release): --version X.Y.Z, vX.Y.Z, latest (newest stable release), or '>=X.Y.Z' (newest stable release at or above the floor) env: DWP_VIM_VERSION --ref a tag, branch or commit (DWP_VIM_REF=main follows main) env: DWP_VIM_REF Install: --dir config directory (default ~/.config/nvim) env: DWP_VIM_DIR --skip-packages install no system package (images, CI) env: DWP_VIM_SKIP_PACKAGES=1 --nvim install that Neovim release into ~/.local/opt/nvim-vX.Y.Z, linked as ~/.local/bin/nvim, sha256-verified env: DWP_VIM_NVIM --strict fail (non-zero) when the headless plugin install fails, leaves required plugins missing or empty, or any plugin HEAD differs from pckr/lockfile.lua env: DWP_VIM_STRICT=1 --yes move an existing foreign config aside without asking (backup: ~/.config/previous-deepworkplan-vim) env: DWP_VIM_YES=1 -h, --help show this help Precedence: a flag beats every environment value; then DWP_VIM_VERSION, then DWP_VIM_REF, then this script's release. A version and a ref given at the same level (two flags, or two env values) that disagree are an error. Switch values: 1/true/yes/on or 0/false/no/off (any case); anything else is an error. Images and CI (download, verify, then run): bash install.sh --version 0.7.0 --nvim 0.12.5 --skip-packages --strict USAGE } usage_error() { printf 'install.sh: %s\n\n' "$1" >&2 usage >&2 exit 2 } # Env twins of the switches: 1/true/yes/on mean on; unset, empty, # 0/false/no/off mean off (any case). Anything else is an error — never a # guess (DWP_VIM_YES=N must not mean yes). switch_env() { # switch_env -> prints 1 or 0 (bash 3.2: no ${v,,}) case "$2" in 1 | [Tt][Rr][Uu][Ee] | [Yy][Ee][Ss] | [Oo][Nn]) printf '1' ;; '' | 0 | [Ff][Aa][Ll][Ss][Ee] | [Nn][Oo] | [Oo][Ff][Ff]) printf '0' ;; *) usage_error "$1='$2' is not a switch value — use 1/true/yes/on or 0/false/no/off" ;; esac } # The token for --nvim's release lookup is captured once and removed from # the environment: install.lua, Neovim and plugin build hooks never see it. NVIM_API_TOKEN="${GITHUB_TOKEN:-}" unset GITHUB_TOKEN GH_TOKEN if [ -n "$NVIM_API_TOKEN" ] && ! [[ "$NVIM_API_TOKEN" =~ ^[A-Za-z0-9_.-]+$ ]]; then printf 'install.sh: GITHUB_TOKEN has unexpected characters — ignored\n' >&2 NVIM_API_TOKEN="" fi ENV_VERSION="${DWP_VIM_VERSION:-}" ENV_REF="${DWP_VIM_REF:-}" FLAG_VERSION="" FLAG_REF="" DEST="${DWP_VIM_DIR:-$HOME/.config/nvim}" SKIP_PACKAGES="$(switch_env DWP_VIM_SKIP_PACKAGES "${DWP_VIM_SKIP_PACKAGES:-}")" STRICT="$(switch_env DWP_VIM_STRICT "${DWP_VIM_STRICT:-}")" NVIM_VERSION="${DWP_VIM_NVIM:-}" ASSUME_YES="$(switch_env DWP_VIM_YES "${DWP_VIM_YES:-}")" # A value option's value: never empty, never another option. opt_value() { # opt_value