- Sync --all with async concurrency, per-host throttling, failure budgets, resumable execution - External ref bundling at fetch time with origin tracking - Cross-alias discovery (--all-aliases) for list and search commands - CI/CD pipeline (.gitlab-ci.yml), cargo-deny config, Dockerfile, install script - Reliability test suite: crash consistency (8 tests), lock contention (3 tests), property-based (4 tests) - Criterion performance benchmarks (5 benchmarks) - Bug fix: doctor --fix now repairs missing index.json when raw.json exists - Bug fix: shared $ref references no longer incorrectly flagged as circular (refs.rs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
187 lines
5.3 KiB
Bash
Executable File
187 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# swagger-cli installer
|
|
# Downloads the correct binary for your platform, verifies its checksum,
|
|
# and installs it to /usr/local/bin or ~/.local/bin.
|
|
|
|
REPO_URL="${SWAGGER_CLI_REPO_URL:-https://gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/generic/swagger-cli}"
|
|
VERSION="${SWAGGER_CLI_VERSION:-latest}"
|
|
|
|
# --- Helpers ---------------------------------------------------------------
|
|
|
|
die() {
|
|
printf 'Error: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
info() {
|
|
printf ' %s\n' "$1"
|
|
}
|
|
|
|
# --- Secure temp directory with cleanup trap --------------------------------
|
|
|
|
TMPDIR_INSTALL="$(mktemp -d)"
|
|
trap 'rm -rf "${TMPDIR_INSTALL}"' EXIT INT TERM
|
|
|
|
# --- OS / arch detection ----------------------------------------------------
|
|
|
|
detect_os() {
|
|
local os
|
|
os="$(uname -s)"
|
|
case "${os}" in
|
|
Darwin) echo "apple-darwin" ;;
|
|
Linux) echo "unknown-linux-gnu" ;;
|
|
*) die "Unsupported operating system: ${os}. Only macOS and Linux are supported." ;;
|
|
esac
|
|
}
|
|
|
|
detect_arch() {
|
|
local arch
|
|
arch="$(uname -m)"
|
|
case "${arch}" in
|
|
x86_64|amd64) echo "x86_64" ;;
|
|
arm64|aarch64) echo "aarch64" ;;
|
|
*) die "Unsupported architecture: ${arch}. Only x86_64 and aarch64 are supported." ;;
|
|
esac
|
|
}
|
|
|
|
# --- Checksum verification -------------------------------------------------
|
|
|
|
verify_checksum() {
|
|
local file="$1"
|
|
local checksums_file="$2"
|
|
local basename
|
|
basename="$(basename "${file}")"
|
|
|
|
local expected
|
|
expected="$(grep "${basename}" "${checksums_file}" | awk '{print $1}')"
|
|
|
|
if [ -z "${expected}" ]; then
|
|
die "No checksum found for ${basename} in SHA256SUMS"
|
|
fi
|
|
|
|
local actual
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
actual="$(sha256sum "${file}" | awk '{print $1}')"
|
|
elif command -v shasum >/dev/null 2>&1; then
|
|
actual="$(shasum -a 256 "${file}" | awk '{print $1}')"
|
|
else
|
|
die "Neither sha256sum nor shasum found. Cannot verify checksum."
|
|
fi
|
|
|
|
if [ "${actual}" != "${expected}" ]; then
|
|
die "Checksum mismatch for ${basename}: expected ${expected}, got ${actual}"
|
|
fi
|
|
|
|
info "Checksum verified: ${basename}"
|
|
}
|
|
|
|
# --- Optional minisign verification -----------------------------------------
|
|
|
|
verify_signature() {
|
|
local checksums_file="$1"
|
|
local sig_file="${checksums_file}.minisig"
|
|
|
|
if [ ! -f "${sig_file}" ]; then
|
|
info "No signature file found; skipping signature verification."
|
|
return 0
|
|
fi
|
|
|
|
if ! command -v minisign >/dev/null 2>&1; then
|
|
info "minisign not found; skipping signature verification."
|
|
info "Install minisign to enable: https://jedisct1.github.io/minisign/"
|
|
return 0
|
|
fi
|
|
|
|
if [ -z "${SWAGGER_CLI_MINISIGN_PUBKEY:-}" ]; then
|
|
info "SWAGGER_CLI_MINISIGN_PUBKEY not set; skipping signature verification."
|
|
return 0
|
|
fi
|
|
|
|
minisign -V -P "${SWAGGER_CLI_MINISIGN_PUBKEY}" -m "${checksums_file}" \
|
|
|| die "Signature verification failed for SHA256SUMS"
|
|
|
|
info "Signature verified: SHA256SUMS"
|
|
}
|
|
|
|
# --- Install location -------------------------------------------------------
|
|
|
|
select_install_dir() {
|
|
if [ -w /usr/local/bin ]; then
|
|
echo "/usr/local/bin"
|
|
else
|
|
local user_bin="${HOME}/.local/bin"
|
|
mkdir -p "${user_bin}"
|
|
echo "${user_bin}"
|
|
fi
|
|
}
|
|
|
|
check_path() {
|
|
local dir="$1"
|
|
case ":${PATH}:" in
|
|
*":${dir}:"*) ;;
|
|
*)
|
|
printf '\nWarning: %s is not in your PATH.\n' "${dir}"
|
|
printf 'Add it with: export PATH="%s:${PATH}"\n' "${dir}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# --- Download ---------------------------------------------------------------
|
|
|
|
download() {
|
|
local url="$1"
|
|
local output="$2"
|
|
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl --fail --silent --location --output "${output}" "${url}"
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
wget --quiet --output-document="${output}" "${url}"
|
|
else
|
|
die "Neither curl nor wget found. Cannot download."
|
|
fi
|
|
}
|
|
|
|
# --- Main -------------------------------------------------------------------
|
|
|
|
main() {
|
|
local os arch target binary_name download_base
|
|
|
|
printf 'Installing swagger-cli %s\n' "${VERSION}"
|
|
|
|
os="$(detect_os)"
|
|
arch="$(detect_arch)"
|
|
target="${arch}-${os}"
|
|
binary_name="swagger-cli-${target}"
|
|
download_base="${REPO_URL}/${VERSION}"
|
|
|
|
info "Detected platform: ${target}"
|
|
|
|
# Download binary and checksums
|
|
info "Downloading ${binary_name}..."
|
|
download "${download_base}/${binary_name}" "${TMPDIR_INSTALL}/${binary_name}"
|
|
download "${download_base}/SHA256SUMS" "${TMPDIR_INSTALL}/SHA256SUMS"
|
|
|
|
# Attempt to download signature file (optional)
|
|
download "${download_base}/SHA256SUMS.minisig" "${TMPDIR_INSTALL}/SHA256SUMS.minisig" 2>/dev/null || true
|
|
|
|
# Verify
|
|
verify_checksum "${TMPDIR_INSTALL}/${binary_name}" "${TMPDIR_INSTALL}/SHA256SUMS"
|
|
verify_signature "${TMPDIR_INSTALL}/SHA256SUMS"
|
|
|
|
# Install
|
|
local install_dir
|
|
install_dir="$(select_install_dir)"
|
|
|
|
install -m 755 "${TMPDIR_INSTALL}/${binary_name}" "${install_dir}/swagger-cli"
|
|
|
|
info "Installed to ${install_dir}/swagger-cli"
|
|
check_path "${install_dir}"
|
|
|
|
printf '\nswagger-cli %s installed successfully.\n' "${VERSION}"
|
|
printf 'Run "swagger-cli --help" to get started.\n'
|
|
}
|
|
|
|
main "$@"
|