Stop conf_upgrade losing every key that follows a single-line array
This commit is contained in:
+50
-20
@@ -249,6 +249,21 @@ elif grep -q 'HOSTN' "$TEMPLATE" 2>/dev/null; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── Block-parsing patterns ───────────────────────────────────────────────────────────────────
|
||||||
|
# All three walkers below share these. A single-line array — KEY=(a b c) — both opens and
|
||||||
|
# closes on one line. Matching only the opener leaves the walker inside a block it never
|
||||||
|
# leaves, so every key until the next standalone ")" becomes invisible: skipped by
|
||||||
|
# _collect_stats, dropped from HOST_MAP by _parse_target, and emitted from the template
|
||||||
|
# instead of the user's conf by _write_merged. _ARR_ONELINE_RE is what stops that.
|
||||||
|
|
||||||
|
_ARR_DECL_RE='^[[:space:]]*declare[[:space:]]+-[a-zA-Z]+[[:space:]]+([A-Z0-9_]+)[[:space:]]*=\('
|
||||||
|
_ARR_OPEN_RE='^[[:space:]]*([A-Z0-9_]+)[[:space:]]*=\('
|
||||||
|
_ARR_CLOSE_RE='^[[:space:]]*\)[[:space:]]*(#.*)?$'
|
||||||
|
# The [^#]* is deliberate: it forces the closing ")" to appear before any comment, so an
|
||||||
|
# opener like FOO=( # see note (here) is not mistaken for a complete single-line array.
|
||||||
|
_ARR_ONELINE_RE='=\([^#]*\)[[:space:]]*(#.*)?$'
|
||||||
|
_SCALAR_RE='^[[:space:]]*([A-Z0-9_]+)[[:space:]]*='
|
||||||
|
|
||||||
# ── Parse target → KEY → full definition block ───────────────────────────────────────────────
|
# ── Parse target → KEY → full definition block ───────────────────────────────────────────────
|
||||||
|
|
||||||
declare -A HOST_MAP # KEY → complete definition line(s) from user's conf
|
declare -A HOST_MAP # KEY → complete definition line(s) from user's conf
|
||||||
@@ -260,19 +275,23 @@ _parse_target() {
|
|||||||
if [[ "$in_block" == true ]]; then
|
if [[ "$in_block" == true ]]; then
|
||||||
cur_block+="$line"$'\n'
|
cur_block+="$line"$'\n'
|
||||||
# Closing ) — optional trailing whitespace and comment
|
# Closing ) — optional trailing whitespace and comment
|
||||||
if [[ "$line" =~ ^[[:space:]]*\)[[:space:]]*(#.*)?$ ]]; then
|
if [[ "$line" =~ $_ARR_CLOSE_RE ]]; then
|
||||||
HOST_MAP["$cur_key"]="$cur_block"
|
HOST_MAP["$cur_key"]="$cur_block"
|
||||||
in_block=false; cur_key=""; cur_block=""
|
in_block=false; cur_key=""; cur_block=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# declare -A KEY=(
|
# declare -A KEY=( / KEY=(
|
||||||
if [[ "$line" =~ ^[[:space:]]*declare[[:space:]]+-[a-zA-Z]+[[:space:]]+([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_DECL_RE ]] || [[ "$line" =~ $_ARR_OPEN_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true; cur_block="$line"$'\n'
|
cur_key="${BASH_REMATCH[1]}"
|
||||||
# KEY=(
|
# KEY=(a b c) — opens and closes on one line, never enter block mode
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_ONELINE_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true; cur_block="$line"$'\n'
|
HOST_MAP["$cur_key"]="$line"$'\n'
|
||||||
|
cur_key=""
|
||||||
|
else
|
||||||
|
in_block=true; cur_block="$line"$'\n'
|
||||||
|
fi
|
||||||
# KEY=value (simple scalar)
|
# KEY=value (simple scalar)
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*= ]]; then
|
elif [[ "$line" =~ $_SCALAR_RE ]]; then
|
||||||
HOST_MAP["${BASH_REMATCH[1]}"]="$line"$'\n'
|
HOST_MAP["${BASH_REMATCH[1]}"]="$line"$'\n'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -289,7 +308,7 @@ _collect_stats() {
|
|||||||
|
|
||||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
if [[ "$in_block" == true ]]; then
|
if [[ "$in_block" == true ]]; then
|
||||||
if [[ "$line" =~ ^[[:space:]]*\)[[:space:]]*(#.*)?$ ]]; then
|
if [[ "$line" =~ $_ARR_CLOSE_RE ]]; then
|
||||||
in_block=false
|
in_block=false
|
||||||
TMPL_SEEN["$cur_key"]=1
|
TMPL_SEEN["$cur_key"]=1
|
||||||
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then KEPT+=("$cur_key")
|
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then KEPT+=("$cur_key")
|
||||||
@@ -297,11 +316,17 @@ _collect_stats() {
|
|||||||
cur_key=""
|
cur_key=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ "$line" =~ ^[[:space:]]*declare[[:space:]]+-[a-zA-Z]+[[:space:]]+([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_DECL_RE ]] || [[ "$line" =~ $_ARR_OPEN_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true
|
cur_key="${BASH_REMATCH[1]}"
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_ONELINE_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true
|
TMPL_SEEN["$cur_key"]=1
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*= ]]; then
|
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then KEPT+=("$cur_key")
|
||||||
|
else ADDED+=("$cur_key"); fi
|
||||||
|
cur_key=""
|
||||||
|
else
|
||||||
|
in_block=true
|
||||||
|
fi
|
||||||
|
elif [[ "$line" =~ $_SCALAR_RE ]]; then
|
||||||
local k="${BASH_REMATCH[1]}"
|
local k="${BASH_REMATCH[1]}"
|
||||||
TMPL_SEEN["$k"]=1
|
TMPL_SEEN["$k"]=1
|
||||||
if [[ -n "${HOST_MAP[$k]+_}" ]]; then KEPT+=("$k")
|
if [[ -n "${HOST_MAP[$k]+_}" ]]; then KEPT+=("$k")
|
||||||
@@ -324,18 +349,23 @@ _write_merged() {
|
|||||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
if [[ "$in_block" == true ]]; then
|
if [[ "$in_block" == true ]]; then
|
||||||
cur_block+="$line"$'\n'
|
cur_block+="$line"$'\n'
|
||||||
if [[ "$line" =~ ^[[:space:]]*\)[[:space:]]*(#.*)?$ ]]; then
|
if [[ "$line" =~ $_ARR_CLOSE_RE ]]; then
|
||||||
in_block=false
|
in_block=false
|
||||||
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then printf '%s' "${HOST_MAP[$cur_key]}"
|
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then printf '%s' "${HOST_MAP[$cur_key]}"
|
||||||
else printf '%s' "$cur_block"; fi
|
else printf '%s' "$cur_block"; fi
|
||||||
cur_key=""; cur_block=""
|
cur_key=""; cur_block=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ "$line" =~ ^[[:space:]]*declare[[:space:]]+-[a-zA-Z]+[[:space:]]+([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_DECL_RE ]] || [[ "$line" =~ $_ARR_OPEN_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true; cur_block="$line"$'\n'
|
cur_key="${BASH_REMATCH[1]}"
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*=\( ]]; then
|
if [[ "$line" =~ $_ARR_ONELINE_RE ]]; then
|
||||||
cur_key="${BASH_REMATCH[1]}"; in_block=true; cur_block="$line"$'\n'
|
if [[ -n "${HOST_MAP[$cur_key]+_}" ]]; then printf '%s' "${HOST_MAP[$cur_key]}"
|
||||||
elif [[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)[[:space:]]*= ]]; then
|
else printf '%s\n' "$line"; fi
|
||||||
|
cur_key=""
|
||||||
|
else
|
||||||
|
in_block=true; cur_block="$line"$'\n'
|
||||||
|
fi
|
||||||
|
elif [[ "$line" =~ $_SCALAR_RE ]]; then
|
||||||
local k="${BASH_REMATCH[1]}"
|
local k="${BASH_REMATCH[1]}"
|
||||||
if [[ -n "${HOST_MAP[$k]+_}" ]]; then printf '%s' "${HOST_MAP[$k]}"
|
if [[ -n "${HOST_MAP[$k]+_}" ]]; then printf '%s' "${HOST_MAP[$k]}"
|
||||||
else printf '%s\n' "$line"; fi
|
else printf '%s\n' "$line"; fi
|
||||||
|
|||||||
Reference in New Issue
Block a user