117 lines
3.8 KiB
Bash
Executable File
117 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# shellcheck shell=bash
|
|
#
|
|
# Shared helpers sourced by every script in this directory.
|
|
# . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
|
|
#
|
|
# Requires bash 4+ and coreutils.
|
|
|
|
set -euo pipefail
|
|
|
|
# ---- paths ----------------------------------------------------------
|
|
LOCAL_BIN="${HOME}/.local/bin"
|
|
CRED_HELPER="${LOCAL_BIN}/git-credential-forge"
|
|
|
|
# Canonical OAuth auth store: matches
|
|
# forge-stack-devpi-gateway-gitea/client_auth.auth_store_path() exactly.
|
|
FORGE_AUTH_DIR="${FSDGG_RUNTIME_DIR:-${HOME}/.forge-stack-devpi-gateway-gitea}"
|
|
FORGE_AUTH_FILE="${FSDGG_AUTH_STORE_PATH:-${FORGE_AUTH_DIR}/client-auth.json}"
|
|
|
|
# ---- colors / logging ----------------------------------------------
|
|
# ANSI enabled only when stderr is a TTY, NO_COLOR is unset, and
|
|
# TERM != "dumb"; empty strings otherwise (piped output byte-identical).
|
|
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-dumb}" != "dumb" ]; then
|
|
_FC_RESET=$'\e[0m'
|
|
_FC_BOLD=$'\e[1m'
|
|
_FC_DIM=$'\e[2m'
|
|
_FC_RED=$'\e[31m'
|
|
_FC_GREEN=$'\e[32m'
|
|
_FC_YELLOW=$'\e[33m'
|
|
_FC_CYAN=$'\e[36m'
|
|
_FC_MAGENTA=$'\e[35m'
|
|
else
|
|
_FC_RESET=''; _FC_BOLD=''; _FC_DIM=''
|
|
_FC_RED=''; _FC_GREEN=''; _FC_YELLOW=''
|
|
_FC_CYAN=''; _FC_MAGENTA=''
|
|
fi
|
|
|
|
# Width-6 tag inside ANSI envelope: pads "[ok]", "[err]" etc. to 6
|
|
# visible columns so subsequent %-wNs fields stay aligned.
|
|
_fc_tag() { printf '%s%-6s%s' "$1" "[$2]" "$_FC_RESET"; }
|
|
|
|
info() { printf '%s %s\n' "$(_fc_tag "$_FC_CYAN" info)" "$*" >&2; }
|
|
ok() { printf '%s %s\n' "$(_fc_tag "$_FC_GREEN" ok )" "$*" >&2; }
|
|
warn() { printf '%s %s\n' "$(_fc_tag "$_FC_YELLOW" warn)" "$*" >&2; }
|
|
err() { printf '%s %s\n' "$(_fc_tag "$_FC_RED" err )" "$*" >&2; }
|
|
step() { printf '\n%s==>%s %s%s%s\n' "$_FC_BOLD" "$_FC_RESET" "$_FC_BOLD" "$*" "$_FC_RESET" >&2; }
|
|
note() { printf '%s%s%s\n' "$_FC_DIM" "$*" "$_FC_RESET" >&2; }
|
|
die() { err "$@"; exit 1; }
|
|
|
|
# ---- repo locator ---------------------------------------------------
|
|
repo_root() {
|
|
local here
|
|
here="$(cd "$(dirname "${BASH_SOURCE[1]:-$0}")" && pwd -P)"
|
|
local d="$here"
|
|
for _ in 1 2 3; do
|
|
if [ -f "$d/Justfile" ]; then
|
|
printf '%s\n' "$d"
|
|
return 0
|
|
fi
|
|
d="$(dirname "$d")"
|
|
done
|
|
die "cannot locate repo root (Justfile) from $here"
|
|
}
|
|
|
|
# Load $repo/.env into the environment.
|
|
# Existing environment values take precedence (matches just dotenv-load).
|
|
load_env() {
|
|
local root env line key rest
|
|
root="$(repo_root)"
|
|
env="$root/.env"
|
|
[ -f "$env" ] || return 0
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
# Strip CR from CRLF files and leading whitespace.
|
|
line="${line%$'\r'}"
|
|
line="${line#"${line%%[![:space:]]*}"}"
|
|
case "$line" in
|
|
''|'#'*) continue ;;
|
|
*=*) ;;
|
|
*) continue ;;
|
|
esac
|
|
# Optional leading `export `.
|
|
line="${line#export }"
|
|
key="${line%%=*}"
|
|
rest="${line#*=}"
|
|
# Skip malformed keys.
|
|
case "$key" in
|
|
*[!A-Za-z0-9_]*|'') continue ;;
|
|
esac
|
|
# Existing env values win.
|
|
if [ -n "${!key+x}" ]; then
|
|
continue
|
|
fi
|
|
# Strip matching surrounding single or double quotes.
|
|
case "$rest" in
|
|
\"*\") rest="${rest#\"}"; rest="${rest%\"}" ;;
|
|
\'*\') rest="${rest#\'}"; rest="${rest%\'}" ;;
|
|
esac
|
|
export "$key=$rest"
|
|
done < "$env"
|
|
}
|
|
|
|
# ---- prereq checks --------------------------------------------------
|
|
require_cmd() {
|
|
local cmd="$1" hint="${2:-}"
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
[ -n "$hint" ] && warn "install hint: $hint"
|
|
die "required command not found: $cmd"
|
|
fi
|
|
}
|
|
|
|
require_env() {
|
|
local name="$1"
|
|
if [ -z "${!name:-}" ]; then
|
|
die "environment variable '$name' is unset. Run 'just init-env' and set it in .env."
|
|
fi
|
|
}
|