mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
wip
This commit is contained in:
parent
94a563dfd8
commit
f46c60f74d
38
pkg/yqlib/doc/Keys.md
Normal file
38
pkg/yqlib/doc/Keys.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
## Get Keys
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
b: cat
|
||||||
|
c: dog
|
||||||
|
d: frog
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq eval '.a | keys' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Set key style
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
b: cat
|
||||||
|
c: dog
|
||||||
|
d: frog
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq eval '(.a | keys) style = 'single'' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
b: cat
|
||||||
|
c: dog
|
||||||
|
d: frog
|
||||||
|
```
|
||||||
|
|
@ -49,6 +49,7 @@ var CreateMap = &OperationType{Type: "CREATE_MAP", NumArgs: 2, Precedence: 40, H
|
|||||||
var ShortPipe = &OperationType{Type: "SHORT_PIPE", NumArgs: 2, Precedence: 45, Handler: PipeOperator}
|
var ShortPipe = &OperationType{Type: "SHORT_PIPE", NumArgs: 2, Precedence: 45, Handler: PipeOperator}
|
||||||
|
|
||||||
var Length = &OperationType{Type: "LENGTH", NumArgs: 0, Precedence: 50, Handler: LengthOperator}
|
var Length = &OperationType{Type: "LENGTH", NumArgs: 0, Precedence: 50, Handler: LengthOperator}
|
||||||
|
var Keys = &OperationType{Type: "KEYS", NumArgs: 0, Precedence: 50, Handler: KeysOperator}
|
||||||
var Collect = &OperationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handler: CollectOperator}
|
var Collect = &OperationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handler: CollectOperator}
|
||||||
var GetStyle = &OperationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: GetStyleOperator}
|
var GetStyle = &OperationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: GetStyleOperator}
|
||||||
var GetTag = &OperationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: GetTagOperator}
|
var GetTag = &OperationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: GetTagOperator}
|
||||||
|
34
pkg/yqlib/operator_keys.go
Normal file
34
pkg/yqlib/operator_keys.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"container/list"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func KeysOperator(d *dataTreeNavigator, matchMap *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||||
|
log.Debugf("-- KeyOperation")
|
||||||
|
var results = list.New()
|
||||||
|
|
||||||
|
for el := matchMap.Front(); el != nil; el = el.Next() {
|
||||||
|
candidate := el.Value.(*CandidateNode)
|
||||||
|
targetNode := UnwrapDoc(candidate.Node)
|
||||||
|
|
||||||
|
switch targetNode.Kind {
|
||||||
|
case yaml.MappingNode:
|
||||||
|
node := &yaml.Node{Kind: yaml.SequenceNode, Value: fmt.Sprintf("%v", length), Tag: "!!int"}
|
||||||
|
|
||||||
|
case yaml.SequenceNode:
|
||||||
|
length = len(targetNode.Content)
|
||||||
|
default:
|
||||||
|
length = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", length), Tag: "!!int"}
|
||||||
|
lengthCand := &CandidateNode{Node: node, Document: candidate.Document, Path: candidate.Path}
|
||||||
|
results.PushBack(lengthCand)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
88
pkg/yqlib/operator_keys_test.go
Normal file
88
pkg/yqlib/operator_keys_test.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var keyOperatorScenarios = []expressionScenario{
|
||||||
|
{
|
||||||
|
description: "Get Keys of map",
|
||||||
|
document: `{a: {b: cat, c: dog, d: frog}}`,
|
||||||
|
expression: `.a | keys`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!seq)::- b\n- c\n- d\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{a1: {b: cat, c: dog, d: frog}, a2: {e: cat, f: dog, g: frog}}`,
|
||||||
|
expression: `(.a1, .a2) | keys`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a1], (!!seq)::- b\n- c\n- d\n",
|
||||||
|
"D0, P[a2], (!!seq)::- e\n- f\n- g\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Get Keys of array",
|
||||||
|
document: `{a: [0,1,2]}`,
|
||||||
|
expression: `.a | keys`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!seq)::0\n",
|
||||||
|
"D0, P[a], (!!int)::1\n",
|
||||||
|
"D0, P[a], (!!int)::2\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Set key style",
|
||||||
|
document: `{a: {b: cat, c: dog, d: frog}}`,
|
||||||
|
expression: `(.a | keys | ..) style = 'single'`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!doc)::{a: {'b': cat, 'c': dog, 'd': frog}}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Set key alias",
|
||||||
|
document: `{a: {b: cat, c: dog, d: frog}}`,
|
||||||
|
expression: `(.a | keys | .. | select(.=="b")) alias = 'boo'`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!doc)::{a: {*meow: cat, c: dog, d: frog}}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Set key alias",
|
||||||
|
document: `{a: {b: cat, c: dog, d: frog}}`,
|
||||||
|
expression: `(.a | key("b")) alias = 'boo'`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!doc)::{a: {*meow: cat, c: dog, d: frog}}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{a: [0,1,2]}`,
|
||||||
|
expression: `(.a | keys) style = 'single'`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!int)::0\n",
|
||||||
|
"D0, P[a], (!!int)::1\n",
|
||||||
|
"D0, P[a], (!!int)::2\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `a: cat`,
|
||||||
|
expression: `.a | keys`,
|
||||||
|
expected: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{}`,
|
||||||
|
expression: `.a | keys`,
|
||||||
|
expected: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKeyOperatorScenarios(t *testing.T) {
|
||||||
|
for _, tt := range keyOperatorScenarios {
|
||||||
|
testScenario(t, &tt)
|
||||||
|
}
|
||||||
|
documentScenarios(t, "Keys", keyOperatorScenarios)
|
||||||
|
}
|
@ -182,6 +182,7 @@ func initLexer() (*lex.Lexer, error) {
|
|||||||
lexer.Add([]byte(`,`), opToken(Union))
|
lexer.Add([]byte(`,`), opToken(Union))
|
||||||
lexer.Add([]byte(`:\s*`), opToken(CreateMap))
|
lexer.Add([]byte(`:\s*`), opToken(CreateMap))
|
||||||
lexer.Add([]byte(`length`), opToken(Length))
|
lexer.Add([]byte(`length`), opToken(Length))
|
||||||
|
lexer.Add([]byte(`keys`), opToken(Keys))
|
||||||
lexer.Add([]byte(`sortKeys`), opToken(SortKeys))
|
lexer.Add([]byte(`sortKeys`), opToken(SortKeys))
|
||||||
lexer.Add([]byte(`select`), opToken(Select))
|
lexer.Add([]byte(`select`), opToken(Select))
|
||||||
lexer.Add([]byte(`has`), opToken(Has))
|
lexer.Add([]byte(`has`), opToken(Has))
|
||||||
|
10
pkg/yqlib/test.yml
Normal file
10
pkg/yqlib/test.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"a1": {
|
||||||
|
"b": "cat",
|
||||||
|
"c": "dog"
|
||||||
|
},
|
||||||
|
"a2": {
|
||||||
|
"d": "cat",
|
||||||
|
"e": "dog"
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user