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.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 return err
} }
// TODO: test comment on array
func (dec *propertiesDecoder) applyProperty(context Context, properties *properties.Properties, key string) error { func (dec *propertiesDecoder) applyProperty(context Context, properties *properties.Properties, key string) error {
value, _ := properties.Get(key) value, _ := properties.Get(key)
path := parsePropKey(key) path := parsePropKey(key)

View File

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

View File

@ -139,10 +139,12 @@ yq -p=props sample.properties
will output will output
```yaml ```yaml
person: person:
name: Mike Wazowski # block comments come through # block comments come through
# comments on values appear # comments on values appear
name: Mike Wazowski
pets: pets:
- cat # comments on array values appear # comments on array values appear
- cat
food: food:
- pizza - 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 { func (pe *propertiesEncoder) Encode(writer io.Writer, node *yaml.Node) error {
mapKeysToStrings(node) mapKeysToStrings(node)
p := properties.NewProperties() p := properties.NewProperties()
err := pe.doEncode(p, node, "") err := pe.doEncode(p, node, "", nil)
if err != nil { if err != nil {
return err return err
} }
@ -74,10 +74,17 @@ func (pe *propertiesEncoder) Encode(writer io.Writer, node *yaml.Node) error {
return err 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")) p.SetComments(path, strings.Split(commentsWithSpaces, "\n"))
switch node.Kind { switch node.Kind {
case yaml.ScalarNode: case yaml.ScalarNode:
var nodeValue string var nodeValue string
@ -89,13 +96,13 @@ func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node,
_, _, err := p.Set(path, nodeValue) _, _, err := p.Set(path, nodeValue)
return err return err
case yaml.DocumentNode: case yaml.DocumentNode:
return pe.doEncode(p, node.Content[0], path) return pe.doEncode(p, node.Content[0], path, node)
case yaml.SequenceNode: case yaml.SequenceNode:
return pe.encodeArray(p, node.Content, path) return pe.encodeArray(p, node.Content, path)
case yaml.MappingNode: case yaml.MappingNode:
return pe.encodeMap(p, node.Content, path) return pe.encodeMap(p, node.Content, path)
case yaml.AliasNode: case yaml.AliasNode:
return pe.doEncode(p, node.Alias, path) return pe.doEncode(p, node.Alias, path, nil)
default: default:
return fmt.Errorf("Unsupported node %v", node.Tag) 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 { func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kids []*yaml.Node, path string) error {
for index, child := range kids { 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 { if err != nil {
return err 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 { for index := 0; index < len(kids); index = index + 2 {
key := kids[index] key := kids[index]
value := kids[index+1] 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 { if err != nil {
return err return err
} }

View File

@ -8,6 +8,48 @@ import (
"github.com/mikefarah/yq/v4/test" "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 const samplePropertiesYaml = `# block comments come through
person: # neither do comments on maps person: # neither do comments on maps
name: Mike Wazowski # comments on values appear name: Mike Wazowski # comments on values appear
@ -46,9 +88,12 @@ person.food.0 = pizza
` `
const expectedDecodedYaml = `person: const expectedDecodedYaml = `person:
name: Mike Wazowski # comments on values appear # block comments come through
# comments on values appear
name: Mike Wazowski
pets: pets:
- cat # comments on array values appear # comments on array values appear
- cat
food: food:
- pizza - pizza
` `
@ -116,6 +161,34 @@ var propertyScenarios = []formatScenario{
expected: expectedUpdatedProperties, expected: expectedUpdatedProperties,
scenarioType: "roundtrip", 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", description: "Empty doc",
skipDoc: true, skipDoc: true,

View File

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

View File

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strings"
) )
func readStream(filename string) (io.Reader, error) { 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 { func writeString(writer io.Writer, txt string) error {
_, errorWriting := writer.Write([]byte(txt)) _, errorWriting := writer.Write([]byte(txt))
return errorWriting return errorWriting