feat: add --skip-trailing-cr to helmfile diff (#625)
This commit is contained in:
		
							parent
							
								
									14a33f998f
								
							
						
					
					
						commit
						b6dd7122f9
					
				|  | @ -40,6 +40,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { | ||||||
| 	f.IntVar(&applyOptions.Context, "context", 0, "output NUM lines of context around changes") | 	f.IntVar(&applyOptions.Context, "context", 0, "output NUM lines of context around changes") | ||||||
| 	f.StringVar(&applyOptions.Output, "output", "", "output format for diff plugin") | 	f.StringVar(&applyOptions.Output, "output", "", "output format for diff plugin") | ||||||
| 	f.BoolVar(&applyOptions.DetailedExitcode, "detailed-exitcode", false, "return a non-zero exit code 2 instead of 0 when there were changes detected AND the changes are synced successfully") | 	f.BoolVar(&applyOptions.DetailedExitcode, "detailed-exitcode", false, "return a non-zero exit code 2 instead of 0 when there were changes detected AND the changes are synced successfully") | ||||||
|  | 	f.BoolVar(&applyOptions.StripTrailingCR, "strip-trailing-cr", false, "strip trailing carriage return on input") | ||||||
| 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") | 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") | ||||||
| 	if !runtime.V1Mode { | 	if !runtime.V1Mode { | ||||||
| 		// TODO: Remove this function once Helmfile v0.x
 | 		// TODO: Remove this function once Helmfile v0.x
 | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { | ||||||
| 	f.BoolVar(&diffOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the output. should be used for debug purpose only") | 	f.BoolVar(&diffOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the output. should be used for debug purpose only") | ||||||
| 	f.BoolVar(&diffOptions.NoHooks, "no-hooks", false, "do not diff changes made by hooks.") | 	f.BoolVar(&diffOptions.NoHooks, "no-hooks", false, "do not diff changes made by hooks.") | ||||||
| 	f.BoolVar(&diffOptions.DetailedExitcode, "detailed-exitcode", false, "return a detailed exit code") | 	f.BoolVar(&diffOptions.DetailedExitcode, "detailed-exitcode", false, "return a detailed exit code") | ||||||
|  | 	f.BoolVar(&diffOptions.StripTrailingCR, "strip-trailing-cr", false, "strip trailing carriage return on input") | ||||||
| 	f.IntVar(&diffOptions.Context, "context", 0, "output NUM lines of context around changes") | 	f.IntVar(&diffOptions.Context, "context", 0, "output NUM lines of context around changes") | ||||||
| 	f.StringVar(&diffOptions.Output, "output", "", "output format for diff plugin") | 	f.StringVar(&diffOptions.Output, "output", "", "output format for diff plugin") | ||||||
| 	f.BoolVar(&diffOptions.SuppressSecrets, "suppress-secrets", false, "suppress secrets in the output. highly recommended to specify on CI/CD use-cases") | 	f.BoolVar(&diffOptions.SuppressSecrets, "suppress-secrets", false, "suppress secrets in the output. highly recommended to specify on CI/CD use-cases") | ||||||
|  |  | ||||||
|  | @ -2211,6 +2211,7 @@ type applyConfig struct { | ||||||
| 	diffOutput             string | 	diffOutput             string | ||||||
| 	concurrency            int | 	concurrency            int | ||||||
| 	detailedExitcode       bool | 	detailedExitcode       bool | ||||||
|  | 	stripTrailingCR        bool | ||||||
| 	interactive            bool | 	interactive            bool | ||||||
| 	skipDiffOnInstall      bool | 	skipDiffOnInstall      bool | ||||||
| 	logger                 *zap.SugaredLogger | 	logger                 *zap.SugaredLogger | ||||||
|  | @ -2321,6 +2322,10 @@ func (a applyConfig) DetailedExitcode() bool { | ||||||
| 	return a.detailedExitcode | 	return a.detailedExitcode | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (a applyConfig) StripTrailingCR() bool { | ||||||
|  | 	return a.stripTrailingCR | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (a applyConfig) Interactive() bool { | func (a applyConfig) Interactive() bool { | ||||||
| 	return a.interactive | 	return a.interactive | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -63,6 +63,7 @@ type ApplyConfigProvider interface { | ||||||
| 	SuppressDiff() bool | 	SuppressDiff() bool | ||||||
| 
 | 
 | ||||||
| 	DetailedExitcode() bool | 	DetailedExitcode() bool | ||||||
|  | 	StripTrailingCR() bool | ||||||
| 
 | 
 | ||||||
| 	Color() bool | 	Color() bool | ||||||
| 	NoColor() bool | 	NoColor() bool | ||||||
|  | @ -130,6 +131,7 @@ type DiffConfigProvider interface { | ||||||
| 	DAGConfig | 	DAGConfig | ||||||
| 
 | 
 | ||||||
| 	DetailedExitcode() bool | 	DetailedExitcode() bool | ||||||
|  | 	StripTrailingCR() bool | ||||||
| 	Color() bool | 	Color() bool | ||||||
| 	NoColor() bool | 	NoColor() bool | ||||||
| 	Context() int | 	Context() int | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ type diffConfig struct { | ||||||
| 	diffOutput             string | 	diffOutput             string | ||||||
| 	concurrency            int | 	concurrency            int | ||||||
| 	detailedExitcode       bool | 	detailedExitcode       bool | ||||||
|  | 	stripTrailingCR        bool | ||||||
| 	interactive            bool | 	interactive            bool | ||||||
| 	skipDiffOnInstall      bool | 	skipDiffOnInstall      bool | ||||||
| 	reuseValues            bool | 	reuseValues            bool | ||||||
|  | @ -126,6 +127,10 @@ func (a diffConfig) DetailedExitcode() bool { | ||||||
| 	return a.detailedExitcode | 	return a.detailedExitcode | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (a diffConfig) StripTrailingCR() bool { | ||||||
|  | 	return a.stripTrailingCR | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (a diffConfig) Interactive() bool { | func (a diffConfig) Interactive() bool { | ||||||
| 	return a.interactive | 	return a.interactive | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -137,7 +137,7 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig | ||||||
| 
 | 
 | ||||||
| 	// TODO Better way to detect diff on only filtered releases
 | 	// TODO Better way to detect diff on only filtered releases
 | ||||||
| 	{ | 	{ | ||||||
| 		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.IncludeTests(), c.Suppress(), c.SuppressSecrets(), c.ShowSecrets(), c.NoHooks(), c.SuppressDiff(), triggerCleanupEvent, diffOpts) | 		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.StripTrailingCR(), c.IncludeTests(), c.Suppress(), c.SuppressSecrets(), c.ShowSecrets(), c.NoHooks(), c.SuppressDiff(), triggerCleanupEvent, diffOpts) | ||||||
| 
 | 
 | ||||||
| 		var err error | 		var err error | ||||||
| 		deletingReleases, err = st.DetectReleasesToBeDeletedForSync(helm, st.Releases) | 		deletingReleases, err = st.DetectReleasesToBeDeletedForSync(helm, st.Releases) | ||||||
|  |  | ||||||
|  | @ -16,7 +16,8 @@ type ApplyOptions struct { | ||||||
| 	Output string | 	Output string | ||||||
| 	// DetailedExitcode is true if the exit code should be 2 instead of 0 if there were changes detected and the changes were synced successfully
 | 	// DetailedExitcode is true if the exit code should be 2 instead of 0 if there were changes detected and the changes were synced successfully
 | ||||||
| 	DetailedExitcode bool | 	DetailedExitcode bool | ||||||
| 
 | 	// StripTrailingCR is true if trailing carriage returns should be stripped during diffing
 | ||||||
|  | 	StripTrailingCR bool | ||||||
| 	// TODO: Remove this function once Helmfile v0.x
 | 	// TODO: Remove this function once Helmfile v0.x
 | ||||||
| 	// DEPRECATED: Use skip-cleanup instead
 | 	// DEPRECATED: Use skip-cleanup instead
 | ||||||
| 	RetainValuesFiles bool | 	RetainValuesFiles bool | ||||||
|  | @ -96,6 +97,11 @@ func (a *ApplyImpl) DetailedExitcode() bool { | ||||||
| 	return a.ApplyOptions.DetailedExitcode | 	return a.ApplyOptions.DetailedExitcode | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // StripTrailingCR is true if trailing carriage returns should be stripped during diffing
 | ||||||
|  | func (a *ApplyImpl) StripTrailingCR() bool { | ||||||
|  | 	return a.ApplyOptions.StripTrailingCR | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // DiffOutput returns the diff output.
 | // DiffOutput returns the diff output.
 | ||||||
| func (a *ApplyImpl) DiffOutput() string { | func (a *ApplyImpl) DiffOutput() string { | ||||||
| 	return a.ApplyOptions.Output | 	return a.ApplyOptions.Output | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ type DiffOptions struct { | ||||||
| 	Values []string | 	Values []string | ||||||
| 	// DetailedExitcode is the detailed exit code
 | 	// DetailedExitcode is the detailed exit code
 | ||||||
| 	DetailedExitcode bool | 	DetailedExitcode bool | ||||||
|  | 	// StripTrailingCR is true if trailing carriage returns should be stripped during diffing
 | ||||||
|  | 	StripTrailingCR bool | ||||||
| 	// IncludeTests is the include tests flag
 | 	// IncludeTests is the include tests flag
 | ||||||
| 	IncludeTests bool | 	IncludeTests bool | ||||||
| 	// SkipNeeds is the include crds flag
 | 	// SkipNeeds is the include crds flag
 | ||||||
|  | @ -110,6 +112,11 @@ func (t *DiffImpl) DetailedExitcode() bool { | ||||||
| 	return t.DiffOptions.DetailedExitcode | 	return t.DiffOptions.DetailedExitcode | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // StripTrailingCR is true if trailing carriage returns should be stripped during diffing
 | ||||||
|  | func (a *DiffImpl) StripTrailingCR() bool { | ||||||
|  | 	return a.DiffOptions.StripTrailingCR | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Output returns the output
 | // Output returns the output
 | ||||||
| func (t *DiffImpl) DiffOutput() string { | func (t *DiffImpl) DiffOutput() string { | ||||||
| 	return t.DiffOptions.Output | 	return t.DiffOptions.Output | ||||||
|  |  | ||||||
|  | @ -1679,13 +1679,17 @@ type diffPrepareResult struct { | ||||||
| 	upgradeDueToSkippedDiff bool | 	upgradeDueToSkippedDiff bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (st *HelmState) commonDiffFlags(detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets bool, showSecrets bool, noHooks bool, opt *DiffOpts) []string { | func (st *HelmState) commonDiffFlags(detailedExitCode bool, stripTrailingCR bool, includeTests bool, suppress []string, suppressSecrets bool, showSecrets bool, noHooks bool, opt *DiffOpts) []string { | ||||||
| 	var flags []string | 	var flags []string | ||||||
| 
 | 
 | ||||||
| 	if detailedExitCode { | 	if detailedExitCode { | ||||||
| 		flags = append(flags, "--detailed-exitcode") | 		flags = append(flags, "--detailed-exitcode") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if stripTrailingCR { | ||||||
|  | 		flags = append(flags, "--strip-trailing-cr") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if includeTests { | 	if includeTests { | ||||||
| 		flags = append(flags, "--include-tests") | 		flags = append(flags, "--include-tests") | ||||||
| 	} | 	} | ||||||
|  | @ -1731,7 +1735,7 @@ func (st *HelmState) commonDiffFlags(detailedExitCode bool, includeTests bool, s | ||||||
| 	return flags | 	return flags | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets bool, showSecrets bool, noHooks bool, opts ...DiffOpt) ([]diffPrepareResult, []error) { | func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode bool, stripTrailingCR bool, includeTests bool, suppress []string, suppressSecrets bool, showSecrets bool, noHooks bool, opts ...DiffOpt) ([]diffPrepareResult, []error) { | ||||||
| 	opt := &DiffOpts{} | 	opt := &DiffOpts{} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| 		o.Apply(opt) | 		o.Apply(opt) | ||||||
|  | @ -1775,7 +1779,7 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu | ||||||
| 	jobs := make(chan *ReleaseSpec, numReleases) | 	jobs := make(chan *ReleaseSpec, numReleases) | ||||||
| 	results := make(chan diffPrepareResult, numReleases) | 	results := make(chan diffPrepareResult, numReleases) | ||||||
| 	resultsMap := map[string]diffPrepareResult{} | 	resultsMap := map[string]diffPrepareResult{} | ||||||
| 	commonDiffFlags := st.commonDiffFlags(detailedExitCode, includeTests, suppress, suppressSecrets, showSecrets, noHooks, opt) | 	commonDiffFlags := st.commonDiffFlags(detailedExitCode, stripTrailingCR, includeTests, suppress, suppressSecrets, showSecrets, noHooks, opt) | ||||||
| 
 | 
 | ||||||
| 	rs := []diffPrepareResult{} | 	rs := []diffPrepareResult{} | ||||||
| 	errs := []error{} | 	errs := []error{} | ||||||
|  | @ -1915,13 +1919,13 @@ type DiffOpt interface{ Apply(*DiffOpts) } | ||||||
| // For example, terraform-provider-helmfile runs a helmfile-diff on `terraform plan` and another on `terraform apply`.
 | // For example, terraform-provider-helmfile runs a helmfile-diff on `terraform plan` and another on `terraform apply`.
 | ||||||
| // `terraform`, by design, fails when helmfile-diff outputs were not equivalent.
 | // `terraform`, by design, fails when helmfile-diff outputs were not equivalent.
 | ||||||
| // Stabilized helmfile-diff output rescues that.
 | // Stabilized helmfile-diff output rescues that.
 | ||||||
| func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets, showSecrets, noHooks bool, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) { | func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode bool, stripTrailingCR bool, includeTests bool, suppress []string, suppressSecrets, showSecrets, noHooks bool, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) { | ||||||
| 	opts := &DiffOpts{} | 	opts := &DiffOpts{} | ||||||
| 	for _, o := range opt { | 	for _, o := range opt { | ||||||
| 		o.Apply(opts) | 		o.Apply(opts) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppress, suppressSecrets, showSecrets, noHooks, opts) | 	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, stripTrailingCR, includeTests, suppress, suppressSecrets, showSecrets, noHooks, opts) | ||||||
| 
 | 
 | ||||||
| 	if !opts.SkipCleanup { | 	if !opts.SkipCleanup { | ||||||
| 		defer func() { | 		defer func() { | ||||||
|  |  | ||||||
|  | @ -1853,7 +1853,7 @@ func TestHelmState_DiffReleases(t *testing.T) { | ||||||
| 				valsRuntime:    valsRuntime, | 				valsRuntime:    valsRuntime, | ||||||
| 				RenderedValues: map[string]interface{}{}, | 				RenderedValues: map[string]interface{}{}, | ||||||
| 			} | 			} | ||||||
| 			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false, false) | 			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, []string{}, false, false, false, false, false) | ||||||
| 			if len(errs) > 0 { | 			if len(errs) > 0 { | ||||||
| 				t.Errorf("unexpected error: %v", errs) | 				t.Errorf("unexpected error: %v", errs) | ||||||
| 			} | 			} | ||||||
|  | @ -2069,7 +2069,7 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) { | ||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 			state = injectFs(state, testfs) | 			state = injectFs(state, testfs) | ||||||
| 			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false, false); len(errs) > 0 { | 			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, []string{}, false, false, false, false, false); len(errs) > 0 { | ||||||
| 				t.Errorf("unexpected errors: %v", errs) | 				t.Errorf("unexpected errors: %v", errs) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -2740,7 +2740,7 @@ func TestDiffpareSyncReleases(t *testing.T) { | ||||||
| 			Lists: map[exectest.ListKey]string{}, | 			Lists: map[exectest.ListKey]string{}, | ||||||
| 			Helm3: true, | 			Helm3: true, | ||||||
| 		} | 		} | ||||||
| 		results, es := state.prepareDiffReleases(helm, []string{}, 1, false, false, []string{}, false, false, false, tt.diffOptions) | 		results, es := state.prepareDiffReleases(helm, []string{}, 1, false, false, false, []string{}, false, false, false, tt.diffOptions) | ||||||
| 
 | 
 | ||||||
| 		require.Len(t, es, 0) | 		require.Len(t, es, 0) | ||||||
| 		require.Len(t, results, 1) | 		require.Len(t, results, 1) | ||||||
|  | @ -3225,3 +3225,33 @@ func TestGenerateChartPath(t *testing.T) { | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestCommonDiffFlags(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name string | ||||||
|  | 		// stripTrailingCR is a flag to strip trailing carriage returns from the output
 | ||||||
|  | 		stripTrailingCR bool | ||||||
|  | 		expected        []string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:            "stripTrailingCR enabled", | ||||||
|  | 			stripTrailingCR: true, | ||||||
|  | 			expected: []string{ | ||||||
|  | 				"--strip-trailing-cr", | ||||||
|  | 				"--reset-values", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name: "stripTrailingCR disenabled", | ||||||
|  | 			expected: []string{ | ||||||
|  | 				"--reset-values", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		st := &HelmState{} | ||||||
|  | 		result := st.commonDiffFlags(false, tt.stripTrailingCR, false, []string{}, false, false, false, &DiffOpts{}) | ||||||
|  | 
 | ||||||
|  | 		require.Equal(t, tt.expected, result) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue