feat(lib): helper ini_set idempotent pour merge de fichiers INI #24
+33
-3
@@ -159,12 +159,27 @@ ini_set() {
|
|||||||
chmod "$(stat -c '%a' "$file")" "$tmp" 2>/dev/null || true
|
chmod "$(stat -c '%a' "$file")" "$tmp" 2>/dev/null || true
|
||||||
chown "$(stat -c '%u:%g' "$file")" "$tmp" 2>/dev/null || true
|
chown "$(stat -c '%u:%g' "$file")" "$tmp" 2>/dev/null || true
|
||||||
|
|
||||||
awk -v section="$section" -v key="$key" -v value="$value" '
|
# awk writes into $tmp regardless of its own exit status — a mid-stream
|
||||||
|
# death (OOM, signal, an exotic value tripping the regex) would still
|
||||||
|
# leave a truncated-but-nonempty $tmp for `mv` to install over $file.
|
||||||
|
# Gate the mv on awk's exit code so a failure leaves the original config
|
||||||
|
# untouched instead of silently destroying it.
|
||||||
|
if ! awk -v section="$section" -v key="$key" -v value="$value" '
|
||||||
|
# Blank lines are buffered rather than printed immediately while a
|
||||||
|
# section is still awaiting insertion: without this, a key inserted
|
||||||
|
# right before the next section header lands *after* that section'"'"'s
|
||||||
|
# trailing blank line(s) instead of before them. Flushed as soon as
|
||||||
|
# either a non-blank line or the insertion itself happens, so this
|
||||||
|
# never reorders anything except relative to that pending insertion.
|
||||||
|
function flush_blanks() {
|
||||||
|
while (blank_count > 0) { print ""; blank_count-- }
|
||||||
|
}
|
||||||
/^\[.*\]$/ {
|
/^\[.*\]$/ {
|
||||||
if (in_section && !done) {
|
if (in_section && !done) {
|
||||||
printf "%s = %s\n", key, value
|
printf "%s = %s\n", key, value
|
||||||
done = 1
|
done = 1
|
||||||
}
|
}
|
||||||
|
flush_blanks()
|
||||||
cur = $0
|
cur = $0
|
||||||
gsub(/^\[|\]$/, "", cur)
|
gsub(/^\[|\]$/, "", cur)
|
||||||
in_section = (cur == section)
|
in_section = (cur == section)
|
||||||
@@ -173,11 +188,21 @@ ini_set() {
|
|||||||
next
|
next
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if (in_section && !done && match($0, "^[ \t]*" key "[ \t]*=")) {
|
if (in_section && !done) {
|
||||||
|
if (match($0, "^[ \t]*" key "[ \t]*=")) {
|
||||||
|
flush_blanks()
|
||||||
printf "%s = %s\n", key, value
|
printf "%s = %s\n", key, value
|
||||||
done = 1
|
done = 1
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
if ($0 ~ /^[ \t]*$/) {
|
||||||
|
blank_count++
|
||||||
|
next
|
||||||
|
}
|
||||||
|
flush_blanks()
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
print
|
print
|
||||||
}
|
}
|
||||||
END {
|
END {
|
||||||
@@ -185,13 +210,18 @@ ini_set() {
|
|||||||
printf "%s = %s\n", key, value
|
printf "%s = %s\n", key, value
|
||||||
done = 1
|
done = 1
|
||||||
}
|
}
|
||||||
|
flush_blanks()
|
||||||
if (!section_found) {
|
if (!section_found) {
|
||||||
if (NR > 0) print ""
|
if (NR > 0) print ""
|
||||||
printf "[%s]\n", section
|
printf "[%s]\n", section
|
||||||
printf "%s = %s\n", key, value
|
printf "%s = %s\n", key, value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
' "$file" > "$tmp"
|
' "$file" > "$tmp"; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
log_error "ini_set: awk failed on ${file} (${section}.${key}), config left untouched."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
mv "$tmp" "$file"
|
mv "$tmp" "$file"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user