Something went wrong. Try again.
infra stuff in gleam
gleam atproto lexicon codegen oauth
Something went wrong. Try again.
3.3 kB · 86 lines
Shell
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687#!/usr/bin/env bash# Release guard for gleam.toml dependencies. Bash builtins only: the CI image has no grep.# 1. no path dependencies (Hex rejects them, so they block every release of the package)# 2. a dependency on a sibling package needs an upper bound on a minor boundary:# `>= 0.2.0 and < 0.3.0` (several minors are fine: `>= 0.1.1 and < 0.3.0`),# never `< 1.0.0` from a 0.x lower bound. From 1.x: `< (M+1).0.0`.# `or` clauses are accepted and each clause is checked on its own.# Usage: depcheck.sh [package-dir...] (default: every gleam.toml in the repo)set -ushopt -s nullglobcd "${BASH_SOURCE[0]%/*}/.." || exit 1
manifests=(*/gleam.toml */*/gleam.toml)declare -A siblings=()errors=0
fail() { echo "depcheck: $1: $2" >&2 errors=$((errors + 1))}
read_name() { local line while IFS= read -r line; do [[ "$line" =~ ^name[[:space:]]*=[[:space:]]*\"([^\"]+)\" ]] && { echo "${BASH_REMATCH[1]}"; return; } done <"$1"}
for f in "${manifests[@]}"; do n="$(read_name "$f")" [[ -n "$n" ]] && siblings[$n]=1done
((${#@} > 0)) && manifests=("${@/%//gleam.toml}")
# returns 0 when the upper bound `< U` is a minor boundary past the lower bound:# 0.x lower: `< 0.k.0` with k above the lower minor (never `< 1.0.0`);# 1.x+ lower: `< (M+1).0.0`, or `< M.k.0` with k above the lower minor.capped() { local lmaj=$1 lmin=$2 umaj=$3 umin=$4 upatch=$5 ((upatch == 0)) || return 1 ((lmaj == 0)) && return $((!(umaj == 0 && umin > lmin))) ((umaj == lmaj + 1 && umin == 0)) || ((umaj == lmaj && umin > lmin))}
check_clause() { local file=$1 dep=$2 clause=$3 local re='^[[:space:]]*>=[[:space:]]*([0-9]+)\.([0-9]+)\.([0-9]+)[[:space:]]+and[[:space:]]+<[[:space:]]*([0-9]+)\.([0-9]+)\.([0-9]+)[[:space:]]*$' [[ "$clause" =~ $re ]] || { fail "$file" "$dep: unsupported or unbounded requirement '$clause' (want '>= X.Y.Z and < A.B.C')"; return; } capped "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[4]}" "${BASH_REMATCH[5]}" "${BASH_REMATCH[6]}" \ || fail "$file" "$dep: '$clause' has no valid upper bound; use a minor boundary above the lower bound (0.x: < 0.k.0, never < 1.0.0; 1.x: < (M+1).0.0)"}
check_requirement() { local file=$1 dep=$2 req=$3 clause clause="${req//\"/}" while [[ "$clause" == *" or "* ]]; do check_clause "$file" "$dep" "${clause%% or *}" clause="${clause#* or }" done check_clause "$file" "$dep" "$clause"}
for f in "${manifests[@]}"; do [[ -f "$f" ]] || { fail "$f" "no such manifest"; continue; } section="" while IFS= read -r line || [[ -n "$line" ]]; do if [[ "$line" =~ ^\[([^]]+)\][[:space:]]*$ ]]; then section="${BASH_REMATCH[1]}" continue fi [[ "$section" == "dependencies" || "$section" == "dev_dependencies" ]] || continue [[ "$line" =~ ^([A-Za-z0-9_]+)[[:space:]]*=[[:space:]]*(.*)$ ]] || continue dep="${BASH_REMATCH[1]}" value="${BASH_REMATCH[2]}" if [[ "$value" =~ ^\{.*path[[:space:]]*= ]]; then fail "$f" "$dep: path dependency ($value)" continue fi [[ -n "${siblings[$dep]:-}" && "$value" == \"* ]] && check_requirement "$f" "$dep" "$value" done <"$f"done
((errors == 0)) && { echo "depcheck: ok (${#manifests[@]} manifests)"; exit 0; }echo "depcheck: $errors problem(s)" >&2exit 1