mirror of
				https://github.com/taigrr/yq
				synced 2025-01-18 04:53:17 -08:00 
			
		
		
		
	Added anchor operator
This commit is contained in:
		
							parent
							
								
									e5aa4a87a4
								
							
						
					
					
						commit
						f112bde5fe
					
				
							
								
								
									
										29
									
								
								pkg/yqlib/doc/Anchor Operators.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								pkg/yqlib/doc/Anchor Operators.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | 
 | ||||||
|  | ## Get anchor | ||||||
|  | Given a sample.yml file of: | ||||||
|  | ```yaml | ||||||
|  | a: &billyBob cat | ||||||
|  | ``` | ||||||
|  | then | ||||||
|  | ```bash | ||||||
|  | yq eval '.a | anchor' sample.yml | ||||||
|  | ``` | ||||||
|  | will output | ||||||
|  | ```yaml | ||||||
|  | billyBob | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Set anchor name | ||||||
|  | Given a sample.yml file of: | ||||||
|  | ```yaml | ||||||
|  | a: cat | ||||||
|  | ``` | ||||||
|  | then | ||||||
|  | ```bash | ||||||
|  | yq eval '.a anchor = "foobar"' sample.yml | ||||||
|  | ``` | ||||||
|  | will output | ||||||
|  | ```yaml | ||||||
|  | a: &foobar cat | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| @ -36,6 +36,7 @@ var AssignAttributes = &OperationType{Type: "ASSIGN_ATTRIBUTES", NumArgs: 2, Pre | |||||||
| var AssignStyle = &OperationType{Type: "ASSIGN_STYLE", NumArgs: 2, Precedence: 40, Handler: AssignStyleOperator} | var AssignStyle = &OperationType{Type: "ASSIGN_STYLE", NumArgs: 2, Precedence: 40, Handler: AssignStyleOperator} | ||||||
| var AssignTag = &OperationType{Type: "ASSIGN_TAG", NumArgs: 2, Precedence: 40, Handler: AssignTagOperator} | var AssignTag = &OperationType{Type: "ASSIGN_TAG", NumArgs: 2, Precedence: 40, Handler: AssignTagOperator} | ||||||
| var AssignComment = &OperationType{Type: "ASSIGN_COMMENT", NumArgs: 2, Precedence: 40, Handler: AssignCommentsOperator} | var AssignComment = &OperationType{Type: "ASSIGN_COMMENT", NumArgs: 2, Precedence: 40, Handler: AssignCommentsOperator} | ||||||
|  | var AssignAnchor = &OperationType{Type: "ASSIGN_ANCHOR", NumArgs: 2, Precedence: 40, Handler: AssignAnchorOperator} | ||||||
| 
 | 
 | ||||||
| var Multiply = &OperationType{Type: "MULTIPLY", NumArgs: 2, Precedence: 45, Handler: MultiplyOperator} | var Multiply = &OperationType{Type: "MULTIPLY", NumArgs: 2, Precedence: 45, Handler: MultiplyOperator} | ||||||
| var Add = &OperationType{Type: "ADD", NumArgs: 2, Precedence: 45, Handler: AddOperator} | var Add = &OperationType{Type: "ADD", NumArgs: 2, Precedence: 45, Handler: AddOperator} | ||||||
| @ -51,6 +52,7 @@ var Collect = &OperationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handle | |||||||
| 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} | ||||||
| var GetComment = &OperationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: GetCommentsOperator} | var GetComment = &OperationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: GetCommentsOperator} | ||||||
|  | var GetAnchor = &OperationType{Type: "GET_ANCHOR", NumArgs: 0, Precedence: 50, Handler: GetAnchorOperator} | ||||||
| var GetDocumentIndex = &OperationType{Type: "GET_DOCUMENT_INDEX", NumArgs: 0, Precedence: 50, Handler: GetDocumentIndexOperator} | var GetDocumentIndex = &OperationType{Type: "GET_DOCUMENT_INDEX", NumArgs: 0, Precedence: 50, Handler: GetDocumentIndexOperator} | ||||||
| var GetFilename = &OperationType{Type: "GET_FILENAME", NumArgs: 0, Precedence: 50, Handler: GetFilenameOperator} | var GetFilename = &OperationType{Type: "GET_FILENAME", NumArgs: 0, Precedence: 50, Handler: GetFilenameOperator} | ||||||
| var GetFileIndex = &OperationType{Type: "GET_FILE_INDEX", NumArgs: 0, Precedence: 50, Handler: GetFileIndexOperator} | var GetFileIndex = &OperationType{Type: "GET_FILE_INDEX", NumArgs: 0, Precedence: 50, Handler: GetFileIndexOperator} | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								pkg/yqlib/operator_anchor_name.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								pkg/yqlib/operator_anchor_name.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | package yqlib | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"container/list" | ||||||
|  | 
 | ||||||
|  | 	"gopkg.in/yaml.v3" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func AssignAnchorOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) { | ||||||
|  | 
 | ||||||
|  | 	log.Debugf("AssignAnchor operator!") | ||||||
|  | 
 | ||||||
|  | 	rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	anchorName := "" | ||||||
|  | 	if rhs.Front() != nil { | ||||||
|  | 		anchorName = rhs.Front().Value.(*CandidateNode).Node.Value | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for el := lhs.Front(); el != nil; el = el.Next() { | ||||||
|  | 		candidate := el.Value.(*CandidateNode) | ||||||
|  | 		log.Debugf("Setting anchorName of : %v", candidate.GetKey()) | ||||||
|  | 		candidate.Node.Anchor = anchorName | ||||||
|  | 	} | ||||||
|  | 	return matchingNodes, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func GetAnchorOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) { | ||||||
|  | 	log.Debugf("GetAnchor operator!") | ||||||
|  | 	var results = list.New() | ||||||
|  | 
 | ||||||
|  | 	for el := matchingNodes.Front(); el != nil; el = el.Next() { | ||||||
|  | 		candidate := el.Value.(*CandidateNode) | ||||||
|  | 		anchor := candidate.Node.Anchor | ||||||
|  | 		node := &yaml.Node{Kind: yaml.ScalarNode, Value: anchor, Tag: "!!str"} | ||||||
|  | 		lengthCand := &CandidateNode{Node: node, Document: candidate.Document, Path: candidate.Path} | ||||||
|  | 		results.PushBack(lengthCand) | ||||||
|  | 	} | ||||||
|  | 	return results, nil | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								pkg/yqlib/operator_anchor_name_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								pkg/yqlib/operator_anchor_name_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | package yqlib | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var anchorOperatorScenarios = []expressionScenario{ | ||||||
|  | 	{ | ||||||
|  | 		description: "Get anchor", | ||||||
|  | 		document:    `a: &billyBob cat`, | ||||||
|  | 		expression:  `.a | anchor`, | ||||||
|  | 		expected: []string{ | ||||||
|  | 			"D0, P[a], (!!str)::billyBob\n", | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		description: "Set anchor name", | ||||||
|  | 		document:    `a: cat`, | ||||||
|  | 		expression:  `.a anchor = "foobar"`, | ||||||
|  | 		expected: []string{ | ||||||
|  | 			"D0, P[], (doc)::a: &foobar cat\n", | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestAnchorOperatorScenarios(t *testing.T) { | ||||||
|  | 	for _, tt := range anchorOperatorScenarios { | ||||||
|  | 		testScenario(t, &tt) | ||||||
|  | 	} | ||||||
|  | 	documentScenarios(t, "Anchor Operators", anchorOperatorScenarios) | ||||||
|  | } | ||||||
| @ -208,6 +208,7 @@ func initLexer() (*lex.Lexer, error) { | |||||||
| 	lexer.Add([]byte(`style`), opAssignableToken(GetStyle, AssignStyle)) | 	lexer.Add([]byte(`style`), opAssignableToken(GetStyle, AssignStyle)) | ||||||
| 
 | 
 | ||||||
| 	lexer.Add([]byte(`tag`), opAssignableToken(GetTag, AssignTag)) | 	lexer.Add([]byte(`tag`), opAssignableToken(GetTag, AssignTag)) | ||||||
|  | 	lexer.Add([]byte(`anchor`), opAssignableToken(GetAnchor, AssignAnchor)) | ||||||
| 	lexer.Add([]byte(`filename`), opToken(GetFilename)) | 	lexer.Add([]byte(`filename`), opToken(GetFilename)) | ||||||
| 	lexer.Add([]byte(`fileIndex`), opToken(GetFileIndex)) | 	lexer.Add([]byte(`fileIndex`), opToken(GetFileIndex)) | ||||||
| 	lexer.Add([]byte(`path`), opToken(GetPath)) | 	lexer.Add([]byte(`path`), opToken(GetPath)) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user