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 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 GetStyle = &OperationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: GetStyleOperator}
|
||||
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(`:\s*`), opToken(CreateMap))
|
||||
lexer.Add([]byte(`length`), opToken(Length))
|
||||
lexer.Add([]byte(`keys`), opToken(Keys))
|
||||
lexer.Add([]byte(`sortKeys`), opToken(SortKeys))
|
||||
lexer.Add([]byte(`select`), opToken(Select))
|
||||
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