From 653a3c94159b7e6b3c428b297e750bd3cb9401ea Mon Sep 17 00:00:00 2001 From: Yann Autissier Date: Thu, 3 Sep 2026 18:40:31 +0200 Subject: [PATCH] harden the config reader against an empty or malformed .env holcommon's empty .env made the loader evaluate one blank line, which tripped set -u. Verified afterwards on holcommon's real host stack: the CLI and the make engine resolve the same five files and render a byte-identical 241-line compose config. --- bin/myos | 2 +- lib/cmd/doctor.sh | 2 +- lib/config.sh | 3 +++ lib/stack.sh | 2 +- lib/tags.sh | 5 ++++- spec/unit/config_spec.sh | 24 ++++++++++++++++++++++++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/bin/myos b/bin/myos index 3e1805e..b4aacc6 100755 --- a/bin/myos +++ b/bin/myos @@ -118,7 +118,7 @@ WORKDIR=${WORKDIR:-$PWD} WORKDIR=$(cd "$WORKDIR" 2>/dev/null && pwd -P) || myos_die "$MYOS_E_USAGE" "no such directory: $WORKDIR" for _f in $(myos_conf_files); do myos_dotenv_load "$_f"; done -myos_dotenv_load "$HOME/.config/myos/config" +myos_dotenv_load "${HOME:-}/.config/myos/config" ENV=${ENV:-local} myos_dotenv_load "$WORKDIR/.env.$ENV" myos_dotenv_load "$WORKDIR/.env" diff --git a/lib/cmd/doctor.sh b/lib/cmd/doctor.sh index 79ed5a7..b9d1738 100644 --- a/lib/cmd/doctor.sh +++ b/lib/cmd/doctor.sh @@ -18,7 +18,7 @@ myos_cmd_doctor() { printf 'configuration:\n' for _f in $(myos_conf_files); do _ok "$_f" "read"; done - [ -f "$HOME/.config/myos/config" ] && _ok "$HOME/.config/myos/config" "read" + [ -f "${HOME:-}/.config/myos/config" ] && _ok "${HOME:-}/.config/myos/config" "read" [ -f "$WORKDIR/.env" ] && _ok "$WORKDIR/.env" "read" _ok ENV "$ENV" _ok USER "$USER" diff --git a/lib/config.sh b/lib/config.sh index 5c1c908..16865dc 100644 --- a/lib/config.sh +++ b/lib/config.sh @@ -36,7 +36,10 @@ myos_dotenv_parse() { myos_dotenv_load() { [ -f "$1" ] || return 0 while IFS= read -r _kv; do + # an empty file still yields one empty line through the here-document + [ -n "$_kv" ] || continue _k=${_kv%%=*} + [ -n "$_k" ] || continue [ -n "$(myos_var "$_k")" ] && continue eval "$_k=\${_kv#*=}" done <., unless _SERVICE[_]_NAME overrides the prefix diff --git a/spec/unit/config_spec.sh b/spec/unit/config_spec.sh index 87b46a4..a001bd7 100644 --- a/spec/unit/config_spec.sh +++ b/spec/unit/config_spec.sh @@ -80,3 +80,27 @@ Describe 'lib/config.sh' End End End + +Describe 'lib/config.sh robustness' + setup() { MYOS_TMP=$(mktemp -d "${TMPDIR:-/tmp}/myos-cfg.XXXXXX"); } + cleanup() { rm -rf "$MYOS_TMP"; } + BeforeEach setup + AfterEach cleanup + + It 'loads an empty .env without complaining' + : > "$MYOS_TMP/.env" + When call myos_dotenv_load "$MYOS_TMP/.env" + The status should be success + The stderr should equal "" + End + It 'ignores a line with an empty key' + printf '=orphan\nGOOD=1\n' > "$MYOS_TMP/.env" + When call myos_dotenv_parse "$MYOS_TMP/.env" + The output should equal "GOOD=1" + End + It 'returns empty for an unnamed variable' + When call myos_var "" + The output should equal "" + The status should be success + End +End