before merging in essential fixes.
This commit is contained in:
parent
ec7a29598d
commit
191c32b743
@ -1,54 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var VERBOSITY = 2
|
||||
|
||||
func read(file string) []byte {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func parse(data []byte) yaml.MapSlice {
|
||||
var result yaml.MapSlice
|
||||
decoder := yaml.NewDecoder(bytes.NewReader(data),
|
||||
yaml.UseOrderedMap())
|
||||
err := decoder.Decode(&result)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type TypeId int
|
||||
|
||||
const (
|
||||
Map TypeId = iota
|
||||
Slice
|
||||
Scalar
|
||||
)
|
||||
|
||||
func Type(elem any) TypeId {
|
||||
switch elem.(type) {
|
||||
case yaml.MapSlice:
|
||||
return Map
|
||||
case []any:
|
||||
return Slice
|
||||
default:
|
||||
return Scalar
|
||||
}
|
||||
}
|
||||
|
||||
// hack to be able to compare slices and dictionires that cannot be put into a map.
|
||||
func strval(v any) string {
|
||||
return fmt.Sprintf("%v", v)
|
||||
@ -104,44 +63,41 @@ func subtract(yaml2 yaml.MapSlice, yaml1 yaml.MapSlice) yaml.MapSlice {
|
||||
return res
|
||||
}
|
||||
|
||||
func execute(cmd *cobra.Command, args []string) error {
|
||||
func diff(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 2 {
|
||||
return fmt.Errorf("Parameters expected")
|
||||
return fmt.Errorf("Expected 2 files")
|
||||
}
|
||||
if VERBOSITY < 1 || VERBOSITY > 3 {
|
||||
if VERBOSITY < 0 || VERBOSITY > 3 {
|
||||
return fmt.Errorf("Array verbosity out of range")
|
||||
}
|
||||
file1 := os.Args[1]
|
||||
file2 := os.Args[2]
|
||||
file1 := args[0]
|
||||
file2 := args[1]
|
||||
|
||||
yaml1 := parse(read(file1))
|
||||
yaml2 := parse(read(file2))
|
||||
|
||||
yaml2 = subtract(yaml2, yaml1)
|
||||
diff1 := subtract(yaml2, yaml1)
|
||||
diff2 := make(yaml.MapSlice, 0)
|
||||
if SYMMETRIC_DIFF {
|
||||
diff2 = subtract(yaml1, yaml2)
|
||||
}
|
||||
|
||||
enc := yaml.NewEncoder(os.Stdout,
|
||||
yaml.UseLiteralStyleIfMultiline(true),
|
||||
yaml.Indent(2), // Set indentation
|
||||
//yaml.UseOrderedMap(), // Preserve map order
|
||||
diff := diff1
|
||||
if SYMMETRIC_DIFF {
|
||||
diff = make(yaml.MapSlice, 0)
|
||||
diff = append(diff,
|
||||
yaml.MapItem{Key: "forward", Value: diff1},
|
||||
yaml.MapItem{Key: "backward", Value: diff2},
|
||||
)
|
||||
err := enc.Encode(yaml2)
|
||||
}
|
||||
|
||||
if VERBOSITY > 0 {
|
||||
if err := encode(os.Stdout, diff); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "yamldiff <file1> <file2>",
|
||||
Short: "Shows one-way difference between yaml files",
|
||||
Long: `
|
||||
Shows the changes in <file2> compared to <file1>`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return execute(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().IntVarP(&VERBOSITY, "array-output-level",
|
||||
"v", 1, "Array output level: , 1: only show changed/added values, 2 (default) show identical as <UNMODIFIED>, 3: show all values")
|
||||
|
||||
cmd.Execute()
|
||||
if len(diff1) > 0 || len(diff2) > 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
16
cmd/yamltool/encode.go
Normal file
16
cmd/yamltool/encode.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-yaml"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func encode(writer io.Writer, data any) error {
|
||||
enc := yaml.NewEncoder(os.Stdout,
|
||||
yaml.UseLiteralStyleIfMultiline(true),
|
||||
yaml.Indent(2), // Set indentation
|
||||
//yaml.UseOrderedMap(), // Preserve map order
|
||||
)
|
||||
return enc.Encode(data)
|
||||
}
|
30
cmd/yamltool/merge.go
Normal file
30
cmd/yamltool/merge.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
func mergeMap(yaml1 yaml.MapSlice, yaml2 yaml.MapSlice) yaml.MapSlice {
|
||||
res := yaml1
|
||||
|
||||
//for key, item := range yaml2 {
|
||||
// switch {
|
||||
// case res.ToMap()[key] != nil && type
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func merge(cmd *cobra.Command, args []string) error {
|
||||
res := make(yaml.MapSlice, 0)
|
||||
for _, arg := range args {
|
||||
config := parse(read(arg))
|
||||
res = mergeMap(res, config)
|
||||
}
|
||||
encode(os.Stdout, res)
|
||||
return nil
|
||||
}
|
26
cmd/yamltool/parse.go
Normal file
26
cmd/yamltool/parse.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/goccy/go-yaml"
|
||||
"os"
|
||||
)
|
||||
|
||||
func read(file string) []byte {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func parse(data []byte) yaml.MapSlice {
|
||||
var result yaml.MapSlice
|
||||
decoder := yaml.NewDecoder(bytes.NewReader(data),
|
||||
yaml.UseOrderedMap())
|
||||
err := decoder.Decode(&result)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
70
cmd/yamltool/yamltool.go
Normal file
70
cmd/yamltool/yamltool.go
Normal file
@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var VERBOSITY = 3
|
||||
var SYMMETRIC_DIFF = false
|
||||
|
||||
type TypeId int
|
||||
|
||||
const (
|
||||
Map TypeId = iota
|
||||
Slice
|
||||
Scalar
|
||||
)
|
||||
|
||||
func Type(elem any) TypeId {
|
||||
switch elem.(type) {
|
||||
case yaml.MapSlice:
|
||||
return Map
|
||||
case []any:
|
||||
return Slice
|
||||
default:
|
||||
return Scalar
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "yamltool",
|
||||
Short: "Shows one-way difference between yaml files",
|
||||
Long: `
|
||||
Shows the changes in <file2> compared to <file1>`,
|
||||
}
|
||||
|
||||
diff := &cobra.Command{
|
||||
Use: "diff [file1] [file2]",
|
||||
Short: "Shows one-way difference between yaml files",
|
||||
Long: `
|
||||
Shows the additions and modifications in <file2> compared to <file1>`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return diff(cmd, args)
|
||||
},
|
||||
}
|
||||
cmd.AddCommand(diff)
|
||||
|
||||
merge := &cobra.Command{
|
||||
Use: "merge [file1] ... [fileN]",
|
||||
Short: "Merge yaml files.",
|
||||
Long: `Changes will be merged into the first file, so later files override earlier ones`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return merge(cmd, args)
|
||||
},
|
||||
}
|
||||
cmd.AddCommand(merge)
|
||||
|
||||
cmd.PersistentFlags().IntVarP(&VERBOSITY, "array-output-level",
|
||||
"v", 3, `Array output level: ,
|
||||
0: no output, only exit status,
|
||||
1: only show changed/added values,
|
||||
2: show identical as <UNMODIFIED>,
|
||||
3: show all values`)
|
||||
diff.Flags().BoolVarP(&SYMMETRIC_DIFF, "symmetric-diff",
|
||||
"s", false, `Symmetric difference, compare in both directions`)
|
||||
|
||||
cmd.Execute()
|
||||
}
|
Loading…
Reference in New Issue
Block a user