From b47978874a799f8e0597b4a85b96a1ad97b22009 Mon Sep 17 00:00:00 2001 From: Cedric Meury Date: Tue, 26 Jun 2018 14:04:23 +0200 Subject: [PATCH] return non-zero exitcode when encountering any change on upgrade --- README.md | 1 + cmd/upgrade.go | 29 ++++++++++++++++++----------- diff/diff.go | 32 ++++++++++++++++++++++++++------ main.go | 2 ++ 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 1e35cad3..5b5fe747 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Examples: Flags: -h, --help help for upgrade + --detailed-exitcode return a non-zero exit code when there are changes --reset-values reset the values to the ones built into the chart and merge in any new values --reuse-values reuse the last release's values and merge in any new values --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 4577be84..858ca1e6 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -9,19 +9,21 @@ import ( "github.com/databus23/helm-diff/manifest" "github.com/spf13/cobra" "k8s.io/helm/pkg/helm" + "errors" ) type diffCmd struct { - release string - chart string - chartVersion string - client helm.Interface - valueFiles valueFiles - values []string - reuseValues bool - resetValues bool - allowUnreleased bool - suppressedKinds []string + release string + chart string + chartVersion string + client helm.Interface + valueFiles valueFiles + values []string + reuseValues bool + resetValues bool + allowUnreleased bool + detailedExitCode bool + suppressedKinds []string } const globalUsage = `Show a diff explaining what a helm upgrade would change. @@ -67,6 +69,7 @@ func newChartCommand() *cobra.Command { f.BoolVar(&diff.resetValues, "reset-values", false, "reset the values to the ones built into the chart and merge in any new values") f.BoolVar(&diff.allowUnreleased, "allow-unreleased", false, "enables diffing of releases that are not yet deployed via Helm") f.StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output") + f.BoolVar(&diff.detailedExitCode, "detailed-exitcode", false, "return a non-zero exit code when there are changes") return cmd @@ -137,7 +140,11 @@ func (d *diffCmd) run() error { newSpecs = manifest.Parse(upgradeResponse.Release.Manifest) } - diff.DiffManifests(currentSpecs, newSpecs, d.suppressedKinds, os.Stdout) + seenAnyChanges := diff.DiffManifests(currentSpecs, newSpecs, d.suppressedKinds, os.Stdout) + + if d.detailedExitCode && seenAnyChanges { + return errors.New("identified at least one change, exiting with non-zero exit code (detailed-exitcode parameter enabled)") + } return nil } diff --git a/diff/diff.go b/diff/diff.go index 2872a446..a92a99b0 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -11,18 +11,29 @@ import ( "github.com/databus23/helm-diff/manifest" ) -func DiffManifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedKinds []string, to io.Writer) { + +func DiffManifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedKinds []string, to io.Writer) bool { + seenAnyChanges := false + emptyMapping := &manifest.MappingResult{} for key, oldContent := range oldIndex { if newContent, ok := newIndex[key]; ok { if oldContent.Content != newContent.Content { // modified fmt.Fprintf(to, ansi.Color("%s has changed:", "yellow")+"\n", key) - printDiff(suppressedKinds, oldContent.Kind, oldContent.Content, newContent.Content, to) + diffs := generateDiff(oldContent, newContent) + if len(diffs) > 0 { + seenAnyChanges = true + } + printDiff(suppressedKinds, oldContent.Kind, diffs, to) } } else { // removed fmt.Fprintf(to, ansi.Color("%s has been removed:", "yellow")+"\n", key) - printDiff(suppressedKinds, oldContent.Kind, oldContent.Content, "", to) + diffs := generateDiff(oldContent, emptyMapping) + if len(diffs) > 0 { + seenAnyChanges = true + } + printDiff(suppressedKinds, oldContent.Kind, diffs, to) } } @@ -30,13 +41,22 @@ func DiffManifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppre if _, ok := oldIndex[key]; !ok { // added fmt.Fprintf(to, ansi.Color("%s has been added:", "yellow")+"\n", key) - printDiff(suppressedKinds, newContent.Kind, "", newContent.Content, to) + diffs := generateDiff(emptyMapping, newContent) + if len(diffs) > 0 { + seenAnyChanges = true + } + printDiff(suppressedKinds, newContent.Kind, diffs, to) } } + return seenAnyChanges +} + +func generateDiff(oldContent *manifest.MappingResult, newContent *manifest.MappingResult) []difflib.DiffRecord { + const sep = "\n" + return difflib.Diff(strings.Split(oldContent.Content, sep), strings.Split(newContent.Content, sep)) } -func printDiff(suppressedKinds []string, kind, before, after string, to io.Writer) { - diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n")) +func printDiff(suppressedKinds []string, kind string, diffs []difflib.DiffRecord, to io.Writer) { for _, ckind := range suppressedKinds { if ckind == kind { diff --git a/main.go b/main.go index 42e4da20..1f56f4cc 100644 --- a/main.go +++ b/main.go @@ -2,12 +2,14 @@ package main import ( "os" + "fmt" "github.com/databus23/helm-diff/cmd" ) func main() { if err := cmd.New().Execute(); err != nil { + fmt.Println(err) os.Exit(1) } }