upsertYamlPath function

String upsertYamlPath(
  1. String text,
  2. List<String> segments,
  3. List<String> leafLines
)

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');
}