put comments on key node instead

This commit is contained in:
Mike Farah 2022-10-27 15:27:37 +11:00
parent 7eccbe5902
commit fd79ac8603
8 changed files with 99 additions and 37 deletions

View File

@ -1,10 +1 @@
# great huh
# things and stuff
this.is = a properties file
this.cat.0 = free
# this one is important
# another thing
this.cat.1 = meow

View File

@ -75,7 +75,6 @@ func (dec *propertiesDecoder) applyPropertyComments(context Context, path []inte
return err
}
// TODO: test comment on array
func (dec *propertiesDecoder) applyProperty(context Context, properties *properties.Properties, key string) error {
value, _ := properties.Get(key)
path := parsePropKey(key)

View File

@ -154,9 +154,7 @@ will output
cool: things
more_stuff:
this:
is: a properties file # great huh
# things and stuff
another: a properties file # another thing
is: a properties file
```
## Merge from properties
@ -175,10 +173,8 @@ yq '. *= load_props("../../examples/small.properties")' sample.yml
will output
```yaml
this:
is: a properties file # great huh
# things and stuff
is: a properties file
cool: ay
another: a properties file # another thing
```
## Load from base64 encoded file

View File

@ -139,10 +139,12 @@ yq -p=props sample.properties
will output
```yaml
person:
name: Mike Wazowski # block comments come through
# block comments come through
# comments on values appear
name: Mike Wazowski
pets:
- cat # comments on array values appear
# comments on array values appear
- cat
food:
- pizza
```

View File

@ -65,7 +65,7 @@ func (pe *propertiesEncoder) PrintLeadingContent(writer io.Writer, content strin
func (pe *propertiesEncoder) Encode(writer io.Writer, node *yaml.Node) error {
mapKeysToStrings(node)
p := properties.NewProperties()
err := pe.doEncode(p, node, "")
err := pe.doEncode(p, node, "", nil)
if err != nil {
return err
}
@ -74,10 +74,17 @@ func (pe *propertiesEncoder) Encode(writer io.Writer, node *yaml.Node) error {
return err
}
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node, path string) error {
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node, path string, keyNode *yaml.Node) error {
commentsWithSpaces := strings.ReplaceAll(headAndLineComment(node), "\n", "\n ")
comments := ""
if keyNode != nil {
// include the key node comments if present
comments = headAndLineComment(keyNode)
}
comments = comments + headAndLineComment(node)
commentsWithSpaces := strings.ReplaceAll(comments, "\n", "\n ")
p.SetComments(path, strings.Split(commentsWithSpaces, "\n"))
switch node.Kind {
case yaml.ScalarNode:
var nodeValue string
@ -89,13 +96,13 @@ func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node,
_, _, err := p.Set(path, nodeValue)
return err
case yaml.DocumentNode:
return pe.doEncode(p, node.Content[0], path)
return pe.doEncode(p, node.Content[0], path, node)
case yaml.SequenceNode:
return pe.encodeArray(p, node.Content, path)
case yaml.MappingNode:
return pe.encodeMap(p, node.Content, path)
case yaml.AliasNode:
return pe.doEncode(p, node.Alias, path)
return pe.doEncode(p, node.Alias, path, nil)
default:
return fmt.Errorf("Unsupported node %v", node.Tag)
}
@ -110,7 +117,7 @@ func (pe *propertiesEncoder) appendPath(path string, key interface{}) string {
func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kids []*yaml.Node, path string) error {
for index, child := range kids {
err := pe.doEncode(p, child, pe.appendPath(path, index))
err := pe.doEncode(p, child, pe.appendPath(path, index), nil)
if err != nil {
return err
}
@ -122,7 +129,7 @@ func (pe *propertiesEncoder) encodeMap(p *properties.Properties, kids []*yaml.No
for index := 0; index < len(kids); index = index + 2 {
key := kids[index]
value := kids[index+1]
err := pe.doEncode(p, value, pe.appendPath(path, key.Value))
err := pe.doEncode(p, value, pe.appendPath(path, key.Value), key)
if err != nil {
return err
}

View File

@ -8,6 +8,48 @@ import (
"github.com/mikefarah/yq/v4/test"
)
const propertiesWithCommentsOnMap = `this.thing = hi hi
# important notes
# about this value
this.value = cool
`
const expectedPropertiesWithCommentsOnMapProps = `this.thing = hi hi
# important notes
# about this value
this.value = cool
`
const expectedPropertiesWithCommentsOnMapYaml = `this:
thing: hi hi
# important notes
# about this value
value: cool
`
const propertiesWithCommentInArray = `
this.array.0 = cat
# important notes
# about dogs
this.array.1 = dog
`
const expectedPropertiesWithCommentInArrayProps = `this.array.0 = cat
# important notes
# about dogs
this.array.1 = dog
`
const expectedPropertiesWithCommentInArrayYaml = `this:
array:
- cat
# important notes
# about dogs
- dog
`
const samplePropertiesYaml = `# block comments come through
person: # neither do comments on maps
name: Mike Wazowski # comments on values appear
@ -46,9 +88,12 @@ person.food.0 = pizza
`
const expectedDecodedYaml = `person:
name: Mike Wazowski # comments on values appear
# block comments come through
# comments on values appear
name: Mike Wazowski
pets:
- cat # comments on array values appear
# comments on array values appear
- cat
food:
- pizza
`
@ -116,6 +161,34 @@ var propertyScenarios = []formatScenario{
expected: expectedUpdatedProperties,
scenarioType: "roundtrip",
},
{
skipDoc: true,
description: "comments on arrays roundtrip",
input: propertiesWithCommentInArray,
expected: expectedPropertiesWithCommentInArrayProps,
scenarioType: "roundtrip",
},
{
skipDoc: true,
description: "comments on arrays decode",
input: propertiesWithCommentInArray,
expected: expectedPropertiesWithCommentInArrayYaml,
scenarioType: "decode",
},
{
skipDoc: true,
description: "comments on map roundtrip",
input: propertiesWithCommentsOnMap,
expected: expectedPropertiesWithCommentsOnMapProps,
scenarioType: "roundtrip",
},
{
skipDoc: true,
description: "comments on map decode",
input: propertiesWithCommentsOnMap,
expected: expectedPropertiesWithCommentsOnMapYaml,
scenarioType: "decode",
},
{
description: "Empty doc",
skipDoc: true,

View File

@ -1,11 +1,13 @@
package yqlib
import (
"bufio"
"bytes"
"container/list"
"errors"
"fmt"
"io"
"strings"
)
type StringEvaluator interface {
@ -35,10 +37,7 @@ func (s *stringEvaluator) Evaluate(expression string, input string, encoder Enco
return "", err
}
reader, err := readString(input)
if err != nil {
return "", err
}
reader := bufio.NewReader(strings.NewReader(input))
var currentIndex uint
err = decoder.Init(reader)

View File

@ -7,7 +7,6 @@ import (
"fmt"
"io"
"os"
"strings"
)
func readStream(filename string) (io.Reader, error) {
@ -27,10 +26,6 @@ func readStream(filename string) (io.Reader, error) {
}
func readString(input string) (io.Reader, error) {
return bufio.NewReader(strings.NewReader(input)), nil
}
func writeString(writer io.Writer, txt string) error {
_, errorWriting := writer.Write([]byte(txt))
return errorWriting