google / jsonnet

Jsonnet - The data templating language
http://jsonnet.org
Apache License 2.0
6.87k stars 436 forks source link

std.manifestIni should support repeated section names #1125

Open robinp opened 6 months ago

robinp commented 6 months ago

Hello. This is a change request similar in spirit to https://github.com/google/jsonnet/issues/386 (fixed in https://github.com/google/jsonnet/commit/d4434c8df41c46d4ed11958677a655f0d1c52f87), but this time to allow sections with duplicate names (instead of duplicate keys).

The INI file wiki acknowledges this exists. As a specific example, wireguard needs multiple [Peer] sections.

Modifying the upstream std like this, by adding the array-check in section_lines, seems to work (now if a value of a key within sections is an array, then that section will be repeated):

  manifestIni(ini):
    local body_lines(body) =
      std.join([], [
        local value_or_values = body[k];
        if std.isArray(value_or_values) then
          ['%s = %s' % [k, value] for value in value_or_values]
        else
          ['%s = %s' % [k, value_or_values]]

        for k in std.objectFields(body)
      ]);

    local section_lines(sname, value_or_values) = 
            if std.isArray(value_or_values) then
              local rep = value_or_values;
              std.join([], [
                ['[%s]' % [sname]] + body_lines(sbody)
                for sbody in rep
              ])
            else
              local sbody = value_or_values;
              ['[%s]' % [sname]] + body_lines(sbody),
          main_body = if std.objectHas(ini, 'main') then body_lines(ini.main) else [],
          all_sections = [
      section_lines(k, ini.sections[k])
      for k in std.objectFields(ini.sections)
    ];
    std.join('\n', main_body + std.flattenArrays(all_sections) + ['']),