cloverleaf-larry/bin/_nc_common.sh
Clover 400398ca7d v0.9.6: help canonical + prefix-free short commands (nc-find→nfind guard) + HCISITEDIR auto-init
Hands-on ergonomics for Bryan's Gundersen testing. All three changes are
backward-compatible — every old name still works.

1. `help` is now the canonical reference command (live, never-drifts table
   from bin/ + each tool's help block). `cheat` kept as a thin alias.

2. Prefix-free short commands: nc-table→table, nc-parse→parse, nc-msgs→msgs,
   nc-status→status, nc-engine→engine, nc-xlate→xlate, nc-inbound→inbound, plus
   the write tools (create-thread, set-field, insert-protocol, make-jump,
   provision-jumps, tclgen, document, revisions, diff-interface, smat-diff,
   regression). COLLISION GUARD: nc-find→`nfind` (NOT `find` — would shadow the
   system find on PATH); nc-paths keeps `paths`. Every nc-* name retained as a
   backward-compat alias. Tab-completion + the help/cheat table updated.

3. HCISITEDIR auto-init in the shared preflight (bin/_nc_common.sh): HCIROOT +
   HCISITE still required, but $HCIROOT/$HCISITE is created if missing rather
   than erroring. Conservative + idempotent; respects an operator-set HCISITEDIR.

VERSION→0.9.6, MANIFEST regenerated (--check clean), bash -n clean.

Co-Authored-By: Clover (Claude Opus 4.8) <noreply@anthropic.com>
2026-06-08 20:21:32 -07:00

112 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# _nc_common.sh — shared resolver sourced by every bin/ short-command wrapper
# AND by the bash-completion script (bin/nc-completion.bash).
#
# It is NOT a standalone tool — it only defines helpers. The wrappers are thin:
# they resolve the lib/ toolkit dir, then exec the right lib/nc-*.sh with the
# user's args mapped to that tool's flags. Putting the wrappers on PATH is what
# makes `tbn adt` work directly (no `larry tools` / `nc-larry` prefix).
#
# Resolution order for the lib/ dir (first hit wins):
# 1. $LARRY_LIB_DIR if set and valid
# 2. <dir-of-this-bin>/../lib (repo layout: bin/.. /lib)
# 3. $LARRY_HOME/lib (installed layout)
# 4. <dir-of-this-bin>/../../lib (defensive: bin symlinked one level deeper)
#
# Site/thread enumeration is LIVE off the NetConfig tree under $HCIROOT, reusing
# the SAME parser the tools use (lib/nc-parse.sh) so completion can never drift
# from what the tools actually see.
# --- lib/ dir resolution -----------------------------------------------------
_nc_resolve_lib() {
if [ -n "${LARRY_LIB_DIR:-}" ] && [ -f "$LARRY_LIB_DIR/nc-parse.sh" ]; then
printf '%s' "$LARRY_LIB_DIR"; return 0
fi
# dir of the *real* file backing this source (follow one symlink level)
local src="${BASH_SOURCE[0]}"
if [ -L "$src" ]; then src="$(readlink "$src")"; fi
local bindir
bindir="$(cd "$(dirname "$src")" 2>/dev/null && pwd)"
local c
for c in "$bindir/../lib" "${LARRY_HOME:-$HOME/.larry}/lib" "$bindir/../../lib"; do
if [ -d "$c" ] && [ -f "$c/nc-parse.sh" ]; then
( cd "$c" && pwd ); return 0
fi
done
return 1
}
# --- HCIROOT resolution (env, then a couple of sane fallbacks) ----------------
_nc_hciroot() {
if [ -n "${HCIROOT:-}" ] && [ -d "$HCIROOT" ]; then printf '%s' "$HCIROOT"; return 0; fi
printf '%s' "${HCIROOT:-}"; return 0
}
# --- HCISITEDIR auto-init (v0.9.6) -------------------------------------------
# Contract: $HCIROOT and $HCISITE are expected to ALREADY exist — the tools
# themselves still error if those are unset/missing (that check is intentional
# and unchanged). But $HCISITEDIR ("$HCIROOT/$HCISITE") is a DERIVED path the
# operator may not have created yet. Rather than letting a downstream tool die
# on a missing site dir, we materialize it here, in the one preflight every
# short-command wrapper sources.
#
# Safety rails (deliberately conservative — we never invent a path):
# • Only acts when BOTH $HCIROOT and $HCISITE are non-empty AND $HCIROOT is a
# real directory. If HCIROOT/HCISITE are unset/bogus we do NOTHING and let
# the tool's own preflight produce its usual, clearer error.
# • If $HCISITEDIR is already exported we respect it verbatim (operator override).
# • Creates the dir only if missing; idempotent; mkdir failure is non-fatal
# (warn once to stderr) so a read-only/edge env still reaches the tool.
# • Always exports HCISITEDIR so the backing lib tools (which read it) see it.
_nc_init_sitedir() {
# Respect an explicit operator-set HCISITEDIR.
if [ -n "${HCISITEDIR:-}" ]; then export HCISITEDIR; return 0; fi
local root="${HCIROOT:-}" site="${HCISITE:-}"
# Both must be present and HCIROOT must really exist — otherwise stay silent
# and let the tool's own "no \$HCIROOT / set HCISITE" error fire.
[ -n "$root" ] && [ -n "$site" ] && [ -d "$root" ] || return 0
local sitedir="$root/$site"
if [ ! -d "$sitedir" ]; then
if mkdir -p "$sitedir" 2>/dev/null; then
printf 'cloverleaf-larry: created missing HCISITEDIR %s\n' "$sitedir" >&2
else
printf 'cloverleaf-larry: warning — could not create HCISITEDIR %s (continuing)\n' "$sitedir" >&2
# still export the intended value; the tool will report the real problem.
fi
fi
export HCISITEDIR="$sitedir"
return 0
}
# Run at source time so every wrapper that dots this file gets HCISITEDIR ready
# before it execs the backing lib tool.
_nc_init_sitedir
# --- live site enumeration ----------------------------------------------------
# A "site" = an immediate subdir of $HCIROOT that contains a NetConfig file.
# This is what nc-find / nc-paths actually walk, so completion stays truthful.
_nc_sites() {
local root; root="$(_nc_hciroot)"
[ -n "$root" ] && [ -d "$root" ] || return 0
local d
for d in "$root"/*/; do
[ -f "${d}NetConfig" ] && basename "${d%/}"
done 2>/dev/null
}
# --- live thread enumeration --------------------------------------------------
# Every protocol (thread) name across every site's NetConfig, deduped. Uses the
# library parser so it matches the tools' view exactly. Optional arg = restrict
# to one site.
_nc_threads() {
local only_site="${1:-}"
local root lib; root="$(_nc_hciroot)"; lib="$(_nc_resolve_lib)" || return 0
[ -n "$root" ] && [ -d "$root" ] || return 0
local nc site
for nc in "$root"/*/NetConfig; do
[ -f "$nc" ] || continue
site="$(basename "$(dirname "$nc")")"
[ -n "$only_site" ] && [ "$site" != "$only_site" ] && continue
bash "$lib/nc-parse.sh" list-protocols "$nc" 2>/dev/null
done | sort -u
}