pelletier / go-toml

Go library for the TOML file format
https://github.com/pelletier/go-toml
Other
1.72k stars 209 forks source link

Ordered encoded results is incorrect in some cases #882

Closed msaf1980 closed 1 year ago

msaf1980 commented 1 year ago

Describe the bug Ordered encoded results is incorrect in some cases (simple type after map or complex slice)

To Reproduce

Test for reproduce

func TestMarshalOrder(t *testing.T) {
    type included struct {
        Inc int `comment:"Included"`
    }
    type order struct {
        One   int        `comment:"Before array"`
        Two   []included `comment:"Array"`
        Three map[string]time.Duration
        Four  bool `comment:"Order check"`
        Five  []int
    }

    doc := order{
        One: 1, Two: []included{{4}, {2}}, Three: map[string]time.Duration{"3": time.Second}, Four: true, Five: []int{5, 2},
    }

    expected := `
# Before array
One = 1

# Order check
Four = true
Five = [5, 2]

[[Two]]

 # Included
 Inc = 4

[[Two]]

 # Included
 Inc = 2

[Three]
 3 = "1s"
`

    var resultDoc order

    result := new(bytes.Buffer)
    encoder := NewEncoder(result).Indentation(" ").Order(OrderPreserve)
    err := encoder.Encode(doc)
    require.NoError(t, err)

    err = Unmarshal(result.Bytes(), &resultDoc)
    assert.NoError(t, err)

    require.Equal(t, expected, result.String())
    require.Equal(t, doc, resultDoc)
}

Expected behavior Encode simply type first, then complex.

Versions

pelletier commented 1 year ago

Is there something blocking you from upgrading to go-toml v2? This bug has been fixed in that version (playground), and go-toml v1 is not receiving updates anymore.

msaf1980 commented 1 year ago

Is there something blocking you from upgrading to go-toml v2? This bug has been fixed in that version (playground), and go-toml v1 is not receiving updates anymore.

v2 not supporting tag commented. It's main reason why we can't migrate to v2.

pelletier commented 1 year ago

Can you elaborate on your use-case of the commented tag? I'm curious how it's used to understand whether that problem would be better solved by the document model, of if it's worth re-introducing the commented flag.

msaf1980 commented 1 year ago

It's used for generate commneted config files in our projetcs.

pelletier commented 1 year ago

Could you provide an example?

msaf1980 commented 1 year ago

Could you provide an example?

For example, https://github.com/go-graphite/graphite-clickhouse, Some time ago we extaned config (add field) and it generated corrupted,

[common]
 # general listener
 listen = ":9090"
 # listener to serve /debug/pprof requests. '-pprof' argument overrides it
 pprof-listen = ""
 max-cpu = 1
 # limit number of results from find query, 0=unlimited
 max-metrics-in-find-answer = 0
 # limit numbers of queried metrics per target in /render requests, 0 or negative = unlimited
 max-metrics-per-target = 15000
 # daemon returns empty response if query matches any of regular expressions
 # target-blacklist = []
 # daemon will return the freed memory to the OS when it>0
 memory-return-interval = "0s"
 # additional request headers to log
 headers-to-log = []

 # find/tags cache config
 [common.find-cache]
pelletier commented 1 year ago

Ok, so it seems like you are using commented to emit default configuration for your program that includes commented-out optional fields? (in the example here: target-blacklist)

msaf1980 commented 1 year ago

Ok, so it seems like you are using commented to emit default configuration for your program that includes commented-out optional fields? (in the example here: target-blacklist)

Yes

pelletier commented 1 year ago

@msaf1980 I've added back the commented option in go-toml v2. Hopefully that should allow you to upgrade to v2 which doesn't have that issue! https://github.com/pelletier/go-toml/pull/893