walky

package module
v0.0.0-...-963001b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2022 License: Apache-2.0 Imports: 8 Imported by: 3

README

Go Reference

walky - Walk YAML

This is a companion to go-yaml/yaml.v3 to walk and modify abstract *yaml.Node trees.

Example:

package main
import (
	"fmt"

	"github.com/coryb/walky"
	"gopkg.in/yaml.v3"
)

func main() {
	doc := `# foo is a bar
foo: bar
someMap:
  - someKey: value # line comment
# bin is a baz
bin: baz
`
	var root yaml.Node
	_ = yaml.Unmarshal([]byte(doc), &root)

	// we can choose to sort the map if we want
	sort.Sort(walky.SortableNodeMap(&root))

	// create new *yaml.Node from interface{} value
	newNode, _ := walky.ToNode("new\nvalue")

	// walk the document tree, looking for keys `someMap`, then
	// index 0, then key `someKey`.  That node resulting from
	// the walk is passed to the `func(node *yaml.Node) error`
	// callback, where we reassign the node.
	_ = walky.WalkPath(&root, func(node *yaml.Node) error {
		walky.AssignNode(node, newNode)
		return nil
	}, "someMap", 0, "someKey")

	// we can also insert new keys to maps and slices
	keyNode, _ := walky.ToNode("newkey")
	newNode, _ = walky.ToNode("new value")
	// Add comments via code
	newNode.LineComment = "<-- Look Here"
	_ = walky.AssignMapNode(&root, keyNode, newNode)

	// now we will fetch the sequence under someMap and
	// append a new value to it
	newNode, _ = walky.ToNode(42)
	_ = walky.WalkPath(&root, func(node *yaml.Node) error {
		walky.AppendNode(node, newNode)
		return nil
	}, "someMap")

	newDoc, _ := yaml.Marshal(&root)
	fmt.Println(string(newDoc))
	// Output:
	// # bin is a baz
	// bin: baz
	// # foo is a bar
	// foo: bar
	// newkey: new value # <-- Look Here
	// someMap:
	//     - someKey: |- # line comment
	//         new
	//         value
	//     - 42
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrStopRange = errors.New("stop ranging")

ErrStopRange can be returned from the RangerFunc to immediately stop iterating over the map. If this is returned from the RangerFunc then RangeMap will return nil.

Functions

func AppendNode

func AppendNode(listNode, valNode *yaml.Node) error

func AssignMapNode

func AssignMapNode(mapNode, keyNode, valNode *yaml.Node) error

func AssignNode

func AssignNode(destNode, srcNode *yaml.Node)

AssignNode copies over the structure data from `srcNode` leaving the document data alone (comments, line numbers etc are preserved in `destNode`).

func CopyNode

func CopyNode(src *yaml.Node) *yaml.Node

CopyNode will do a deep copy of the src Node and return a copy

func Equal

func Equal(a *yaml.Node, b *yaml.Node) bool

func ErrDecode

func ErrDecode(err error) error

func ErrFilename

func ErrFilename(err error, filename string) error

func GetIndex

func GetIndex(parent *yaml.Node, target *yaml.Node) int

GetIndex returns the index of the target node found in the parent node. If the parent is a MappingNode the index corresponds to the key node (the value will be the key node index + 1). If the parent node is not a SequenceNode or a MappingNode, then -1 will be returned. Also if the target node is not found then -1 will be returned.

func GetKey

func GetKey(mapNode *yaml.Node, key interface{}) (node *yaml.Node)

func GetKeyValue

func GetKeyValue(mapNode *yaml.Node, key *yaml.Node) (keyNode *yaml.Node, valueNode *yaml.Node)

GetKeyValue is used to to simplify getting both the key and value nodes from the provided MappingNode. If the key node is not found then the returned nodes will both be `nil`

func HasKey

func HasKey(mapNode *yaml.Node, key interface{}) bool

func Indirect

func Indirect(node *yaml.Node) *yaml.Node

Indirect will return the aliased node if this node is an alias, otherwise it will return the original node.

func IsNull

func IsNull(node *yaml.Node) bool

IsNull will return true if the node Kind is ScalarNode and the node tag is !!null

func KindString

func KindString(k yaml.Kind) string

KindString will return a human-readable string that represents the yaml.Kind arguments.

func NewBoolNode

func NewBoolNode(value bool) *yaml.Node

NewBoolNode creates a new Node with the value of the provided bool.

func NewDocumentNode

func NewDocumentNode() *yaml.Node

func NewFloatNode

func NewFloatNode(value float64) *yaml.Node

NewFloatNode creates a new Node with the value of the provided float64.

func NewIntNode

func NewIntNode(value int64) *yaml.Node

NewIntNode creates a new Node with the value of the provided int64.

func NewMappingNode

func NewMappingNode() *yaml.Node

func NewSequenceNode

func NewSequenceNode() *yaml.Node

func NewStringNode

func NewStringNode(value string) *yaml.Node

NewStringNode creates a new Node with the value of the provided string.

func NewYAMLError

func NewYAMLError(err error, node *yaml.Node) error

func RangeMap

func RangeMap(node *yaml.Node, f RangerFunc, opts ...RangeOption) error

RangeMap will iterate over `node`, calling the RangerFunc for each key/value pair. An error will be returned if the node is not a mapping node (or an alias referencing a mapping node). An error will be returned unless the node.Content is an even length. If the RangerFunc returns an error it will be returned immediately.

func ReadFile

func ReadFile(filepath string) (*yaml.Node, error)

ReadFile is a helper function to read a file and return a yaml.Node

func Remove

func Remove(parent *yaml.Node, target *yaml.Node) bool

Remove will delete target node from parent node. If parent is a MappingNode then target should correspond to the mapping Key. If parent is a SequenceNode then the target node will be deleted. Returns true if and only if the target was found in the parent.

func ShallowCopyNode

func ShallowCopyNode(src *yaml.Node) *yaml.Node

ShallowCopyNode will do a shallow copy of the src Node and return a copy. Any Contents and Alias will not be copied.

func SortableNodeMap

func SortableNodeMap(mapNode *yaml.Node) sort.Interface

func ToNode

func ToNode(val interface{}) (*yaml.Node, error)

func UnwrapDocument

func UnwrapDocument(node *yaml.Node) *yaml.Node

UnwrapDocument removes the root node if and only if the root node has a Kind value of `yaml.DocumentNode`. It returns the first child node of the root, which is typically the document data.

func Walk

func Walk(node *yaml.Node, f WalkFunc, walkOpts ...WalkOpt) error

func WalkPath

func WalkPath(root *yaml.Node, fn NodeFunc, path ...interface{}) error
Example
doc := `# foo is a bar
foo: bar
someMap:
  - someKey: value # line comment
# bin is a baz
bin: baz
`
var root yaml.Node
_ = yaml.Unmarshal([]byte(doc), &root)

// we can choose to sort the map if we want
sort.Sort(walky.SortableNodeMap(&root))

// create new *yaml.Node from interface{} value
newNode, _ := walky.ToNode("new\nvalue")

// walk the document tree, looking for keys `someMap`, then
// index 0, then key `someKey`.  That node resulting from
// the walk is passed to the `func(node *yaml.Node) error`
// callback, where we reassign the node.
_ = walky.WalkPath(&root, func(node *yaml.Node) error {
	walky.AssignNode(node, newNode)
	return nil
}, "someMap", 0, "someKey")

// we can also insert new keys to maps and slices
keyNode, _ := walky.ToNode("newkey")
newNode, _ = walky.ToNode("new value")
// Add comments via code
newNode.LineComment = "<-- Look Here"
_ = walky.AssignMapNode(&root, keyNode, newNode)

// now we will fetch the sequence under someMap and
// append a new value to it
newNode, _ = walky.ToNode(42)
_ = walky.WalkPath(&root, func(node *yaml.Node) error {
	walky.AppendNode(node, newNode)
	return nil
}, "someMap")

newDoc, _ := yaml.Marshal(&root)
fmt.Println(string(newDoc))
Output:

# bin is a baz
bin: baz
# foo is a bar
foo: bar
newkey: new value # <-- Look Here
someMap:
    - someKey: |- # line comment
        new
        value
    - 42

func WalkPathMatchers

func WalkPathMatchers(root *yaml.Node, fn NodeFunc, matchers ...PathMatcher) error

Types

type NodeFunc

type NodeFunc func(node *yaml.Node) error

type PathMatcher

type PathMatcher interface {
	Match(node *yaml.Node, fn NodeFunc) error
}

func AnyMatcher

func AnyMatcher(walkOpts ...WalkOpt) PathMatcher

func IndexMatcher

func IndexMatcher(i int) PathMatcher

func NodeMatcher

func NodeMatcher(n *yaml.Node) PathMatcher

func StringMatcher

func StringMatcher(key string) PathMatcher

type RangeOption

type RangeOption func(*rangeOption)

func WithMergesLast

func WithMergesLast() RangeOption

WithMergesLast changes the `!!merge` node processing from being inline to be appended to the current iteration. For example:

defs:
  - &mymap {key: 1}
mystuff:
  <<: *mymap
  key: 2

by default RangeMap will process the `!!merge` since it is the first key in `mystuff`, so the RangerFunc will see `key: 1` first, then `key: 2`. If `WithMergesLast` is used, then the RangerFunc will see `key: 2` first, then `key: 1`

type RangerFunc

type RangerFunc func(key, value *yaml.Node) error

RangerFunc is the callback used to iterate over a map via RangeMap. The function is called for each key/value pair found in the map. If an error is returned then RangeMap will immediately return the error. To stop iteration without RangeMap returning an error, you can return ErrStopRange.

type WalkFunc

type WalkFunc func(current, parent *yaml.Node, position int, opts *WalkOptions) (WalkStatus, error)

func IndexWalker

func IndexWalker(ix int, f NodeFunc) WalkFunc

func ScalarValuesWalker

func ScalarValuesWalker(f NodeFunc) WalkFunc

func StringWalker

func StringWalker(key string, f NodeFunc) WalkFunc

StringWalker is used with Walk to apply `f` to map values that match the provided key string. If the match is against a map key then the `NodeFunc` will be called with the map value. If the match is not a map key, then the `NodeFunc` will be called on the matched node.

type WalkOpt

type WalkOpt func(*WalkOptions)

func WithBreadthFirst

func WithBreadthFirst() WalkOpt

func WithFirstOnly

func WithFirstOnly() WalkOpt

func WithMaxDepth

func WithMaxDepth(max int) WalkOpt

func WithTrace

func WithTrace(f func(current, parent *yaml.Node, pos, depth int, ws WalkStatus, err error)) WalkOpt

type WalkOptions

type WalkOptions struct {
	// contains filtered or unexported fields
}

func (*WalkOptions) MatchStatus

func (opts *WalkOptions) MatchStatus() WalkStatus

func (*WalkOptions) MissStatus

func (opts *WalkOptions) MissStatus() WalkStatus

type WalkStatus

type WalkStatus int
const (
	WalkExit WalkStatus = iota
	WalkDepthFirst
	WalkBreadthFirst
	WalkPrune
)

func (WalkStatus) String

func (ws WalkStatus) String() string

type YAMLError

type YAMLError struct {
	Line     int
	Column   int
	Filename string
	Context  string
	Err      error
}

func (YAMLError) Error

func (e YAMLError) Error() string

func (YAMLError) Format

func (e YAMLError) Format(s fmt.State, verb rune)

func (YAMLError) Unwrap

func (e YAMLError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL