check / check (push) Waiting to run
script/bootstrap --cgo installs vips-jxl when the package manager it uses is apk, as Alpine's vips package lacks JPEG XL support; the nix and brew libvips include it, as does apt's from Debian 12 and Ubuntu 24.04 on. The runtime stage of the Dockerfile installs vips-jxl too. imgcache.NewService calls the new imageprocessor.CheckJPEGXLSupport before it builds the image processor and fails with its error, which names the fix, so pixad does not start without the support. JPEG XL becomes the default output later in the issue. New tests check the support and save an image as JPEG XL with govips and load it back. Model: opus-5-5
204 lines
6.3 KiB
Bash
Executable File
204 lines
6.3 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
|
|
# the package vips-jxl on Alpine. detect_pkgmgr is called only where
|
|
# apk exists, as on apt it updates the package lists.
|
|
if ! missing apk; then
|
|
detect_pkgmgr
|
|
fi
|
|
if [ "$PKGMGR" = "apk" ] && ! 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 "$@"
|