added yamltool sort
This commit is contained in:
+21
-6
@@ -2,10 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// hack to be able to compare slices and dictionires that cannot be put into a map.
|
||||
@@ -45,6 +46,11 @@ func subtract(yaml2 yaml.MapSlice, yaml1 yaml.MapSlice) yaml.MapSlice {
|
||||
v1set[strval(v)] = true
|
||||
}
|
||||
s := make([]any, 0)
|
||||
// TODO
|
||||
// convert both slices to lists of strings
|
||||
// apply LCS to the list of strings with approximate equality
|
||||
// added elements: -> output fully
|
||||
// approximately equal elements: -> when identical, skip, otherwise, output diffs (recurse)
|
||||
for _, v2value := range v2.([]any) {
|
||||
k2 := strval(v2value)
|
||||
if v1set[k2] {
|
||||
@@ -78,13 +84,22 @@ func diff(cmd *cobra.Command, args []string) error {
|
||||
file1 := args[0]
|
||||
file2 := args[1]
|
||||
|
||||
yaml1, err := parse(read(file1))
|
||||
data1, err := read(file1)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("%s: %w", file1, err))
|
||||
return err
|
||||
}
|
||||
yaml2, err := parse(read(file2))
|
||||
data2, err := read(file2)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("%s: %w", file2, err))
|
||||
return err
|
||||
}
|
||||
|
||||
yaml1, err := parse(data1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", file1, err)
|
||||
}
|
||||
yaml2, err := parse(data2)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", file2, err)
|
||||
}
|
||||
|
||||
diff1 := subtract(yaml2, yaml1)
|
||||
|
||||
@@ -2,10 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type MyMap yaml.MapSlice
|
||||
@@ -54,7 +55,11 @@ func mergeMap(yaml1 yaml.MapSlice, yaml2 yaml.MapSlice) yaml.MapSlice {
|
||||
func merge(cmd *cobra.Command, args []string) error {
|
||||
res := make(yaml.MapSlice, 0)
|
||||
for _, arg := range args {
|
||||
config, err := parse(read(arg))
|
||||
data, err := read(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := parse(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", arg, err)
|
||||
}
|
||||
|
||||
+5
-11
@@ -6,18 +6,8 @@ import (
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"os"
|
||||
)
|
||||
|
||||
func read(file string) []byte {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func parse(data []byte) (yaml.MapSlice, error) {
|
||||
var result yaml.MapSlice
|
||||
decoder := yaml.NewDecoder(bytes.NewReader(data),
|
||||
@@ -31,7 +21,11 @@ func parse(data []byte) (yaml.MapSlice, error) {
|
||||
|
||||
func parseFiles(cmd *cobra.Command, args []string) error {
|
||||
for _, arg := range args {
|
||||
_, err := parse(read(arg))
|
||||
data, err := read(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = parse(data)
|
||||
if err != nil {
|
||||
fmt.Printf("%s: %v\n", arg, err.Error())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"os"
|
||||
)
|
||||
|
||||
type MapSlice yaml.MapSlice
|
||||
|
||||
func (s MapSlice) Sort() {
|
||||
slices.SortFunc(s, func(a, b yaml.MapItem) int {
|
||||
keya := fmt.Sprintf("%s", a.Key)
|
||||
keyb := fmt.Sprintf("%s", b.Key)
|
||||
return cmp.Compare(keya, keyb)
|
||||
})
|
||||
for _, item := range s {
|
||||
switch {
|
||||
case reflect.TypeOf(item.Value) == reflect.TypeOf(yaml.MapSlice{}):
|
||||
((MapSlice)(item.Value.(yaml.MapSlice))).Sort()
|
||||
case Type(item.Value) == Slice:
|
||||
for _, v := range item.Value.([]any) {
|
||||
ms, ok := v.(yaml.MapSlice)
|
||||
if ok {
|
||||
((MapSlice)(ms)).Sort()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sortYaml(cmd *cobra.Command, args []string) error {
|
||||
for _, arg := range args {
|
||||
data, err := read(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
doc, err := parse(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v\n", arg, err.Error())
|
||||
}
|
||||
((MapSlice)(doc)).Sort()
|
||||
if len(args) > 1 {
|
||||
fmt.Printf("---\n")
|
||||
}
|
||||
encode(os.Stdout, doc)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func read(file string) ([]byte, error) {
|
||||
|
||||
if file == "-" {
|
||||
data, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading from stdin")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading from '%s'", file)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
@@ -67,6 +67,16 @@ Shows the additions and modifications in <file2> compared to <file1>`,
|
||||
}
|
||||
cmd.AddCommand(parse)
|
||||
|
||||
sort := &cobra.Command{
|
||||
Use: "sort [file1] ... [fileN]",
|
||||
Short: "Sort the yaml output by sorting based on map key ",
|
||||
Long: `Sort yaml files, this makes it easier to also use regular diff`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return sortYaml(cmd, args)
|
||||
},
|
||||
}
|
||||
cmd.AddCommand(sort)
|
||||
|
||||
diff.PersistentFlags().IntVarP(&VERBOSITY, "array-output-level",
|
||||
"v", 3, `Array output level: ,
|
||||
0: no output, only exit status,
|
||||
|
||||
Reference in New Issue
Block a user