upsertYamlPath function
Edits text so the dotted segments path carries leafLines (one
scalar line, or a multi-line yaml block), keeping every unrelated line
(including comments) byte-identical:
- an existing scalar line is rewritten in place, preserving a trailing
# comment; - an existing block (or scalar replaced by a block) is swapped for
leafLines, leaving the rest of the parent block untouched; - a missing key is inserted at the top of its parent's block;
- a missing top-level section is appended at the end of the file;
- descending into an inline scalar is a ConfigException (type clash).
Split into a per-segment scan helper to stay under the repo's CRAP ratchet (crap4dart threshold 12).
Implementation
String upsertYamlPath(
String text,
List<String> segments,
List<String> leafLines,
) {
final hadTrailingNewline = text.endsWith('\n');
final lines = text.isEmpty
? <String>[]
: (hadTrailingNewline ? text.substring(0, text.length - 1) : text).split(
'\n',
);
var cursor = 0;
for (var depth = 0; depth < segments.length; depth++) {
final found = _findKeyLine(lines, segments, depth, cursor);
if (found < 0) {
return _insertChain(
lines,
segments,
depth,
cursor,
leafLines,
hadTrailingNewline,
);
}
if (depth == segments.length - 1) {
return _replaceLeaf(
lines,
segments[depth],
depth,
found,
leafLines,
hadTrailingNewline,
);
}
final inline = _inlineValue(lines[found]);
if (inline != null && inline.isNotEmpty) {
throw ConfigException(
'"${segments.sublist(0, depth + 1).join('.')}" is a scalar — '
'cannot set a deeper key under it',
);
}
cursor = found + 1;
}
// Unreachable: the leaf always returns inside the loop.
throw StateError('upsertYamlPath fell through');
}