check / check (push) Waiting to run
script/bootstrap --cgo installs vips-jxl on Alpine, where libvips' JPEG XL loader and saver are a package of their own; the nix and brew libvips include them, as does apt's from Debian 12 and Ubuntu 24.04 on. The runtime stage of the Dockerfile installs vips-jxl too. imageprocessor.New now returns an error when libvips cannot load and save JPEG XL, and NewService passes it on, so pixad does not start without that support. JPEG XL becomes the default output later in the issue, which a pixad without it could not serve. A new test saves an image as JPEG XL with govips and loads it back. Model: opus-5-5
200 lines
6.2 KiB
Bash
Executable File
200 lines
6.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/bootstrap: install all dependencies needed to build and develop
|
|
# this repo. Idempotent: every install is guarded by a check so already
|
|
# installed tools are skipped. Base tooling comes from nix, apt, brew,
|
|
# or apk (detected in that order); assumes NOTHING is present (not git,
|
|
# make, or go). Node is used directly if installed; otherwise it is
|
|
# installed at a pinned version via nvm (installing nvm itself first,
|
|
# from a hash-verified release archive, never curl | sh). The linter is
|
|
# never installed on the host: golangci-lint runs only in the lint phase
|
|
# of the Dockerfile (see script/lint).
|
|
#
|
|
# script/bootstrap git, make, Go, and Node, Yarn and the
|
|
# prettier in yarn.lock for script/fmt and
|
|
# script/fmt-check: all the host needs, as
|
|
# the checks compile pixa in Docker
|
|
# script/bootstrap --cgo git, make, Go, and a C compiler and the
|
|
# CGO image libraries (pkg-config, vips
|
|
# with its JPEG XL support, libheif) for
|
|
# the govips bindings instead of Node: to
|
|
# compile pixa, in the Dockerfile's test
|
|
# phase and build stage, which format
|
|
# nothing
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
# Pinned versions, 2026-07-06
|
|
NODE_VERSION="22.17.0"
|
|
NVM_VERSION="0.40.3"
|
|
# sha256 of https://github.com/nvm-sh/nvm/archive/refs/tags/v0.40.3.tar.gz
|
|
NVM_SHA256="5f4d6aaa04a177dc93c985e31dbc411ab6b8c6e1e21d8015dbc1372625fcd1d0"
|
|
YARN_VERSION="1.22.22"
|
|
|
|
PKGMGR=""
|
|
SUDO=""
|
|
|
|
detect_pkgmgr() {
|
|
[ -n "$PKGMGR" ] && return 0
|
|
if command -v nix-env >/dev/null 2>&1; then
|
|
PKGMGR="nix"
|
|
elif command -v apt-get >/dev/null 2>&1; then
|
|
PKGMGR="apt"
|
|
elif command -v brew >/dev/null 2>&1; then
|
|
PKGMGR="brew"
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
PKGMGR="apk"
|
|
else
|
|
echo "bootstrap: no supported package manager (nix, apt, brew, apk)" >&2
|
|
exit 1
|
|
fi
|
|
if [ "$PKGMGR" = "apt" ]; then
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
if [ "$(id -u)" != "0" ]; then
|
|
SUDO="sudo"
|
|
fi
|
|
# This runs before the first install only. A fresh image, such
|
|
# as a CI runner's, has no package lists, and apt-get install
|
|
# finds no package without them.
|
|
$SUDO apt-get update
|
|
fi
|
|
}
|
|
|
|
# pkg_install <nix-attr> <apt-pkg> <brew-formula> <apk-pkg>
|
|
pkg_install() {
|
|
detect_pkgmgr
|
|
case "$PKGMGR" in
|
|
nix) nix-env -iA "nixpkgs.$1" ;;
|
|
apt) $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y "$2" ;;
|
|
brew) brew install "$3" ;;
|
|
apk) apk add --no-cache "$4" ;;
|
|
esac
|
|
}
|
|
|
|
missing() {
|
|
! command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
# verify_sha256 <file> <expected-hash>
|
|
verify_sha256() {
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
actual="$(sha256sum "$1" | cut -d' ' -f1)"
|
|
else
|
|
actual="$(shasum -a 256 "$1" | cut -d' ' -f1)"
|
|
fi
|
|
if [ "$actual" != "$2" ]; then
|
|
echo "bootstrap: sha256 mismatch for $1" >&2
|
|
echo " expected: $2" >&2
|
|
echo " actual: $actual" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# nvm is a bash script; run a command in a bash with nvm loaded
|
|
nvm_sh() {
|
|
bash -c ". \"\$HOME/.nvm/nvm.sh\" && $*"
|
|
}
|
|
|
|
ensure_nvm() {
|
|
[ -s "$HOME/.nvm/nvm.sh" ] && return 0
|
|
# nvm prerequisites; nvm itself requires bash
|
|
if missing bash; then pkg_install bash bash bash bash; fi
|
|
if missing curl; then pkg_install curl curl curl curl; fi
|
|
if missing git; then pkg_install git git git git; fi
|
|
tmp="$(mktemp -d)"
|
|
curl -fsSL -o "$tmp/nvm.tar.gz" \
|
|
"https://github.com/nvm-sh/nvm/archive/refs/tags/v${NVM_VERSION}.tar.gz"
|
|
verify_sha256 "$tmp/nvm.tar.gz" "$NVM_SHA256"
|
|
mkdir -p "$HOME/.nvm"
|
|
tar -xzf "$tmp/nvm.tar.gz" -C "$HOME/.nvm" --strip-components=1
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
ensure_node() {
|
|
if ! missing node; then return 0; fi
|
|
ensure_nvm
|
|
nvm_sh "nvm install $NODE_VERSION"
|
|
}
|
|
|
|
ensure_yarn() {
|
|
if ! missing yarn; then return 0; fi
|
|
if ! missing corepack; then
|
|
corepack enable
|
|
corepack prepare "yarn@$YARN_VERSION" --activate
|
|
elif [ -s "$HOME/.nvm/nvm.sh" ]; then
|
|
nvm_sh "nvm use $NODE_VERSION >/dev/null && corepack enable && \
|
|
corepack prepare yarn@$YARN_VERSION --activate"
|
|
else
|
|
npm install -g "yarn@$YARN_VERSION"
|
|
fi
|
|
}
|
|
|
|
install_js_deps() {
|
|
if missing yarn && [ -s "$HOME/.nvm/nvm.sh" ]; then
|
|
nvm_sh "nvm use $NODE_VERSION >/dev/null && cd \"$ROOT\" && \
|
|
yarn install --frozen-lockfile"
|
|
else
|
|
yarn install --frozen-lockfile
|
|
fi
|
|
}
|
|
|
|
# CGO dependencies for govips (image processing)
|
|
ensure_cgo_deps() {
|
|
# cgo compiles with gcc on Linux; build-base and build-essential
|
|
# also bring the C library headers.
|
|
if missing gcc; then
|
|
pkg_install gcc build-essential gcc build-base
|
|
fi
|
|
if missing pkg-config; then
|
|
pkg_install pkg-config pkg-config pkg-config pkgconfig
|
|
fi
|
|
if ! pkg-config --exists vips; then
|
|
pkg_install vips libvips-dev vips vips-dev
|
|
fi
|
|
# libvips' JPEG XL loader and saver are in the nix and brew vips
|
|
# packages, and in apt's from Debian 12 and Ubuntu 24.04 on, but in a
|
|
# package of their own on Alpine.
|
|
if command -v apk >/dev/null 2>&1 && ! apk info -e vips-jxl >/dev/null; then
|
|
apk add --no-cache vips-jxl
|
|
fi
|
|
if ! pkg-config --exists libheif; then
|
|
pkg_install libheif libheif-dev libheif libheif-dev
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
echo "usage: script/bootstrap [--cgo]" >&2
|
|
exit 2
|
|
}
|
|
|
|
main() {
|
|
case "$*" in
|
|
"" | --cgo) ;;
|
|
*) usage ;;
|
|
esac
|
|
cd "$ROOT"
|
|
|
|
# Base tooling
|
|
if missing git; then pkg_install git git git git; fi
|
|
if missing make; then pkg_install gnumake make make make; fi
|
|
|
|
# Go toolchain
|
|
if missing go; then pkg_install go golang go go; fi
|
|
|
|
# CGO image libraries where pixa is compiled; elsewhere Node, Yarn
|
|
# and prettier
|
|
if [ "$*" = "--cgo" ]; then
|
|
ensure_cgo_deps
|
|
else
|
|
ensure_node
|
|
ensure_yarn
|
|
install_js_deps
|
|
fi
|
|
|
|
go mod download
|
|
|
|
echo "bootstrap complete"
|
|
}
|
|
|
|
main "$@"
|