diff --git a/cmd/gmailctl/cmd/apply_cmd.go b/cmd/gmailctl/cmd/apply_cmd.go index fdd8d8c6..1fb74b64 100644 --- a/cmd/gmailctl/cmd/apply_cmd.go +++ b/cmd/gmailctl/cmd/apply_cmd.go @@ -16,6 +16,7 @@ var ( applySkipTests bool applyDebug bool applyDiffContext int + applyColor string ) const renameLabelWarning = `Warning: You are going to delete labels. This operation is @@ -51,15 +52,19 @@ func init() { applyCmd.PersistentFlags().StringVarP(&applyFilename, "filename", "f", "", "configuration file") applyCmd.Flags().BoolVarP(&applyYes, "yes", "y", false, "don't ask for confirmation, just apply") applyCmd.Flags().BoolVarP(&applyRemoveLabels, "remove-labels", "r", false, "allow removing labels") - applyCmd.Flags().BoolVarP(&applySkipTests, "yolo", "", false, "skip configuration tests") - applyCmd.PersistentFlags().BoolVarP(&applyDebug, "debug", "", false, "print extra debugging information") - applyCmd.PersistentFlags().IntVarP(&applyDiffContext, "diff-context", "", papply.DefaultContextLines, "number of lines of filter diff context to show") + applyCmd.Flags().BoolVar(&applySkipTests, "yolo", false, "skip configuration tests") + applyCmd.PersistentFlags().BoolVar(&applyDebug, "debug", false, "print extra debugging information") + applyCmd.PersistentFlags().IntVar(&applyDiffContext, "diff-context", papply.DefaultContextLines, "number of lines of filter diff context to show") + applyCmd.PersistentFlags().StringVar(&applyColor, "color", "auto", "whether to enable color output (must be \"auto\" or \"never\")") } func apply(path string, interactive, test bool) error { if applyDiffContext < 0 { return errors.New("--diff-context must be non-negative") } + if applyColor != "auto" && applyColor != "never" { + return errors.New("--color must be \"auto\" or \"never\"") + } parseRes, err := parseConfig(path, "", test) if err != nil { @@ -76,7 +81,7 @@ func apply(path string, interactive, test bool) error { return err } - diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, applyDebug, applyDiffContext) + diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, applyDebug, applyDiffContext, applyColor == "auto") if err != nil { return fmt.Errorf("cannot compare upstream with local config: %w", err) } diff --git a/cmd/gmailctl/cmd/diff_cmd.go b/cmd/gmailctl/cmd/diff_cmd.go index 12b918d1..8575b7b1 100644 --- a/cmd/gmailctl/cmd/diff_cmd.go +++ b/cmd/gmailctl/cmd/diff_cmd.go @@ -13,6 +13,7 @@ var ( diffFilename string diffDebug bool diffContext int + diffColor string ) // diffCmd represents the diff command @@ -40,14 +41,18 @@ func init() { // Flags and configuration settings diffCmd.PersistentFlags().StringVarP(&diffFilename, "filename", "f", "", "configuration file") - diffCmd.PersistentFlags().BoolVarP(&diffDebug, "debug", "", false, "print extra debugging information") - diffCmd.PersistentFlags().IntVarP(&diffContext, "context", "", papply.DefaultContextLines, "number of lines of filter diff context to show") + diffCmd.PersistentFlags().BoolVar(&diffDebug, "debug", false, "print extra debugging information") + diffCmd.PersistentFlags().IntVar(&diffContext, "context", papply.DefaultContextLines, "number of lines of filter diff context to show") + diffCmd.PersistentFlags().StringVar(&diffColor, "color", "auto", "whether to enable color output (must be \"auto\" or \"never\")") } func diff(path string) error { if diffContext < 0 { return errors.New("--context must be non-negative") } + if diffColor != "auto" && diffColor != "never" { + return errors.New("--color must be \"auto\" or \"never\"") + } parseRes, err := parseConfig(path, "", false) if err != nil { @@ -64,7 +69,7 @@ func diff(path string) error { return err } - diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, diffDebug, diffContext) + diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, diffDebug, diffContext, diffColor == "auto") if err != nil { return fmt.Errorf("cannot compare upstream with local config: %w", err) } diff --git a/cmd/gmailctl/cmd/edit_cmd.go b/cmd/gmailctl/cmd/edit_cmd.go index 7d307b1c..fa11b21a 100644 --- a/cmd/gmailctl/cmd/edit_cmd.go +++ b/cmd/gmailctl/cmd/edit_cmd.go @@ -21,6 +21,7 @@ var ( editSkipTests bool editDebug bool editDiffContext int + editColor string ) var ( @@ -70,14 +71,18 @@ func init() { // Flags and configuration settings editCmd.PersistentFlags().StringVarP(&editFilename, "filename", "f", "", "configuration file") editCmd.Flags().BoolVarP(&editSkipTests, "yolo", "", false, "skip configuration tests") - editCmd.PersistentFlags().BoolVarP(&editDebug, "debug", "", false, "print extra debugging information") - editCmd.PersistentFlags().IntVarP(&editDiffContext, "diff-context", "", papply.DefaultContextLines, "number of lines of filter diff context to show") + editCmd.PersistentFlags().BoolVar(&editDebug, "debug", false, "print extra debugging information") + editCmd.PersistentFlags().IntVar(&editDiffContext, "diff-context", papply.DefaultContextLines, "number of lines of filter diff context to show") + editCmd.PersistentFlags().StringVar(&editColor, "color", "auto", "whether to enable color output (must be \"auto\" or \"never\")") } func edit(path string, test bool) error { if editDiffContext < 0 { return errors.New("--diff-context must be non-negative") } + if editColor != "auto" && editColor != "never" { + return errors.New("--color must be \"auto\" or \"never\"") + } // First make sure that Gmail can be contacted, so that we don't // waste the user's time editing a config file that cannot be @@ -229,7 +234,7 @@ func applyEdited(path, originalPath string, test bool, gmailapi *api.GmailAPI) e return err } - diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, editDebug, editDiffContext) + diff, err := papply.Diff(parseRes.Res.GmailConfig, upstream, editDebug, editDiffContext, editColor == "auto") if err != nil { return errors.New("comparing upstream with local config") } diff --git a/go.mod b/go.mod index 05337013..d5a386bd 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/go-jsonnet v0.20.0 github.com/gorilla/mux v1.8.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/pmezard/go-difflib v1.0.0 + github.com/martinohmann/go-difflib v1.1.0 github.com/spf13/cobra v1.9.1 github.com/stretchr/testify v1.10.0 golang.org/x/oauth2 v0.30.0 @@ -21,6 +21,7 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.12.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -30,6 +31,9 @@ require ( github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.6 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect diff --git a/go.sum b/go.sum index 239c3723..9e2d3818 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,9 @@ cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1F github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -21,6 +24,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= +github.com/google/pprof v0.0.0-20190404155422-f8f10df84213/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -42,6 +46,15 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/martinohmann/go-difflib v1.1.0 h1:cWipyTDwXGZeN/J0D1PbkupyMvOnqTrKRSMZ68y8Rbc= +github.com/martinohmann/go-difflib v1.1.0/go.mod h1:AcMcOkYMsAiB5qTRFy5lmqgbGkN4IOEGuuo3zNXQp/A= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= @@ -69,18 +82,27 @@ go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5J go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/tools v0.0.0-20190422165002-7f54bd5c703d/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/api v0.232.0 h1:qGnmaIMf7KcuwHOlF3mERVzChloDYwRfOJOrHt8YC3I= google.golang.org/api v0.232.0/go.mod h1:p9QCfBWZk1IJETUdbTKloR5ToFdKbYh2fkjsUL6vNoY= google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= @@ -96,5 +118,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/engine/apply/apply.go b/internal/engine/apply/apply.go index bf87ce8a..97282947 100644 --- a/internal/engine/apply/apply.go +++ b/internal/engine/apply/apply.go @@ -116,20 +116,20 @@ func (d ConfigDiff) Validate() error { } // Diff computes the diff between local and upstream configuration. -func Diff(local, upstream GmailConfig, debugInfo bool, contextLines int) (ConfigDiff, error) { +func Diff(local, upstream GmailConfig, debugInfo bool, contextLines int, allowColor bool) (ConfigDiff, error) { res := ConfigDiff{ LocalConfig: local, } var err error - res.FiltersDiff, err = filter.Diff(upstream.Filters, local.Filters, debugInfo, contextLines) + res.FiltersDiff, err = filter.Diff(upstream.Filters, local.Filters, debugInfo, contextLines, allowColor) if err != nil { return res, fmt.Errorf("cannot compute filters diff: %w", err) } if len(local.Labels) > 0 { // LabelsDiff management opted-in - res.LabelsDiff, err = label.Diff(upstream.Labels, local.Labels) + res.LabelsDiff, err = label.Diff(upstream.Labels, local.Labels, allowColor) if err != nil { return res, fmt.Errorf("cannot compute labels diff: %w", err) } diff --git a/internal/engine/cfgtest/cfgtest.go b/internal/engine/cfgtest/cfgtest.go index e2744ddb..f9c14552 100644 --- a/internal/engine/cfgtest/cfgtest.go +++ b/internal/engine/cfgtest/cfgtest.go @@ -7,7 +7,7 @@ import ( "sort" "strings" - "github.com/pmezard/go-difflib/difflib" + "github.com/martinohmann/go-difflib/difflib" "github.com/mbrt/gmailctl/internal/engine/config/v1alpha3" "github.com/mbrt/gmailctl/internal/engine/gmail" diff --git a/internal/engine/filter/diff.go b/internal/engine/filter/diff.go index 2b102457..d21eb11d 100644 --- a/internal/engine/filter/diff.go +++ b/internal/engine/filter/diff.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/pmezard/go-difflib/difflib" + "github.com/martinohmann/go-difflib/difflib" "github.com/mbrt/gmailctl/internal/graph" ) @@ -14,12 +14,12 @@ import ( // Diff computes the diff between two lists of filters. // // To compute the diff, IDs are ignored, only the contents of the filters are actually considered. -func Diff(upstream, local Filters, debugInfo bool, contextLines int) (FiltersDiff, error) { +func Diff(upstream, local Filters, debugInfo bool, contextLines int, allowColor bool) (FiltersDiff, error) { // Computing the diff is very expensive, so we have to minimize the number of filters // we have to analyze. To do so, we get rid of the filters that are exactly the same, // by hashing them. added, removed := changedFilters(upstream, local) - return NewMinimalFiltersDiff(added, removed, debugInfo, contextLines), nil + return NewMinimalFiltersDiff(added, removed, debugInfo, contextLines, allowColor), nil } // NewMinimalFiltersDiff creates a new FiltersDiff with reordered filters, where @@ -28,11 +28,11 @@ func Diff(upstream, local Filters, debugInfo bool, contextLines int) (FiltersDif // The algorithm used is a quadratic approximation to the otherwise NP-complete // travel salesman problem. Hopefully the number of filters is low enough to // make this not too slow and the approximation not too bad. -func NewMinimalFiltersDiff(added, removed Filters, printDebugInfo bool, contextLines int) FiltersDiff { +func NewMinimalFiltersDiff(added, removed Filters, printDebugInfo bool, contextLines int, allowColor bool) FiltersDiff { if len(added) > 0 && len(removed) > 0 { added, removed = reorderWithHungarian(added, removed) } - return FiltersDiff{added, removed, printDebugInfo, contextLines} + return FiltersDiff{added, removed, printDebugInfo, contextLines, allowColor} } // FiltersDiff contains filters that have been added and removed locally with respect to upstream. @@ -41,6 +41,7 @@ type FiltersDiff struct { Removed Filters PrintDebugInfo bool ContextLines int + AllowColor bool } // Empty returns true if the diff is empty. @@ -64,6 +65,7 @@ func (f FiltersDiff) String() string { FromFile: "Current", ToFile: "TO BE APPLIED", Context: f.ContextLines, + Color: f.AllowColor, }) if err != nil { // We can't get a diff apparently, let's make something up here diff --git a/internal/engine/label/diff.go b/internal/engine/label/diff.go index e6e39240..e85dc59e 100644 --- a/internal/engine/label/diff.go +++ b/internal/engine/label/diff.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/pmezard/go-difflib/difflib" + "github.com/martinohmann/go-difflib/difflib" "github.com/mbrt/gmailctl/internal/engine/filter" ) @@ -14,11 +14,11 @@ import ( // // To compute the diff, IDs are ignored, only the properties of the labels are // actually considered. -func Diff(upstream, local Labels) (LabelsDiff, error) { +func Diff(upstream, local Labels, allowColor bool) (LabelsDiff, error) { sort.Sort(byName(upstream)) sort.Sort(byName(local)) - res := LabelsDiff{} + res := LabelsDiff{AllowColor: allowColor} i, j := 0, 0 for i < len(upstream) && j < len(local) { @@ -63,9 +63,10 @@ func Diff(upstream, local Labels) (LabelsDiff, error) { // LabelsDiff contains the diff of two lists of labels. type LabelsDiff struct { - Modified []ModifiedLabel - Added Labels - Removed Labels + Modified []ModifiedLabel + Added Labels + Removed Labels + AllowColor bool } // Empty returns true if the diff is empty. @@ -103,6 +104,7 @@ func (d LabelsDiff) String() string { FromFile: "Current", ToFile: "TO BE APPLIED", Context: 3, + Color: d.AllowColor, }) if err != nil { // We can't get a diff apparently, let's make something up here