remove profile dependency
This commit is contained in:
@@ -20,8 +20,9 @@
|
||||
# resolves relative to the entry point. Libraries may source further
|
||||
# libraries however they like — bash follows those itself.
|
||||
# 3. Configuration enters through `load_config`, and the libraries provide
|
||||
# `config_profiles` and `config_freeze <profile>` — the latter prints a
|
||||
# replacement load_config with that profile resolved. How config is layered,
|
||||
# `config_profiles`, `config_freeze <profile|--current>` — which prints a
|
||||
# replacement load_config with that resolution frozen in — and, for an
|
||||
# export, `config_current_profile` and `config_left_out`. How config is layered,
|
||||
# stored, derived or frozen is rig's business; this only asks, and embeds
|
||||
# the answer without interpreting it.
|
||||
#
|
||||
@@ -36,8 +37,16 @@
|
||||
# line and what is wrong. It never writes a kit that only looks finished.
|
||||
#
|
||||
# Usage:
|
||||
# standalone.sh write generate every kit into standalone/<profile>/
|
||||
# standalone.sh check generate into a scratch dir and fail if any kit differs
|
||||
# standalone.sh write generate every kit into standalone/<profile>/
|
||||
# standalone.sh check generate into a scratch dir and fail if any kit differs
|
||||
# standalone.sh export DIR ONE kit for the configuration this machine runs —
|
||||
# its profile plus the choices in its local config,
|
||||
# WITHOUT its credentials — written outside the repo.
|
||||
#
|
||||
# write and check are what gets committed: one kit per profile, identical on any
|
||||
# machine. export is the other question — "take the setup I have here somewhere
|
||||
# else" — so it reflects this machine, and for exactly that reason it never lands
|
||||
# in the repository.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
@@ -47,6 +56,11 @@ OUT="$ROOT/standalone"
|
||||
SELF_REL="ctrl/${0##*/}"
|
||||
|
||||
GENERATED_TAG="GENERATED by make standalone — do not edit"
|
||||
|
||||
# The contract's own functions: questions rig answers FOR this generator. They
|
||||
# are never carried into a kit — load_config is replaced by the frozen one, and
|
||||
# the rest mean nothing without rig's tree. The only names this file knows.
|
||||
CONTRACT_FUNCS="load_config config_profiles config_snapshot config_freeze config_current_profile config_left_out"
|
||||
FROZEN_OPEN="# ── configuration, frozen"
|
||||
FROZEN_CLOSE="# ── end of frozen configuration"
|
||||
|
||||
@@ -54,7 +68,7 @@ refuse() { echo >&2; echo "standalone: refusing — $*" >&2; exit 1; }
|
||||
|
||||
# A clean bash with nothing from the caller's shell in it. What the kit carries
|
||||
# must not depend on who ran the generator or what they had exported.
|
||||
clean_bash() { env -i PATH="$PATH" HOME="$HOME" bash --noprofile --norc "$@"; }
|
||||
clean_bash() { env -i PATH="$PATH" HOME="$HOME" CONTRACT_FUNCS="$CONTRACT_FUNCS" bash --noprofile --norc "$@"; }
|
||||
|
||||
# ── 1. entry points ────────────────────────────────────────────────────────
|
||||
entries() {
|
||||
@@ -104,7 +118,7 @@ libs_into() {
|
||||
lib_defs() { # entry lib... -> declare -p globals, then declare -f functions
|
||||
local entry="$1"; shift
|
||||
( cd "$(dirname "$entry")" && clean_bash -c '
|
||||
skip_var() { case "$1" in BASH*|FUNCNAME|PIPESTATUS|LINENO|RANDOM|SRANDOM|SECONDS|EPOCH*|HISTCMD|COLUMNS|LINES|PWD|OLDPWD|_|SHLVL|OPTIND|OPTERR|IFS|PS4|PATH|HOME|v|f|l|before_v|before_f) return 0 ;; esac; return 1; }
|
||||
skip_var() { case "$1" in CONTRACT_FUNCS|BASH*|FUNCNAME|PIPESTATUS|LINENO|RANDOM|SRANDOM|SECONDS|EPOCH*|HISTCMD|COLUMNS|LINES|PWD|OLDPWD|_|SHLVL|OPTIND|OPTERR|IFS|PS4|PATH|HOME|v|f|l|before_v|before_f) return 0 ;; esac; return 1; }
|
||||
before_v=" $(compgen -v | tr "\n" " ") "
|
||||
before_f=" $(compgen -A function | tr "\n" " ") "
|
||||
for l in "$@"; do source "$l" || { echo "__FAIL__ sourcing $l" ; exit 1; }; done
|
||||
@@ -115,7 +129,7 @@ lib_defs() { # entry lib... -> declare -p globals, then declare -f functions
|
||||
done
|
||||
for f in $(compgen -A function); do
|
||||
case "$before_f" in *" $f "*) continue ;; esac
|
||||
case "$f" in skip_var|load_config|config_profiles|config_snapshot|config_freeze) continue ;; esac
|
||||
case " skip_var $CONTRACT_FUNCS " in *" $f "*) continue ;; esac
|
||||
declare -f "$f"
|
||||
done
|
||||
' _ "$@" ) || refuse "$entry: its libraries could not be sourced cleanly"
|
||||
@@ -146,7 +160,7 @@ assemble() { # entry profile out-file lib...
|
||||
echo '#!/usr/bin/env bash'
|
||||
echo "# $GENERATED_TAG"
|
||||
echo "#"
|
||||
echo "# $(basename "$dest") for profile '$profile', flattened from:"
|
||||
echo "# $(basename "$dest") for ${KIT_LABEL:-profile '$profile'}, flattened from:"
|
||||
echo "# ctrl/$entry"
|
||||
local l; for l in ${libs[@]+"${libs[@]}"}; do echo "# ctrl/$l"; done
|
||||
echo "# Edit those and run \`make standalone\`. Changes made here are lost, and"
|
||||
@@ -161,9 +175,9 @@ assemble() { # entry profile out-file lib...
|
||||
|
||||
if [ "$calls_config" = yes ]; then
|
||||
local frozen
|
||||
frozen=$(ask "$entry" ${libs[@]+"${libs[@]}"} -- config_freeze "$profile") \
|
||||
|| refuse "ctrl/$entry calls load_config, but its libraries do not answer config_freeze for '$profile'"
|
||||
echo "$FROZEN_OPEN for profile '$profile' ──"
|
||||
frozen=$(ask "$entry" ${libs[@]+"${libs[@]}"} -- config_freeze "${FREEZE_ARG:-$profile}") \
|
||||
|| refuse "ctrl/$entry calls load_config, but its libraries do not answer config_freeze ${FREEZE_ARG:-$profile}"
|
||||
echo "$FROZEN_OPEN for ${KIT_LABEL:-profile '$profile'} ──"
|
||||
printf '%s\n' "$frozen"
|
||||
echo "$FROZEN_CLOSE ──"
|
||||
echo
|
||||
@@ -337,5 +351,44 @@ case "$cmd" in
|
||||
[ "$stale" -eq 0 ] || { echo "run: make standalone"; exit 1; }
|
||||
echo "every kit is current"
|
||||
;;
|
||||
*) echo "usage: $SELF_REL [write|check]" >&2; exit 1 ;;
|
||||
export)
|
||||
dest="${1:-}"
|
||||
[ -n "$dest" ] || refuse "export needs a directory, outside the repo: make standalone export ~/rig-kit"
|
||||
dest=$(realpath -m "$dest")
|
||||
top=$(git -C "$ROOT" rev-parse --show-toplevel 2>/dev/null || echo "$ROOT")
|
||||
case "$dest/" in
|
||||
"$top"/*) refuse "an export reflects this machine, so it does not go inside the repository — $dest is under $top. The committed per-profile kits are what standalone/ is for." ;;
|
||||
esac
|
||||
if [ -d "$dest" ] && [ -n "$(ls -A "$dest" 2>/dev/null)" ] && ! is_generated_dir "$dest"; then
|
||||
refuse "$dest already holds something that is not a previous export — pick an empty directory"
|
||||
fi
|
||||
|
||||
mapfile -t all_entries < <(entries)
|
||||
[ ${#all_entries[@]} -gt 0 ] || refuse "no script under ctrl/ carries a '# rig:standalone <kit> <verb>' marker"
|
||||
libs_into "${all_entries[0]}"
|
||||
profile=$(ask "${all_entries[0]}" ${libs[@]+"${libs[@]}"} -- config_current_profile) \
|
||||
|| refuse "this machine's configuration does not resolve — run make check"
|
||||
left=$(ask "${all_entries[0]}" ${libs[@]+"${libs[@]}"} -- config_left_out | tr '\n' ' ')
|
||||
|
||||
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
|
||||
echo "exporting the configuration this machine runs (profile '$profile')"
|
||||
FREEZE_ARG=--current
|
||||
KIT_LABEL="the configuration exported from $(hostname -s 2>/dev/null || echo this machine) (profile '$profile', local choices included, credentials not)"
|
||||
for e in "${all_entries[@]}"; do
|
||||
read -r kit verb <<< "$(marker_of "$e")"
|
||||
libs_into "$e"
|
||||
assemble "$e" "$profile" "$tmp/$kit.sh" ${libs[@]+"${libs[@]}"}
|
||||
done
|
||||
makefile "$tmp" "${all_entries[@]}"
|
||||
verify_kit "$tmp" "export" "${all_entries[@]}"
|
||||
|
||||
rm -rf "$dest"; mkdir -p "$(dirname "$dest")"; cp -r "$tmp" "$dest"
|
||||
echo " wrote $dest: $(cd "$dest" && ls | tr '\n' ' ')— verified to stand alone"
|
||||
if [ -n "${left// /}" ]; then
|
||||
echo
|
||||
echo " NOT carried — this machine's own, set them on the target if it needs them:"
|
||||
for k in $left; do echo " $k"; done
|
||||
fi
|
||||
;;
|
||||
*) echo "usage: $SELF_REL [write|check|export DIR]" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user