Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for --wrapScalar=false in properties encoder #1241

Merged
merged 5 commits into from
Jun 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ yq.1
# debian pkg
_build
debian/files

# intellij
/.idea
2 changes: 1 addition & 1 deletion cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func configureEncoder(format yqlib.PrinterOutputFormat) yqlib.Encoder {
case yqlib.JSONOutputFormat:
return yqlib.NewJONEncoder(indent, colorsEnabled)
case yqlib.PropsOutputFormat:
return yqlib.NewPropertiesEncoder()
return yqlib.NewPropertiesEncoder(unwrapScalar)
case yqlib.CSVOutputFormat:
return yqlib.NewCsvEncoder(',')
case yqlib.TSVOutputFormat:
Expand Down
49 changes: 39 additions & 10 deletions pkg/yqlib/doc/usage/properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Given a sample.yml file of:
```yaml
# block comments don't come through
person: # neither do comments on maps
name: Mike # comments on values appear
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
food: [pizza] # comments on arrays do not
Expand All @@ -32,7 +32,36 @@ yq -o=props sample.yml
will output
```properties
# comments on values appear
person.name = Mike
person.name = Mike Wazowski

# comments on array values appear
person.pets.0 = cat
person.food.0 = pizza
```

## Encode properties: scalar encapsulation
Note that string values with blank characters in them are encapsulated with double quotes

Given a sample.yml file of:
```yaml
# block comments don't come through
person: # neither do comments on maps
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
food: [pizza] # comments on arrays do not
emptyArray: []
emptyMap: []

```
then
```bash
yq -o=props --unwrapScalar=false sample.yml
```
will output
```properties
# comments on values appear
person.name = "Mike Wazowski"

# comments on array values appear
person.pets.0 = cat
Expand All @@ -44,7 +73,7 @@ Given a sample.yml file of:
```yaml
# block comments don't come through
person: # neither do comments on maps
name: Mike # comments on values appear
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
food: [pizza] # comments on arrays do not
Expand All @@ -58,7 +87,7 @@ yq -o=props '... comments = ""' sample.yml
```
will output
```properties
person.name = Mike
person.name = Mike Wazowski
person.pets.0 = cat
person.food.0 = pizza
```
Expand All @@ -70,7 +99,7 @@ Given a sample.yml file of:
```yaml
# block comments don't come through
person: # neither do comments on maps
name: Mike # comments on values appear
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
food: [pizza] # comments on arrays do not
Expand All @@ -85,7 +114,7 @@ yq -o=props '(.. | select( (tag == "!!map" or tag =="!!seq") and length == 0)) =
will output
```properties
# comments on values appear
person.name = Mike
person.name = Mike Wazowski

# comments on array values appear
person.pets.0 = cat
Expand All @@ -98,7 +127,7 @@ emptyMap =
Given a sample.properties file of:
```properties
# comments on values appear
person.name = Mike
person.name = Mike Wazowski

# comments on array values appear
person.pets.0 = cat
Expand All @@ -112,7 +141,7 @@ yq -p=props sample.properties
will output
```yaml
person:
name: Mike # comments on values appear
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
food:
Expand All @@ -123,7 +152,7 @@ person:
Given a sample.properties file of:
```properties
# comments on values appear
person.name = Mike
person.name = Mike Wazowski

# comments on array values appear
person.pets.0 = cat
Expand All @@ -137,7 +166,7 @@ yq -p=props -o=props '.person.pets.0 = "dog"' sample.properties
will output
```properties
# comments on values appear
person.name = Mike
person.name = Mike Wazowski

# comments on array values appear
person.pets.0 = dog
Expand Down
15 changes: 12 additions & 3 deletions pkg/yqlib/encoder_properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import (
)

type propertiesEncoder struct {
unwrapScalar bool
}

func NewPropertiesEncoder() Encoder {
return &propertiesEncoder{}
func NewPropertiesEncoder(unwrapScalar bool) Encoder {
return &propertiesEncoder{
unwrapScalar: unwrapScalar,
}
}

func (pe *propertiesEncoder) CanHandleAliases() bool {
Expand Down Expand Up @@ -75,7 +78,13 @@ func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node,
p.SetComment(path, headAndLineComment(node))
switch node.Kind {
case yaml.ScalarNode:
_, _, err := p.Set(path, node.Value)
var nodeValue string
if pe.unwrapScalar || !strings.Contains(node.Value, " ") {
nodeValue = node.Value
} else {
nodeValue = fmt.Sprintf("%q", node.Value)
}
_, _, err := p.Set(path, nodeValue)
return err
case yaml.DocumentNode:
return pe.doEncode(p, node.Content[0], path)
Expand Down
73 changes: 61 additions & 12 deletions pkg/yqlib/encoder_properties_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"github.com/mikefarah/yq/v4/test"
)

func yamlToProps(sampleYaml string) string {
func yamlToProps(sampleYaml string, unwrapScalar bool) string {
var output bytes.Buffer
writer := bufio.NewWriter(&output)

var propsEncoder = NewPropertiesEncoder()
var propsEncoder = NewPropertiesEncoder(unwrapScalar)
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder())
if err != nil {
panic(err)
Expand All @@ -28,51 +28,100 @@ func yamlToProps(sampleYaml string) string {
return strings.TrimSuffix(output.String(), "\n")
}

func TestPropertiesEncoderSimple(t *testing.T) {
func TestPropertiesEncoderSimple_Unwrapped(t *testing.T) {
var sampleYaml = `a: 'bob cool'`

var expectedProps = `a = bob cool`
var actualProps = yamlToProps(sampleYaml)
var actualProps = yamlToProps(sampleYaml, true)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderSimpleWithComments(t *testing.T) {
func TestPropertiesEncoderSimple_Wrapped(t *testing.T) {
var sampleYaml = `a: 'bob cool'`

var expectedProps = `a = "bob cool"`
var actualProps = yamlToProps(sampleYaml, false)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderSimpleWithComments_Unwrapped(t *testing.T) {
var sampleYaml = `a: 'bob cool' # line`

var expectedProps = `# line
a = bob cool`
var actualProps = yamlToProps(sampleYaml)
var actualProps = yamlToProps(sampleYaml, true)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderSimpleWithComments_Wrapped(t *testing.T) {
var sampleYaml = `a: 'bob cool' # line`

var expectedProps = `# line
a = "bob cool"`
var actualProps = yamlToProps(sampleYaml, false)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderDeep(t *testing.T) {
func TestPropertiesEncoderDeep_Unwrapped(t *testing.T) {
var sampleYaml = `a:
b: "bob cool"
`

var expectedProps = `a.b = bob cool`
var actualProps = yamlToProps(sampleYaml)
var actualProps = yamlToProps(sampleYaml, true)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderDeep_Wrapped(t *testing.T) {
var sampleYaml = `a:
b: "bob cool"
`

var expectedProps = `a.b = "bob cool"`
var actualProps = yamlToProps(sampleYaml, false)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderDeepWithComments(t *testing.T) {
func TestPropertiesEncoderDeepWithComments_Unwrapped(t *testing.T) {
var sampleYaml = `a: # a thing
b: "bob cool" # b thing
`

var expectedProps = `# b thing
a.b = bob cool`
var actualProps = yamlToProps(sampleYaml)
var actualProps = yamlToProps(sampleYaml, true)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderDeepWithComments_Wrapped(t *testing.T) {
var sampleYaml = `a: # a thing
b: "bob cool" # b thing
`

var expectedProps = `# b thing
a.b = "bob cool"`
var actualProps = yamlToProps(sampleYaml, false)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderArray(t *testing.T) {
func TestPropertiesEncoderArray_Unwrapped(t *testing.T) {
var sampleYaml = `a:
b: [{c: dog}, {c: cat}]
`

var expectedProps = `a.b.0.c = dog
a.b.1.c = cat`
var actualProps = yamlToProps(sampleYaml)
var actualProps = yamlToProps(sampleYaml, true)
test.AssertResult(t, expectedProps, actualProps)
}

func TestPropertiesEncoderArray_Wrapped(t *testing.T) {
var sampleYaml = `a:
b: [{c: dog named jim}, {c: cat named jam}]
`

var expectedProps = `a.b.0.c = "dog named jim"
a.b.1.c = "cat named jam"`
var actualProps = yamlToProps(sampleYaml, false)
test.AssertResult(t, expectedProps, actualProps)
}
21 changes: 14 additions & 7 deletions pkg/yqlib/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/mikefarah/yq/v4/test"
)

var complexExpectYaml = `D0, P[], (!!map)::a: Easy! as one two three
const complexExpectYaml = `D0, P[], (!!map)::a: Easy! as one two three
b:
c: 2
d:
Expand Down Expand Up @@ -96,11 +96,15 @@ func decodeJSON(t *testing.T, jsonString string) *CandidateNode {
}

func testJSONScenario(t *testing.T, s formatScenario) {
if s.scenarioType == "encode" || s.scenarioType == "roundtrip" {
switch s.scenarioType {
case "encode", "decode":
test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewYamlDecoder(), NewJONEncoder(s.indent, false)), s.description)
} else {
case "":
var actual = resultToString(t, decodeJSON(t, s.input))
test.AssertResultWithContext(t, s.expected, actual, s.description)

default:
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
}
}

Expand Down Expand Up @@ -135,14 +139,17 @@ func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s formatScenario)

func documentJSONScenario(t *testing.T, w *bufio.Writer, i interface{}) {
s := i.(formatScenario)

if s.skipDoc {
return
}
if s.scenarioType == "encode" {
documentJSONEncodeScenario(w, s)
} else {
switch s.scenarioType {
case "":
documentJSONDecodeScenario(t, w, s)
case "encode":
documentJSONEncodeScenario(w, s)

default:
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/yqlib/operator_encoder_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
case JSONOutputFormat:
return NewJONEncoder(indent, false)
case PropsOutputFormat:
return NewPropertiesEncoder()
return NewPropertiesEncoder(true)
case CSVOutputFormat:
return NewCsvEncoder(',')
case TSVOutputFormat:
Expand Down
Loading