Skip to content

Commit

Permalink
make sequence style configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Oct 23, 2023
1 parent 70ebea7 commit 330e1e5
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 3 deletions.
22 changes: 19 additions & 3 deletions goyaml.v3/emitterc.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_
}

// Increase the indentation level.
func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
func yaml_emitter_increase_indent_compact(emitter *yaml_emitter_t, flow, indentless bool, compact_seq bool) bool {
emitter.indents = append(emitter.indents, emitter.indent)
if emitter.indent < 0 {
if flow {
Expand All @@ -241,7 +241,14 @@ func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool
emitter.indent += 2
} else {
// Everything else aligns to the chosen indentation.
emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)
emitter.indent = emitter.best_indent * ((emitter.indent + emitter.best_indent) / emitter.best_indent)
if compact_seq {
// The value compact_seq passed in is almost always set to `false` when this function is called,
// except when we are dealing with sequence nodes. So this gets triggered to subtract 2 only when we
// are increasing the indent to account for sequence nodes, which will be correct because we need to
// subtract 2 to account for the - at the beginning of the sequence node.
emitter.indent = emitter.indent - 2
}
}
}
return true
Expand Down Expand Up @@ -728,7 +735,16 @@ func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_e
// Expect a block item node.
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
if first {
if !yaml_emitter_increase_indent(emitter, false, false) {
// emitter.mapping context tells us if we are currently in a mapping context.
// emiiter.column tells us which column we are in in the yaml output. 0 is the first char of the column.
// emitter.indentation tells us if the last character was an indentation character.
// emitter.compact_sequence_indent tells us if '- ' is considered part of the indentation for sequence elements.
// So, `seq` means that we are in a mapping context, and we are either at the first char of the column or
// the last character was not an indentation character, and we consider '- ' part of the indentation
// for sequence elements.
seq := emitter.mapping_context && (emitter.column == 0 || !emitter.indention) &&
emitter.compact_sequence_indent
if !yaml_emitter_increase_indent_compact(emitter, false, false, seq) {
return false
}
}
Expand Down
33 changes: 33 additions & 0 deletions goyaml.v3/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package yaml

// yaml_emitter_increase_indent preserves the original signature and delegates to
// yaml_emitter_increase_indent_compact without compact-sequence indentation
func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
return yaml_emitter_increase_indent_compact(emitter, flow, indentless, false)
}

// CompactSeqIndent makes it so that '- ' is considered part of the indentation.
func (e *Encoder) CompactSeqIndent() {
e.encoder.emitter.compact_sequence_indent = true
}

// DefaultSeqIndent makes it so that '- ' is not considered part of the indentation.
func (e *Encoder) DefaultSeqIndent() {
e.encoder.emitter.compact_sequence_indent = false
}
146 changes: 146 additions & 0 deletions goyaml.v3/patch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package yaml_test

import (
"bytes"

. "gopkg.in/check.v1"
yaml "sigs.k8s.io/yaml/goyaml.v3"
)

func (s *S) TestCompactSeqIndentDefault(c *C) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
enc.CompactSeqIndent()
err := enc.Encode(map[string]interface{}{"a": []string{"b", "c"}})
c.Assert(err, Equals, nil)
err = enc.Close()
c.Assert(err, Equals, nil)
// The default indent is 4, so these sequence elements get 2 indents as before
c.Assert(buf.String(), Equals, `a:
- b
- c
`)
}

func (s *S) TestCompactSequenceWithSetIndent(c *C) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
enc.CompactSeqIndent()
enc.SetIndent(2)
err := enc.Encode(map[string]interface{}{"a": []string{"b", "c"}})
c.Assert(err, Equals, nil)
err = enc.Close()
c.Assert(err, Equals, nil)
// The sequence indent is 2, so these sequence elements don't get indented at all
c.Assert(buf.String(), Equals, `a:
- b
- c
`)
}

type normal string
type compact string

// newlinePlusNormalToNewlinePlusCompact maps the normal encoding (prefixed with a newline)
// to the compact encoding (prefixed with a newline), for test cases in marshalTests
var newlinePlusNormalToNewlinePlusCompact = map[normal]compact{
normal(`
v:
- A
- B
`): compact(`
v:
- A
- B
`),

normal(`
v:
- A
- |-
B
C
`): compact(`
v:
- A
- |-
B
C
`),

normal(`
v:
- A
- 1
- B:
- 2
- 3
`): compact(`
v:
- A
- 1
- B:
- 2
- 3
`),

normal(`
a:
- 1
- 2
`): compact(`
a:
- 1
- 2
`),

normal(`
a:
b:
- c: 1
d: 2
`): compact(`
a:
b:
- c: 1
d: 2
`),
}

func (s *S) TestEncoderCompactIndents(c *C) {
for i, item := range marshalTests {
c.Logf("test %d. %q", i, item.data)
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
enc.CompactSeqIndent()
err := enc.Encode(item.value)
c.Assert(err, Equals, nil)
err = enc.Close()
c.Assert(err, Equals, nil)

// Default to expecting the item data
expected := item.data
// If there's a different compact representation, use that
if c, ok := newlinePlusNormalToNewlinePlusCompact[normal("\n"+item.data)]; ok {
expected = string(c[1:])
}

c.Assert(buf.String(), Equals, expected)
}
}
2 changes: 2 additions & 0 deletions goyaml.v3/yamlh.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,8 @@ type yaml_emitter_t struct {

indent int // The current indentation level.

compact_sequence_indent bool // Is '- ' is considered part of the indentation for sequence elements?

flow_level int // The current flow level.

root_context bool // Is it the document root context?
Expand Down

0 comments on commit 330e1e5

Please sign in to comment.