diff --git a/go.mod b/go.mod index 7a373b94..6c8175b2 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/onsi/ginkgo/v2 v2.23.4 github.com/onsi/gomega v1.37.0 github.com/spf13/cobra v1.9.1 + github.com/spf13/viper v1.20.1 github.com/texttheater/golang-levenshtein v1.0.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -30,8 +31,10 @@ require ( github.com/BurntSushi/toml v1.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -39,12 +42,20 @@ require ( github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/stretchr/testify v1.10.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect + go.uber.org/multierr v1.9.0 // indirect golang.org/x/net v0.41.0 // indirect golang.org/x/sync v0.16.0 // indirect golang.org/x/sys v0.34.0 // indirect diff --git a/go.sum b/go.sum index c877ba84..3de951f1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -8,10 +9,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gonvenience/bunt v1.4.2 h1:nTgkFZsw38SIJKABhLj8aXj2rqion9Zo1so/EBkbFBY= github.com/gonvenience/bunt v1.4.2/go.mod h1:WjyEO2rSYR+OLZg67Ucl+gjdXPs8GpFl63SCA02XDyI= github.com/gonvenience/idem v0.0.2 h1:jWHknjPfSbiWgYKre9wB2FhMgVLd1RWXCXzVq+7VIWg= @@ -53,6 +60,8 @@ github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -65,22 +74,39 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= diff --git a/internal/cmd/between.go b/internal/cmd/between.go index 5c97e426..f328d8f7 100644 --- a/internal/cmd/between.go +++ b/internal/cmd/between.go @@ -22,9 +22,10 @@ package cmd import ( "fmt" - "github.com/gonvenience/ytbx" "github.com/spf13/cobra" + "github.com/spf13/viper" + "os" "github.com/homeport/dyff/pkg/dyff" ) @@ -39,6 +40,8 @@ type betweenCmdOptions struct { var betweenCmdSettings betweenCmdOptions +var configFile string + // betweenCmd represents the between command var betweenCmd = &cobra.Command{ Use: "between [flags] ", @@ -49,7 +52,21 @@ types are: YAML (http://yaml.org/) and JSON (http://json.org/). `, Args: cobra.ExactArgs(2), Aliases: []string{"bw"}, + PreRun: func(cmd *cobra.Command, args []string) { + if _, err := os.Stat(configFile); err == nil { + viper.SetConfigFile(configFile) + if err := viper.ReadInConfig(); err != nil { + fmt.Printf("Error reading config file: %v\n", err) + os.Exit(1) + } + } + }, RunE: func(cmd *cobra.Command, args []string) error { + // Decode config file + if err := viper.Unmarshal(&reportOptions); err != nil { + return fmt.Errorf("failed to decode config file: %w", err) + } + var fromLocation, toLocation string if betweenCmdSettings.swap { fromLocation = args[1] @@ -72,47 +89,47 @@ types are: YAML (http://yaml.org/) and JSON (http://json.org/). // Change root of 'from' input file if change root flag for 'from' is set if betweenCmdSettings.chrootFrom != "" { - if err = dyff.ChangeRoot(&from, betweenCmdSettings.chrootFrom, reportOptions.useGoPatchPaths, betweenCmdSettings.translateListToDocuments); err != nil { + if err = dyff.ChangeRoot(&from, betweenCmdSettings.chrootFrom, reportOptions.UseGoPatchPaths, betweenCmdSettings.translateListToDocuments); err != nil { return fmt.Errorf("failed to change root of %s to path %s: %w", from.Location, betweenCmdSettings.chrootFrom, err) } } // Change root of 'to' input file if change root flag for 'to' is set if betweenCmdSettings.chrootTo != "" { - if err = dyff.ChangeRoot(&to, betweenCmdSettings.chrootTo, reportOptions.useGoPatchPaths, betweenCmdSettings.translateListToDocuments); err != nil { + if err = dyff.ChangeRoot(&to, betweenCmdSettings.chrootTo, reportOptions.UseGoPatchPaths, betweenCmdSettings.translateListToDocuments); err != nil { return fmt.Errorf("failed to change root of %s to path %s: %w", to.Location, betweenCmdSettings.chrootTo, err) } } report, err := dyff.CompareInputFiles(from, to, - dyff.IgnoreOrderChanges(reportOptions.ignoreOrderChanges), - dyff.IgnoreWhitespaceChanges(reportOptions.ignoreWhitespaceChanges), - dyff.KubernetesEntityDetection(reportOptions.kubernetesEntityDetection), - dyff.AdditionalIdentifiers(reportOptions.additionalIdentifiers...), - dyff.DetectRenames(reportOptions.detectRenames), + dyff.IgnoreOrderChanges(reportOptions.IgnoreOrderChanges), + dyff.IgnoreWhitespaceChanges(reportOptions.IgnoreWhitespaceChanges), + dyff.KubernetesEntityDetection(reportOptions.KubernetesEntityDetection), + dyff.AdditionalIdentifiers(reportOptions.AdditionalIdentifiers...), + dyff.DetectRenames(reportOptions.DetectRenames), ) if err != nil { return fmt.Errorf("failed to compare input files: %w", err) } - if reportOptions.filters != nil { - report = report.Filter(reportOptions.filters...) + if reportOptions.Filters != nil { + report = report.Filter(reportOptions.Filters...) } - if reportOptions.filterRegexps != nil { - report = report.FilterRegexp(reportOptions.filterRegexps...) + if reportOptions.FilterRegexps != nil { + report = report.FilterRegexp(reportOptions.FilterRegexps...) } - if reportOptions.excludes != nil { - report = report.Exclude(reportOptions.excludes...) + if reportOptions.Excludes != nil { + report = report.Exclude(reportOptions.Excludes...) } - if reportOptions.excludeRegexps != nil { - report = report.ExcludeRegexp(reportOptions.excludeRegexps...) + if reportOptions.ExcludeRegexps != nil { + report = report.ExcludeRegexp(reportOptions.ExcludeRegexps...) } - if reportOptions.ignoreValueChanges { + if reportOptions.IgnoreValueChanges { report = report.IgnoreValueChanges() } @@ -133,4 +150,5 @@ func init() { betweenCmd.Flags().StringVar(&betweenCmdSettings.chrootFrom, "chroot-of-from", "", "only change the root level of the from input file") betweenCmd.Flags().StringVar(&betweenCmdSettings.chrootTo, "chroot-of-to", "", "only change the root level of the to input file") betweenCmd.Flags().BoolVar(&betweenCmdSettings.translateListToDocuments, "chroot-list-to-documents", false, "in case the change root points to a list, treat this list as a set of documents and not as the list itself") + betweenCmd.PersistentFlags().StringVar(&configFile, "config", ".dyffconfig.yml", "set dyff options from a yaml config file.") } diff --git a/internal/cmd/common.go b/internal/cmd/common.go index 85b5f899..2db9b857 100644 --- a/internal/cmd/common.go +++ b/internal/cmd/common.go @@ -24,6 +24,7 @@ import ( "bufio" "bytes" "fmt" + "github.com/spf13/viper" "io" "os" "strings" @@ -38,76 +39,94 @@ import ( ) type reportConfig struct { - style string - ignoreOrderChanges bool - ignoreWhitespaceChanges bool - kubernetesEntityDetection bool - noTableStyle bool - doNotInspectCerts bool - exitWithCode bool - omitHeader bool - useGoPatchPaths bool - ignoreValueChanges bool - detectRenames bool - minorChangeThreshold float64 - multilineContextLines int - additionalIdentifiers []string - filters []string - excludes []string - filterRegexps []string - excludeRegexps []string + Style string `mapstructure:"style"` + IgnoreOrderChanges bool `mapstructure:"ignore-order-changes"` + IgnoreWhitespaceChanges bool `mapstructure:"ignore-whitespace-changes"` + KubernetesEntityDetection bool `mapstructure:"kubernetes-entity-detection"` + NoTableStyle bool `mapstructure:"no-table-style"` + DoNotInspectCerts bool `mapstructure:"do-not-inspect-certs"` + ExitWithCode bool `mapstructure:"exit-with-code"` + OmitHeader bool `mapstructure:"omit-header"` + UseGoPatchPaths bool `mapstructure:"use-go-patch-paths"` + IgnoreValueChanges bool `mapstructure:"ignore-value-changes"` + DetectRenames bool `mapstructure:"detect-renames"` + MinorChangeThreshold float64 `mapstructure:"minor-change-threshold"` + MultilineContextLines int `mapstructure:"multiline-context-lines"` + AdditionalIdentifiers []string `mapstructure:"additional-identifier"` + Filters []string `mapstructure:"filter"` + Excludes []string `mapstructure:"exclude"` + FilterRegexps []string `mapstructure:"filter-regexp"` + ExcludeRegexps []string `mapstructure:"exclude-regexp"` } var defaults = reportConfig{ - style: "human", - ignoreOrderChanges: false, - ignoreWhitespaceChanges: false, - kubernetesEntityDetection: true, - noTableStyle: false, - doNotInspectCerts: false, - exitWithCode: false, - omitHeader: false, - useGoPatchPaths: false, - ignoreValueChanges: false, - detectRenames: true, - minorChangeThreshold: 0.1, - multilineContextLines: 4, - additionalIdentifiers: nil, - filters: nil, - excludes: nil, - filterRegexps: nil, - excludeRegexps: nil, + Style: "human", + IgnoreOrderChanges: false, + IgnoreWhitespaceChanges: false, + KubernetesEntityDetection: true, + NoTableStyle: false, + DoNotInspectCerts: false, + ExitWithCode: false, + OmitHeader: false, + UseGoPatchPaths: false, + IgnoreValueChanges: false, + DetectRenames: true, + MinorChangeThreshold: 0.1, + MultilineContextLines: 4, + AdditionalIdentifiers: nil, + Filters: nil, + Excludes: nil, + FilterRegexps: nil, + ExcludeRegexps: nil, } var reportOptions reportConfig func applyReportOptionsFlags(cmd *cobra.Command) { // Compare options - cmd.Flags().BoolVarP(&reportOptions.ignoreOrderChanges, "ignore-order-changes", "i", defaults.ignoreOrderChanges, "ignore order changes in lists") - cmd.Flags().BoolVar(&reportOptions.ignoreWhitespaceChanges, "ignore-whitespace-changes", defaults.ignoreWhitespaceChanges, "ignore leading or trailing whitespace changes") - cmd.Flags().BoolVarP(&reportOptions.kubernetesEntityDetection, "detect-kubernetes", "", defaults.kubernetesEntityDetection, "detect kubernetes entities") - cmd.Flags().StringArrayVar(&reportOptions.additionalIdentifiers, "additional-identifier", defaults.additionalIdentifiers, "use additional identifier candidates in named entry lists") - cmd.Flags().StringSliceVar(&reportOptions.filters, "filter", defaults.filters, "filter reports to a subset of differences based on supplied arguments") - cmd.Flags().StringSliceVar(&reportOptions.excludes, "exclude", defaults.excludes, "exclude reports from a set of differences based on supplied arguments") - cmd.Flags().StringSliceVar(&reportOptions.filterRegexps, "filter-regexp", defaults.filterRegexps, "filter reports to a subset of differences based on supplied regular expressions") - cmd.Flags().StringSliceVar(&reportOptions.excludeRegexps, "exclude-regexp", defaults.excludeRegexps, "exclude reports from a set of differences based on supplied regular expressions") - cmd.Flags().BoolVarP(&reportOptions.ignoreValueChanges, "ignore-value-changes", "v", defaults.ignoreValueChanges, "exclude changes in values") - cmd.Flags().BoolVar(&reportOptions.detectRenames, "detect-renames", defaults.detectRenames, "enable detection for renames (document level for Kubernetes resources)") + cmd.Flags().BoolVarP(&reportOptions.IgnoreOrderChanges, "ignore-order-changes", "i", defaults.IgnoreOrderChanges, "ignore order changes in lists") + viper.BindPFlag("ignore-order-changes", cmd.Flags().Lookup("ignore-order-changes")) + cmd.Flags().BoolVar(&reportOptions.IgnoreWhitespaceChanges, "ignore-whitespace-changes", defaults.IgnoreWhitespaceChanges, "ignore leading or trailing whitespace changes") + viper.BindPFlag("ignore-whitespace-changes", cmd.Flags().Lookup("ignore-whitespace-changes")) + cmd.Flags().BoolVarP(&reportOptions.KubernetesEntityDetection, "detect-kubernetes", "", defaults.KubernetesEntityDetection, "detect kubernetes entities") + viper.BindPFlag("detect-kubernetes", cmd.Flags().Lookup("detect-kubernetes")) + cmd.Flags().StringArrayVar(&reportOptions.AdditionalIdentifiers, "additional-identifier", defaults.AdditionalIdentifiers, "use additional identifier candidates in named entry lists") + viper.BindPFlag("additional-identifier", cmd.Flags().Lookup("additional-identifier")) + cmd.Flags().StringSliceVar(&reportOptions.Filters, "filter", defaults.Filters, "filter reports to a subset of differences based on supplied arguments") + viper.BindPFlag("filter", cmd.Flags().Lookup("filter")) + cmd.Flags().StringSliceVar(&reportOptions.Excludes, "exclude", defaults.Excludes, "exclude reports from a set of differences based on supplied arguments") + viper.BindPFlag("exclude", cmd.Flags().Lookup("exclude")) + cmd.Flags().StringSliceVar(&reportOptions.FilterRegexps, "filter-regexp", defaults.FilterRegexps, "filter reports to a subset of differences based on supplied regular expressions") + viper.BindPFlag("filter-regexp", cmd.Flags().Lookup("filter-regexp")) + cmd.Flags().StringSliceVar(&reportOptions.ExcludeRegexps, "exclude-regexp", defaults.ExcludeRegexps, "exclude reports from a set of differences based on supplied regular expressions") + viper.BindPFlag("exclude-regexp", cmd.Flags().Lookup("exclude-regexp")) + cmd.Flags().BoolVarP(&reportOptions.IgnoreValueChanges, "ignore-value-changes", "v", defaults.IgnoreValueChanges, "exclude changes in values") + viper.BindPFlag("ignore-value-changes", cmd.Flags().Lookup("ignore-value-changes")) + cmd.Flags().BoolVar(&reportOptions.DetectRenames, "detect-renames", defaults.DetectRenames, "enable detection for renames (document level for Kubernetes resources)") + viper.BindPFlag("detect-renames", cmd.Flags().Lookup("detect-renames")) // Main output preferences - cmd.Flags().StringVarP(&reportOptions.style, "output", "o", defaults.style, "specify the output style, supported styles: human, brief, github, gitlab, gitea") - cmd.Flags().BoolVarP(&reportOptions.omitHeader, "omit-header", "b", defaults.omitHeader, "omit the dyff summary header") - cmd.Flags().BoolVarP(&reportOptions.exitWithCode, "set-exit-code", "s", defaults.exitWithCode, "set program exit code, with 0 meaning no difference, 1 for differences detected, and 255 for program error") + cmd.Flags().StringVarP(&reportOptions.Style, "output", "o", defaults.Style, "specify the output style, supported styles: human, brief, github, gitlab, gitea, yaml") + viper.BindPFlag("output", cmd.Flags().Lookup("output")) + cmd.Flags().BoolVarP(&reportOptions.OmitHeader, "omit-header", "b", defaults.OmitHeader, "omit the dyff summary header") + viper.BindPFlag("omit-header", cmd.Flags().Lookup("omit-header")) + cmd.Flags().BoolVarP(&reportOptions.ExitWithCode, "set-exit-code", "s", defaults.ExitWithCode, "set program exit code, with 0 meaning no difference, 1 for differences detected, and 255 for program error") + viper.BindPFlag("set-exit-code", cmd.Flags().Lookup("set-exit-code")) // Human/BOSH output related flags - cmd.Flags().BoolVarP(&reportOptions.noTableStyle, "no-table-style", "l", defaults.noTableStyle, "do not place blocks next to each other, always use one row per text block") - cmd.Flags().BoolVarP(&reportOptions.doNotInspectCerts, "no-cert-inspection", "x", defaults.doNotInspectCerts, "disable x509 certificate inspection, compare as raw text") - cmd.Flags().BoolVarP(&reportOptions.useGoPatchPaths, "use-go-patch-style", "g", defaults.useGoPatchPaths, "use Go-Patch style paths in outputs") - cmd.Flags().Float64VarP(&reportOptions.minorChangeThreshold, "minor-change-threshold", "", defaults.minorChangeThreshold, "minor change threshold") - cmd.Flags().IntVarP(&reportOptions.multilineContextLines, "multi-line-context-lines", "", defaults.multilineContextLines, "multi-line context lines") + cmd.Flags().BoolVarP(&reportOptions.NoTableStyle, "no-table-style", "l", defaults.NoTableStyle, "do not place blocks next to each other, always use one row per text block") + viper.BindPFlag("no-table-style", cmd.Flags().Lookup("no-table-style")) + cmd.Flags().BoolVarP(&reportOptions.DoNotInspectCerts, "no-cert-inspection", "x", defaults.DoNotInspectCerts, "disable x509 certificate inspection, compare as raw text") + viper.BindPFlag("no-cert-inspection", cmd.Flags().Lookup("no-cert-inspection")) + cmd.Flags().BoolVarP(&reportOptions.UseGoPatchPaths, "use-go-patch-style", "g", defaults.UseGoPatchPaths, "use Go-Patch style paths in outputs") + viper.BindPFlag("use-go-patch-style", cmd.Flags().Lookup("use-go-patch-style")) + cmd.Flags().Float64VarP(&reportOptions.MinorChangeThreshold, "minor-change-threshold", "", defaults.MinorChangeThreshold, "minor change threshold") + viper.BindPFlag("minor-change-threshold", cmd.Flags().Lookup("minor-change-threshold")) + cmd.Flags().IntVarP(&reportOptions.MultilineContextLines, "multi-line-context-lines", "", defaults.MultilineContextLines, "multi-line context lines") + viper.BindPFlag("multiline-context-lines", cmd.Flags().Lookup("multi-line-context-lines")) // Deprecated - cmd.Flags().BoolVar(&reportOptions.exitWithCode, "set-exit-status", defaults.exitWithCode, "set program exit code, with 0 meaning no difference, 1 for differences detected, and 255 for program error") + cmd.Flags().BoolVar(&reportOptions.ExitWithCode, "set-exit-status", defaults.ExitWithCode, "set program exit code, with 0 meaning no difference, 1 for differences detected, and 255 for program error") _ = cmd.Flags().MarkDeprecated("set-exit-status", "use --set-exit-code instead") } @@ -212,17 +231,17 @@ func (w *OutputWriter) write(writer io.Writer, filename string) error { func writeReport(cmd *cobra.Command, report dyff.Report) error { var reportWriter dyff.ReportWriter - switch strings.ToLower(reportOptions.style) { + switch strings.ToLower(reportOptions.Style) { case "human", "bosh": reportWriter = &dyff.HumanReport{ Report: report, Indent: 2, - DoNotInspectCerts: reportOptions.doNotInspectCerts, - NoTableStyle: reportOptions.noTableStyle, - OmitHeader: reportOptions.omitHeader, - UseGoPatchPaths: reportOptions.useGoPatchPaths, - MinorChangeThreshold: reportOptions.minorChangeThreshold, - MultilineContextLines: reportOptions.multilineContextLines, + DoNotInspectCerts: reportOptions.DoNotInspectCerts, + NoTableStyle: reportOptions.NoTableStyle, + OmitHeader: reportOptions.OmitHeader, + UseGoPatchPaths: reportOptions.UseGoPatchPaths, + MinorChangeThreshold: reportOptions.MinorChangeThreshold, + MultilineContextLines: reportOptions.MultilineContextLines, PrefixMultiline: false, } @@ -234,12 +253,12 @@ func writeReport(cmd *cobra.Command, report dyff.Report) error { HumanReport: dyff.HumanReport{ Report: report, Indent: 0, - DoNotInspectCerts: reportOptions.doNotInspectCerts, + DoNotInspectCerts: reportOptions.DoNotInspectCerts, NoTableStyle: true, OmitHeader: true, - UseGoPatchPaths: reportOptions.useGoPatchPaths, - MinorChangeThreshold: reportOptions.minorChangeThreshold, - MultilineContextLines: reportOptions.multilineContextLines, + UseGoPatchPaths: reportOptions.UseGoPatchPaths, + MinorChangeThreshold: reportOptions.MinorChangeThreshold, + MultilineContextLines: reportOptions.MultilineContextLines, PrefixMultiline: true, }, } @@ -252,12 +271,12 @@ func writeReport(cmd *cobra.Command, report dyff.Report) error { HumanReport: dyff.HumanReport{ Report: report, Indent: 0, - DoNotInspectCerts: reportOptions.doNotInspectCerts, + DoNotInspectCerts: reportOptions.DoNotInspectCerts, NoTableStyle: true, OmitHeader: true, - UseGoPatchPaths: reportOptions.useGoPatchPaths, - MinorChangeThreshold: reportOptions.minorChangeThreshold, - MultilineContextLines: reportOptions.multilineContextLines, + UseGoPatchPaths: reportOptions.UseGoPatchPaths, + MinorChangeThreshold: reportOptions.MinorChangeThreshold, + MultilineContextLines: reportOptions.MultilineContextLines, PrefixMultiline: true, }, } @@ -270,12 +289,12 @@ func writeReport(cmd *cobra.Command, report dyff.Report) error { HumanReport: dyff.HumanReport{ Report: report, Indent: 0, - DoNotInspectCerts: reportOptions.doNotInspectCerts, + DoNotInspectCerts: reportOptions.DoNotInspectCerts, NoTableStyle: true, OmitHeader: true, - UseGoPatchPaths: reportOptions.useGoPatchPaths, - MinorChangeThreshold: reportOptions.minorChangeThreshold, - MultilineContextLines: reportOptions.multilineContextLines, + UseGoPatchPaths: reportOptions.UseGoPatchPaths, + MinorChangeThreshold: reportOptions.MinorChangeThreshold, + MultilineContextLines: reportOptions.MultilineContextLines, PrefixMultiline: true, }, } @@ -286,7 +305,7 @@ func writeReport(cmd *cobra.Command, report dyff.Report) error { } default: - return fmt.Errorf("unknown output style %s: %w", reportOptions.style, fmt.Errorf(cmd.UsageString())) + return fmt.Errorf("unknown output style %s: %w", reportOptions.Style, fmt.Errorf(cmd.UsageString())) } if err := reportWriter.WriteReport(os.Stdout); err != nil { @@ -294,7 +313,7 @@ func writeReport(cmd *cobra.Command, report dyff.Report) error { } // If configured, make sure `dyff` exists with an exit status - if reportOptions.exitWithCode { + if reportOptions.ExitWithCode { switch len(report.Diffs) { case 0: return errorWithExitCode{value: 0} diff --git a/internal/cmd/lastApplied.go b/internal/cmd/lastApplied.go index e5a98602..7386fced 100644 --- a/internal/cmd/lastApplied.go +++ b/internal/cmd/lastApplied.go @@ -58,7 +58,7 @@ to compare it against the current configuration. purgeWellKnownMetadataEntries(inputFile.Documents[0]) - report, err := dyff.CompareInputFiles(lastConfiguration, inputFile, dyff.IgnoreOrderChanges(reportOptions.ignoreOrderChanges)) + report, err := dyff.CompareInputFiles(lastConfiguration, inputFile, dyff.IgnoreOrderChanges(reportOptions.IgnoreOrderChanges)) if err != nil { return fmt.Errorf("failed to compare input files: %w", err) } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 7a9abdb4..8e62b83e 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -94,13 +94,13 @@ func Execute() error { os.Args = rearrange() // Enable Kubernetes specific entity detection implicitly - reportOptions.kubernetesEntityDetection = true + reportOptions.KubernetesEntityDetection = true // Add implicit exclude for metadata.managedFields as this cannot // be configured via a command-line flag using KUBECTL_EXTERNAL_DIFF // due to an bug/feature in kubectl that ignore command-line flags // in the diff environment variable with non alpha-numeric characters - reportOptions.excludeRegexps = append(reportOptions.excludeRegexps, "^/metadata/managedFields") + reportOptions.ExcludeRegexps = append(reportOptions.ExcludeRegexps, "^/metadata/managedFields") } if err := rootCmd.Execute(); err != nil {