Added is_key operator

This commit is contained in:
Mike Farah 2022-09-30 10:27:35 +10:00
parent 3dd5f0c80c
commit 55a7fdfd8a
5 changed files with 90 additions and 0 deletions

View File

@ -118,3 +118,43 @@ will output
comment on key comment on key
``` ```
## Check node is a key
Given a sample.yml file of:
```yaml
a:
b:
- cat
c: frog
```
then
```bash
yq '[... | { "p": path | join("."), "isKey": is_key, "tag": tag }]' sample.yml
```
will output
```yaml
- p: ""
isKey: false
tag: '!!map'
- p: a
isKey: true
tag: '!!str'
- p: a
isKey: false
tag: '!!map'
- p: a.b
isKey: true
tag: '!!str'
- p: a.b
isKey: false
tag: '!!seq'
- p: a.b.0
isKey: false
tag: '!!str'
- p: a.c
isKey: true
tag: '!!str'
- p: a.c
isKey: false
tag: '!!str'
```

View File

@ -123,6 +123,7 @@ var participleYqRules = []*participleYqRule{
simpleOp("keys", keysOpType), simpleOp("keys", keysOpType),
simpleOp("key", getKeyOpType), simpleOp("key", getKeyOpType),
simpleOp("is_?key", isKeyOpType),
simpleOp("file_?name|fileName", getFilenameOpType), simpleOp("file_?name|fileName", getFilenameOpType),
simpleOp("file_?index|fileIndex|fi", getFileIndexOpType), simpleOp("file_?index|fileIndex|fi", getFileIndexOpType),

View File

@ -121,6 +121,7 @@ var getStyleOpType = &operationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 5
var getTagOpType = &operationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: getTagOperator} var getTagOpType = &operationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: getTagOperator}
var getKeyOpType = &operationType{Type: "GET_KEY", NumArgs: 0, Precedence: 50, Handler: getKeyOperator} var getKeyOpType = &operationType{Type: "GET_KEY", NumArgs: 0, Precedence: 50, Handler: getKeyOperator}
var isKeyOpType = &operationType{Type: "IS_KEY", NumArgs: 0, Precedence: 50, Handler: isKeyOperator}
var getParentOpType = &operationType{Type: "GET_PARENT", NumArgs: 0, Precedence: 50, Handler: getParentOperator} var getParentOpType = &operationType{Type: "GET_PARENT", NumArgs: 0, Precedence: 50, Handler: getParentOperator}
var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator} var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator}

View File

@ -7,6 +7,20 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
func isKeyOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("-- isKeyOperator")
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
results.PushBack(createBooleanCandidate(candidate, candidate.IsMapKey))
}
return context.ChildContext(results), nil
}
func getKeyOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func getKeyOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("-- getKeyOperator") log.Debugf("-- getKeyOperator")

View File

@ -4,6 +4,32 @@ import (
"testing" "testing"
) )
var expectedIsKey = `D0, P[], (!!seq)::- p: ""
isKey: false
tag: '!!map'
- p: a
isKey: true
tag: '!!str'
- p: a
isKey: false
tag: '!!map'
- p: a.b
isKey: true
tag: '!!str'
- p: a.b
isKey: false
tag: '!!seq'
- p: a.b.0
isKey: false
tag: '!!str'
- p: a.c
isKey: true
tag: '!!str'
- p: a.c
isKey: false
tag: '!!str'
`
var keysOperatorScenarios = []expressionScenario{ var keysOperatorScenarios = []expressionScenario{
{ {
description: "Map keys", description: "Map keys",
@ -75,6 +101,14 @@ var keysOperatorScenarios = []expressionScenario{
"D0, P[a x], (!!str)::comment on key\n", "D0, P[a x], (!!str)::comment on key\n",
}, },
}, },
{
description: "Check node is a key",
document: "a: \n b: [cat]\n c: frog\n",
expression: `[... | { "p": path | join("."), "isKey": is_key, "tag": tag }]`,
expected: []string{
expectedIsKey,
},
},
} }
func TestKeysOperatorScenarios(t *testing.T) { func TestKeysOperatorScenarios(t *testing.T) {