mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-07 03:15:56 +00:00
`make test-unit` (docker runner) reached run.sh inside the container via `bash --login`, which never sources the project's env-loader. PYTHON stayed unset, so the test invocation fell back to the system python3 — which has none of the runtime deps (ruamel, ansible, bcrypt, requests, certifi, humanfriendly), producing 132+ ModuleNotFoundError errors. run.sh now sources scripts/meta/env/load.sh itself (idempotent via INFINITO_ENV_LOADED), so the env layer applies regardless of how the shell was spawned. While load.sh's detect.sh (now scripts/meta/env/python.sh) correctly walks /opt/venvs and ~/.venvs to find the venv, an ambient VIRTUAL_ENV from a different project (e.g. /root/.venvs/pkgmgr in pkgmgr's container) would hijack the resolution. python.sh now scans the project-named venv candidates first and only falls back to VIRTUAL_ENV when no project venv exists. Also moves scripts/meta/python/detect.sh to scripts/meta/env/python.sh so the env-related helpers live under one directory; updates the load.sh source pragma and the lint-test path that scans it for INFINITO_* registrations. `make test-unit` goes from 1262 tests / 132 errors to 1999 tests / 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.2 KiB
Bash
Executable File
68 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# shellcheck shell=bash
|
|
#
|
|
# Sources `.env` (auto-generates via `python -m cli.meta.env` if missing)
|
|
# with setdefault semantics: caller-set values win over `.env` defaults.
|
|
# Idempotent (INFINITO_ENV_LOADED). INFINITO_ENV_GENERATING short-circuits
|
|
# re-entry from generator subshells (BASH_ENV would otherwise recurse).
|
|
|
|
_infinito_env_repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
|
_infinito_env_dotenv="${_infinito_env_repo_root}/.env"
|
|
|
|
# Re-resolve PYTHON + PATH on every source so a venv created mid-chain takes over.
|
|
# shellcheck source=scripts/meta/env/python.sh
|
|
source "${_infinito_env_repo_root}/scripts/meta/env/python.sh"
|
|
|
|
if [[ -n "${VENV:-}" && -d "${VENV%/}/bin" ]]; then
|
|
case ":${PATH:-}:" in
|
|
*:"${VENV%/}/bin":*) ;;
|
|
*) export PATH="${VENV%/}/bin${PATH:+:${PATH}}" ;;
|
|
esac
|
|
fi
|
|
|
|
if [[ "${INFINITO_ENV_LOADED:-}" == "1" ]]; then # nocheck: env-loader-internal-guard
|
|
unset _infinito_env_repo_root _infinito_env_dotenv
|
|
return 0
|
|
fi
|
|
if [[ "${INFINITO_ENV_GENERATING:-}" == "1" ]]; then # nocheck: env-loader-internal-guard
|
|
unset _infinito_env_repo_root _infinito_env_dotenv
|
|
return 0
|
|
fi
|
|
|
|
if [[ ! -f "${_infinito_env_dotenv}" ]]; then
|
|
(
|
|
cd "${_infinito_env_repo_root}" || exit 1
|
|
export INFINITO_ENV_GENERATING=1
|
|
"${PYTHON}" -m cli.meta.env
|
|
) >&2
|
|
fi
|
|
|
|
# Snapshot caller-set values, restore them after the bulk source (setdefault).
|
|
declare -A _infinito_env_preserved=()
|
|
while IFS= read -r _infinito_env_line; do
|
|
case "${_infinito_env_line}" in
|
|
"" | "#"*) continue ;;
|
|
esac
|
|
_infinito_env_key="${_infinito_env_line%%=*}"
|
|
if [[ "${_infinito_env_key}" == "${_infinito_env_line}" ]]; then
|
|
continue
|
|
fi
|
|
if [[ -n "${!_infinito_env_key:-}" ]]; then
|
|
_infinito_env_preserved["${_infinito_env_key}"]="${!_infinito_env_key}"
|
|
fi
|
|
done <"${_infinito_env_dotenv}"
|
|
unset _infinito_env_line _infinito_env_key
|
|
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "${_infinito_env_dotenv}"
|
|
set +a
|
|
|
|
for _infinito_env_key in "${!_infinito_env_preserved[@]}"; do
|
|
declare -gx "${_infinito_env_key}=${_infinito_env_preserved[${_infinito_env_key}]}"
|
|
done
|
|
unset _infinito_env_key _infinito_env_preserved
|
|
|
|
export INFINITO_ENV_LOADED="1"
|
|
unset _infinito_env_repo_root _infinito_env_dotenv
|