Member-only story
How to Customize “yq” Operators in Go
yq already has abundant operators that cover most scenarios, but sometimes some unique operators are still needed, such as in scenarios with generic operations like sort
, has
, contains
, or in complex scenarios where we must write complex expressions that frequently combine multiple operators.
Take the insert
operator as an example. yq supports adding items to the array or map, but only at the head or tail of the array, not inserting by position. While a new insert
operator can add item
by index, such as
# a: ['dog']
# append
yq '.a += "cat"' sample.yml
# insert to head
yq '.a = ["cat"] + .a' sample.yml
# a: - cat
# - dog
yq '.a | insert(1, "pig") sample.yml
In the previous article, we had a basic understanding of how yq.4x is built, preparing us for customizing yq operators. Today we will learn to make an operator by modifying the source code. The operators we customize can be shared among colleagues or contributed to the community to save us the effort to reinvent the wheels.
Write the Operator
Take the insert
operator as an example again. There are three steps to go.
Design the operator
The logic of the insert
operator in the example below is quite simple. It always begins with a sequence node in the YAML, and then it involves inserting a string or number into the sequence at the specified position.
Write the code
Implement a operator_insert.go
, which contains the insert
function.
The operator implementation often follows a certain workflow.
- Find the matching nodes. In this example, find the sequence node
.a
. - Traverse the expression tree and get all inputs the operator needs. That is the
index(1)
and item value(“pig”)
. - Finish the operator's action by creating a new sequence node, then return.