mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-13 22:38:04 +00:00
wip
This commit is contained in:
parent
aad15ccc6e
commit
972e2b9575
@ -1,7 +1,10 @@
|
|||||||
- command: update
|
- command: update
|
||||||
path: b.c
|
path: b.c
|
||||||
value:
|
value:
|
||||||
#great
|
#great
|
||||||
things: frog # wow!
|
things: frog # wow!
|
||||||
|
- command: update
|
||||||
b.e[+].name: Mike Farah
|
path: b.e[+].name
|
||||||
|
value: Mike Farah
|
||||||
|
- command: delete
|
||||||
|
path: a
|
@ -7,14 +7,9 @@ import (
|
|||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WriteCommand struct {
|
|
||||||
// Command string TODO
|
|
||||||
Value yaml.Node
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataNavigator interface {
|
type DataNavigator interface {
|
||||||
Get(rootNode *yaml.Node, remainingPath []string) (*yaml.Node, error)
|
Get(rootNode *yaml.Node, remainingPath []string) (*yaml.Node, error)
|
||||||
Update(rootNode *yaml.Node, remainingPath []string, writeCommand WriteCommand) error
|
Update(rootNode *yaml.Node, remainingPath []string, changesToApply yaml.Node) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type navigator struct {
|
type navigator struct {
|
||||||
@ -33,7 +28,7 @@ func (n *navigator) Get(value *yaml.Node, path []string) (*yaml.Node, error) {
|
|||||||
realValue = value.Content[0]
|
realValue = value.Content[0]
|
||||||
}
|
}
|
||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
n.log.Debug("diving into %v", path[0])
|
n.log.Debugf("diving into %v", path[0])
|
||||||
return n.recurse(realValue, path[0], path[1:])
|
return n.recurse(realValue, path[0], path[1:])
|
||||||
}
|
}
|
||||||
return realValue, nil
|
return realValue, nil
|
||||||
@ -117,15 +112,11 @@ func (n *navigator) recurse(value *yaml.Node, head string, tail []string) (*yaml
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *navigator) Update(dataBucket *yaml.Node, remainingPath []string, writeCommand WriteCommand) error {
|
func (n *navigator) Update(dataBucket *yaml.Node, remainingPath []string, changesToApply yaml.Node) error {
|
||||||
nodeToUpdate, errorRecursing := n.Get(dataBucket, remainingPath)
|
nodeToUpdate, errorRecursing := n.Get(dataBucket, remainingPath)
|
||||||
if errorRecursing != nil {
|
if errorRecursing != nil {
|
||||||
return errorRecursing
|
return errorRecursing
|
||||||
}
|
}
|
||||||
// later, support ability to execute other commands
|
|
||||||
|
|
||||||
changesToApply := writeCommand.Value
|
|
||||||
|
|
||||||
nodeToUpdate.Value = changesToApply.Value
|
nodeToUpdate.Value = changesToApply.Value
|
||||||
nodeToUpdate.Tag = changesToApply.Tag
|
nodeToUpdate.Tag = changesToApply.Tag
|
||||||
nodeToUpdate.Kind = changesToApply.Kind
|
nodeToUpdate.Kind = changesToApply.Kind
|
||||||
|
@ -1,24 +1,34 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
logging "gopkg.in/op/go-logging.v1"
|
logging "gopkg.in/op/go-logging.v1"
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UpdateCommand struct {
|
||||||
|
Command string
|
||||||
|
Path string
|
||||||
|
Value yaml.Node
|
||||||
|
}
|
||||||
|
|
||||||
type YqLib interface {
|
type YqLib interface {
|
||||||
Get(rootNode *yaml.Node, path string) (*yaml.Node, error)
|
Get(rootNode *yaml.Node, path string) (*yaml.Node, error)
|
||||||
Update(rootNode *yaml.Node, path string, writeCommand WriteCommand) error
|
Update(rootNode *yaml.Node, updateCommand UpdateCommand) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type lib struct {
|
type lib struct {
|
||||||
navigator DataNavigator
|
navigator DataNavigator
|
||||||
parser PathParser
|
parser PathParser
|
||||||
|
log *logging.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYqLib(l *logging.Logger) YqLib {
|
func NewYqLib(l *logging.Logger) YqLib {
|
||||||
return &lib{
|
return &lib{
|
||||||
navigator: NewDataNavigator(l),
|
navigator: NewDataNavigator(l),
|
||||||
parser: NewPathParser(),
|
parser: NewPathParser(),
|
||||||
|
log: l,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +40,18 @@ func (l *lib) Get(rootNode *yaml.Node, path string) (*yaml.Node, error) {
|
|||||||
return l.navigator.Get(rootNode, paths)
|
return l.navigator.Get(rootNode, paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lib) Update(rootNode *yaml.Node, path string, writeCommand WriteCommand) error {
|
func (l *lib) Update(rootNode *yaml.Node, updateCommand UpdateCommand) error {
|
||||||
var paths = l.parser.ParsePath(path)
|
// later - support other command types
|
||||||
return l.navigator.Update(rootNode, paths, writeCommand)
|
l.log.Debugf("%v to %v", updateCommand.Command, updateCommand.Path)
|
||||||
|
switch updateCommand.Command {
|
||||||
|
case "update":
|
||||||
|
var paths = l.parser.ParsePath(updateCommand.Path)
|
||||||
|
return l.navigator.Update(rootNode, paths, updateCommand.Value)
|
||||||
|
case "delete":
|
||||||
|
l.log.Debugf("need to implement delete")
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown command %v", updateCommand.Command)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
52
yq.go
52
yq.go
@ -19,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var rawOutput = false
|
var rawOutput = false
|
||||||
var trimOutput = true
|
var customTag = ""
|
||||||
var writeInplace = false
|
var writeInplace = false
|
||||||
var writeScript = ""
|
var writeScript = ""
|
||||||
var outputToJSON = false
|
var outputToJSON = false
|
||||||
@ -74,7 +74,6 @@ func newCommandCLI() *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(&trimOutput, "trim", "t", true, "trim yaml output")
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose mode")
|
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose mode")
|
||||||
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
||||||
|
|
||||||
@ -144,6 +143,7 @@ a.b.e:
|
|||||||
}
|
}
|
||||||
cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||||
cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
||||||
|
cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||||
cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
return cmdWrite
|
return cmdWrite
|
||||||
}
|
}
|
||||||
@ -327,7 +327,7 @@ func readProperty(cmd *cobra.Command, args []string) error {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// func newYaml(args []string) (interface{}, error) {
|
// func newYaml(args []string) (interface{}, error) {
|
||||||
// var writeCommands, writeCommandsError = readWriteCommands(args, 2, "Must provide <path_to_update> <value>")
|
// var writeCommands, writeCommandsError = readUpdateCommands(args, 2, "Must provide <path_to_update> <value>")
|
||||||
// if writeCommandsError != nil {
|
// if writeCommandsError != nil {
|
||||||
// return nil, writeCommandsError
|
// return nil, writeCommandsError
|
||||||
// }
|
// }
|
||||||
@ -404,9 +404,9 @@ func mapYamlDecoder(updateData updateDataFn, encoder *yaml.Encoder) yamlDecoderF
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeProperty(cmd *cobra.Command, args []string) error {
|
func writeProperty(cmd *cobra.Command, args []string) error {
|
||||||
var writeCommands, writeCommandsError = readWriteCommands(args, 3, "Must provide <filename> <path_to_update> <value>")
|
var updateCommands, updateCommandsError = readUpdateCommands(args, 3, "Must provide <filename> <path_to_update> <value>")
|
||||||
if writeCommandsError != nil {
|
if updateCommandsError != nil {
|
||||||
return writeCommandsError
|
return updateCommandsError
|
||||||
}
|
}
|
||||||
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||||
if errorParsingDocIndex != nil {
|
if errorParsingDocIndex != nil {
|
||||||
@ -416,12 +416,8 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
|||||||
var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
||||||
if updateAll || currentIndex == docIndexInt {
|
if updateAll || currentIndex == docIndexInt {
|
||||||
log.Debugf("Updating doc %v", currentIndex)
|
log.Debugf("Updating doc %v", currentIndex)
|
||||||
for _, entry := range writeCommands {
|
for _, updateCommand := range updateCommands {
|
||||||
path := entry.Key
|
errorUpdating := lib.Update(dataBucket, updateCommand)
|
||||||
changesToApply := entry.Value
|
|
||||||
var paths = parsePath(path)
|
|
||||||
|
|
||||||
errorUpdating := updateChild(dataBucket, paths, changesToApply)
|
|
||||||
if errorUpdating != nil {
|
if errorUpdating != nil {
|
||||||
return errorUpdating
|
return errorUpdating
|
||||||
}
|
}
|
||||||
@ -552,36 +548,20 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
|
|||||||
// return readAndUpdate(cmd.OutOrStdout(), input, updateData)
|
// return readAndUpdate(cmd.OutOrStdout(), input, updateData)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
type rawWriteCommand struct {
|
func readUpdateCommands(args []string, expectedArgs int, badArgsMessage string) ([]yqlib.UpdateCommand, error) {
|
||||||
// Command string TODO
|
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 1)
|
||||||
Key string
|
|
||||||
Value yaml.Node
|
|
||||||
}
|
|
||||||
|
|
||||||
func readWriteCommands(args []string, expectedArgs int, badArgsMessage string) ([]rawWriteCommand, error) {
|
|
||||||
var writeCommands []rawWriteCommand
|
|
||||||
if writeScript != "" {
|
if writeScript != "" {
|
||||||
var rawCommands yaml.Node
|
if err := readData(writeScript, 0, &updateCommands); err != nil {
|
||||||
if err := readData(writeScript, 0, &rawCommands); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Debugf("Read write commands file '%v'", rawCommands)
|
log.Debugf("Read write commands file '%v'", updateCommands)
|
||||||
var key string
|
|
||||||
for index, content := range rawCommands.Content[0].Content {
|
|
||||||
if index%2 == 0 { // must be the key
|
|
||||||
key = content.Value
|
|
||||||
} else { // its the value
|
|
||||||
writeCommands = append(writeCommands, rawWriteCommand{Key: key, Value: *content})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Debugf("Read write commands '%v'", writeCommands)
|
|
||||||
} else if len(args) < expectedArgs {
|
} else if len(args) < expectedArgs {
|
||||||
return nil, errors.New(badArgsMessage)
|
return nil, errors.New(badArgsMessage)
|
||||||
} else {
|
} else {
|
||||||
writeCommands = make([]rawWriteCommand, 1)
|
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||||
writeCommands[0] = rawWriteCommand{Key: args[expectedArgs-2], Value: parseValue(args[expectedArgs-1])}
|
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: parseValue(args[expectedArgs-1])}
|
||||||
}
|
}
|
||||||
return writeCommands, nil
|
return updateCommands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseValue(argument string) yaml.Node {
|
func parseValue(argument string) yaml.Node {
|
||||||
@ -619,7 +599,7 @@ func toString(context interface{}) (string, error) {
|
|||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
return jsonConverter.JsonToString(context)
|
return jsonConverter.JsonToString(context)
|
||||||
}
|
}
|
||||||
return yamlConverter.YamlToString(context, trimOutput)
|
return yamlConverter.YamlToString(context, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func safelyRenameFile(from string, to string) {
|
func safelyRenameFile(from string, to string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user