mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-19 02:47:27 +02:00
Add support for transitive dependencies. (#1983)
Co-authored-by: Peter Aichinger <petera@topdesk.com>
This commit is contained in:
co-authored by
Peter Aichinger
parent
9a0ce53608
commit
77e6268bcb
+69
-57
@@ -120,7 +120,7 @@ func (a *App) Deps(c DepsConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, c.IncludeTransitiveNeeds(), SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) Repos(c ReposConfigProvider) error {
|
||||
@@ -132,7 +132,7 @@ func (a *App) Repos(c ReposConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, c.IncludeTransitiveNeeds(), SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) DeprecatedSyncCharts(c DeprecatedChartsConfigProvider) error {
|
||||
@@ -149,7 +149,7 @@ func (a *App) DeprecatedSyncCharts(c DeprecatedChartsConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, c.IncludeTransitiveNeeds(), SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) Diff(c DiffConfigProvider) error {
|
||||
@@ -203,7 +203,7 @@ func (a *App) Diff(c DiffConfigProvider) error {
|
||||
}
|
||||
|
||||
return matched, criticalErrs
|
||||
})
|
||||
}, false)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -225,9 +225,6 @@ func (a *App) Diff(c DiffConfigProvider) error {
|
||||
}
|
||||
|
||||
func (a *App) Template(c TemplateConfigProvider) error {
|
||||
|
||||
opts := []LoadOption{SetRetainValuesFiles(c.SkipCleanup())}
|
||||
|
||||
return a.ForEachState(func(run *Run) (ok bool, errs []error) {
|
||||
includeCRDs := c.IncludeCRDs()
|
||||
|
||||
@@ -249,7 +246,7 @@ func (a *App) Template(c TemplateConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, opts...)
|
||||
}, c.IncludeTransitiveNeeds())
|
||||
}
|
||||
|
||||
func (a *App) WriteValues(c WriteValuesConfigProvider) error {
|
||||
@@ -269,7 +266,7 @@ func (a *App) WriteValues(c WriteValuesConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, c.IncludeTransitiveNeeds(), SetFilter(true))
|
||||
}
|
||||
|
||||
type MultiError struct {
|
||||
@@ -322,7 +319,7 @@ func (a *App) Lint(c LintConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -350,7 +347,7 @@ func (a *App) Fetch(c FetchConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) Sync(c SyncConfigProvider) error {
|
||||
@@ -358,11 +355,12 @@ func (a *App) Sync(c SyncConfigProvider) error {
|
||||
includeCRDs := !c.SkipCRDs()
|
||||
|
||||
prepErr := run.withPreparedCharts("sync", state.ChartPrepareOptions{
|
||||
SkipRepos: c.SkipDeps(),
|
||||
SkipDeps: c.SkipDeps(),
|
||||
Wait: c.Wait(),
|
||||
WaitForJobs: c.WaitForJobs(),
|
||||
IncludeCRDs: &includeCRDs,
|
||||
SkipRepos: c.SkipDeps(),
|
||||
SkipDeps: c.SkipDeps(),
|
||||
Wait: c.Wait(),
|
||||
WaitForJobs: c.WaitForJobs(),
|
||||
IncludeCRDs: &includeCRDs,
|
||||
IncludeTransitiveNeeds: c.IncludeTransitiveNeeds(),
|
||||
}, func() {
|
||||
ok, errs = a.sync(run, c)
|
||||
})
|
||||
@@ -372,7 +370,7 @@ func (a *App) Sync(c SyncConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
})
|
||||
}, c.IncludeTransitiveNeeds())
|
||||
}
|
||||
|
||||
func (a *App) Apply(c ApplyConfigProvider) error {
|
||||
@@ -410,7 +408,7 @@ func (a *App) Apply(c ApplyConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, opts...)
|
||||
}, c.IncludeTransitiveNeeds(), opts...)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -439,7 +437,7 @@ func (a *App) Status(c StatusesConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) Delete(c DeleteConfigProvider) error {
|
||||
@@ -456,7 +454,7 @@ func (a *App) Delete(c DeleteConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetReverse(true))
|
||||
}, false, SetReverse(true))
|
||||
}
|
||||
|
||||
func (a *App) Destroy(c DestroyConfigProvider) error {
|
||||
@@ -473,7 +471,7 @@ func (a *App) Destroy(c DestroyConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetReverse(true))
|
||||
}, false, SetReverse(true))
|
||||
}
|
||||
|
||||
func (a *App) Test(c TestConfigProvider) error {
|
||||
@@ -496,7 +494,7 @@ func (a *App) Test(c TestConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) PrintState(c StateConfigProvider) error {
|
||||
@@ -543,7 +541,7 @@ func (a *App) PrintState(c StateConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
}
|
||||
|
||||
func (a *App) ListReleases(c ListConfigProvider) error {
|
||||
@@ -594,7 +592,7 @@ func (a *App) ListReleases(c ListConfigProvider) error {
|
||||
}
|
||||
|
||||
return
|
||||
}, SetFilter(true))
|
||||
}, false, SetFilter(true))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -883,14 +881,14 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func (a *App) ForEachState(do func(*Run) (bool, []error), o ...LoadOption) error {
|
||||
func (a *App) ForEachState(do func(*Run) (bool, []error), includeTransitiveNeeds bool, o ...LoadOption) error {
|
||||
ctx := NewContext()
|
||||
err := a.visitStatesWithSelectorsAndRemoteSupport(a.FileOrDir, func(st *state.HelmState) (bool, []error) {
|
||||
helm := a.getHelm(st)
|
||||
|
||||
run := NewRun(st, helm, ctx)
|
||||
return do(run)
|
||||
}, o...)
|
||||
}, includeTransitiveNeeds, o...)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -966,7 +964,7 @@ type Opts struct {
|
||||
DAGEnabled bool
|
||||
}
|
||||
|
||||
func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converge func(*state.HelmState) (bool, []error), opt ...LoadOption) error {
|
||||
func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converge func(*state.HelmState) (bool, []error), includeTransitiveNeeds bool, opt ...LoadOption) error {
|
||||
opts := LoadOpts{
|
||||
Selectors: a.Selectors,
|
||||
}
|
||||
@@ -1004,16 +1002,17 @@ func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converg
|
||||
return processFilteredReleases(st, a.getHelm(st), func(st *state.HelmState) []error {
|
||||
_, err := converge(st)
|
||||
return err
|
||||
})
|
||||
},
|
||||
includeTransitiveNeeds)
|
||||
}
|
||||
}
|
||||
|
||||
return a.visitStates(fileOrDir, opts, f)
|
||||
}
|
||||
|
||||
func processFilteredReleases(st *state.HelmState, helm helmexec.Interface, converge func(st *state.HelmState) []error) (bool, []error) {
|
||||
func processFilteredReleases(st *state.HelmState, helm helmexec.Interface, converge func(st *state.HelmState) []error, includeTransitiveNeeds bool) (bool, []error) {
|
||||
if len(st.Selectors) > 0 {
|
||||
err := st.FilterReleases()
|
||||
err := st.FilterReleases(includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1066,11 +1065,11 @@ func checkDuplicates(helm helmexec.Interface, st *state.HelmState, releases []st
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) Wrap(converge func(*state.HelmState, helmexec.Interface) []error) func(st *state.HelmState, helm helmexec.Interface) (bool, []error) {
|
||||
return func(st *state.HelmState, helm helmexec.Interface) (bool, []error) {
|
||||
func (a *App) Wrap(converge func(*state.HelmState, helmexec.Interface) []error) func(st *state.HelmState, helm helmexec.Interface, includeTransitiveNeeds bool) (bool, []error) {
|
||||
return func(st *state.HelmState, helm helmexec.Interface, includeTransitiveNeeds bool) (bool, []error) {
|
||||
return processFilteredReleases(st, helm, func(st *state.HelmState) []error {
|
||||
return converge(st, helm)
|
||||
})
|
||||
}, includeTransitiveNeeds)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1144,8 +1143,8 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (a *App) getSelectedReleases(r *Run) ([]state.ReleaseSpec, []state.ReleaseSpec, error) {
|
||||
selected, err := r.state.GetSelectedReleasesWithOverrides()
|
||||
func (a *App) getSelectedReleases(r *Run, includeTransitiveNeeds bool) ([]state.ReleaseSpec, []state.ReleaseSpec, error) {
|
||||
selected, err := r.state.GetSelectedReleasesWithOverrides(includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -1159,12 +1158,7 @@ func (a *App) getSelectedReleases(r *Run) ([]state.ReleaseSpec, []state.ReleaseS
|
||||
|
||||
needed := map[string]struct{}{}
|
||||
for _, r := range selected {
|
||||
for _, id := range r.Needs {
|
||||
// Avoids duplicating a release that is selected AND also needed by another selected release
|
||||
if _, ok := selectedIds[id]; !ok {
|
||||
needed[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
collectNeeds(r, selectedIds, needed, allReleases, includeTransitiveNeeds)
|
||||
}
|
||||
|
||||
var releases []state.ReleaseSpec
|
||||
@@ -1192,11 +1186,29 @@ func (a *App) getSelectedReleases(r *Run) ([]state.ReleaseSpec, []state.ReleaseS
|
||||
return selected, releases, nil
|
||||
}
|
||||
|
||||
func collectNeeds(release state.ReleaseSpec, selectedIds map[string]struct{}, needed map[string]struct{}, allReleases []state.ReleaseSpec, includeTransitiveNeeds bool) {
|
||||
for _, id := range release.Needs {
|
||||
// Avoids duplicating a release that is selected AND also needed by another selected release
|
||||
if _, ok := selectedIds[id]; !ok {
|
||||
needed[id] = struct{}{}
|
||||
if includeTransitiveNeeds {
|
||||
releaseParts := strings.Split(id, "/")
|
||||
releaseName := releaseParts[len(releaseParts)-1]
|
||||
for _, r := range allReleases {
|
||||
if r.Name == releaseName {
|
||||
collectNeeds(r, selectedIds, needed, allReleases, includeTransitiveNeeds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) {
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r)
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r, c.IncludeTransitiveNeeds())
|
||||
if err != nil {
|
||||
return false, false, []error{err}
|
||||
}
|
||||
@@ -1210,7 +1222,7 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) {
|
||||
// See https://github.com/roboll/helmfile/issues/1818 for more context.
|
||||
st.Releases = selectedAndNeededReleases
|
||||
|
||||
plan, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, SkipNeeds: c.SkipNeeds(), IncludeNeeds: c.IncludeNeeds()})
|
||||
plan, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, SkipNeeds: c.SkipNeeds(), IncludeNeeds: c.IncludeNeeds(), IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()})
|
||||
if err != nil {
|
||||
return false, false, []error{err}
|
||||
}
|
||||
@@ -1320,7 +1332,7 @@ Do you really want to apply?
|
||||
|
||||
// We upgrade releases by traversing the DAG
|
||||
if len(releasesToBeUpdated) > 0 {
|
||||
_, updateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, Reverse: false, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
_, updateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, Reverse: false, SkipNeeds: true, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
var rs []state.ReleaseSpec
|
||||
|
||||
for _, r := range subst.Releases {
|
||||
@@ -1357,7 +1369,7 @@ func (a *App) delete(r *Run, purge bool, c DestroyConfigProvider) (bool, []error
|
||||
|
||||
affectedReleases := state.AffectedReleases{}
|
||||
|
||||
toSync, _, err := a.getSelectedReleases(r)
|
||||
toSync, _, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1429,7 +1441,7 @@ Do you really want to delete?
|
||||
func (a *App) diff(r *Run, c DiffConfigProvider) (*string, bool, bool, []error) {
|
||||
st := r.state
|
||||
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r)
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return nil, false, false, []error{err}
|
||||
}
|
||||
@@ -1450,7 +1462,7 @@ func (a *App) diff(r *Run, c DiffConfigProvider) (*string, bool, bool, []error)
|
||||
|
||||
st.Releases = selectedAndNeededReleases
|
||||
|
||||
plan, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, SkipNeeds: c.SkipNeeds(), IncludeNeeds: c.IncludeNeeds()})
|
||||
plan, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, SkipNeeds: c.SkipNeeds(), IncludeNeeds: c.IncludeNeeds(), IncludeTransitiveNeeds: false})
|
||||
if err != nil {
|
||||
return nil, false, false, []error{err}
|
||||
}
|
||||
@@ -1485,7 +1497,7 @@ func (a *App) lint(r *Run, c LintConfigProvider) (bool, []error, []error) {
|
||||
|
||||
allReleases := st.GetReleasesWithOverrides()
|
||||
|
||||
selectedReleases, _, err := a.getSelectedReleases(r)
|
||||
selectedReleases, _, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return false, nil, []error{err}
|
||||
}
|
||||
@@ -1553,7 +1565,7 @@ func (a *App) status(r *Run, c StatusesConfigProvider) (bool, []error) {
|
||||
|
||||
allReleases := st.GetReleasesWithOverrides()
|
||||
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r)
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1603,7 +1615,7 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r)
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r, c.IncludeTransitiveNeeds())
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1617,7 +1629,7 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
|
||||
// See https://github.com/roboll/helmfile/issues/1818 for more context.
|
||||
st.Releases = selectedAndNeededReleases
|
||||
|
||||
batches, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, IncludeNeeds: c.IncludeNeeds(), SkipNeeds: c.SkipNeeds()})
|
||||
batches, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, IncludeNeeds: c.IncludeNeeds(), IncludeTransitiveNeeds: c.IncludeTransitiveNeeds(), SkipNeeds: c.SkipNeeds()})
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1727,7 +1739,7 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
|
||||
}
|
||||
|
||||
if len(releasesToUpdate) > 0 {
|
||||
_, syncErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
_, syncErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, SkipNeeds: true, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
var rs []state.ReleaseSpec
|
||||
|
||||
for _, r := range subst.Releases {
|
||||
@@ -1759,7 +1771,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r)
|
||||
selectedReleases, selectedAndNeededReleases, err := a.getSelectedReleases(r, c.IncludeTransitiveNeeds())
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1773,7 +1785,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
||||
// See https://github.com/roboll/helmfile/issues/1818 for more context.
|
||||
st.Releases = selectedAndNeededReleases
|
||||
|
||||
batches, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, IncludeNeeds: c.IncludeNeeds(), SkipNeeds: !c.IncludeNeeds()})
|
||||
batches, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, IncludeNeeds: c.IncludeNeeds(), IncludeTransitiveNeeds: c.IncludeTransitiveNeeds(), SkipNeeds: !c.IncludeNeeds()})
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
@@ -1813,7 +1825,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
||||
}
|
||||
|
||||
if len(toRender) > 0 {
|
||||
_, templateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toRender, Reverse: false, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
_, templateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toRender, Reverse: false, SkipNeeds: true, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||
opts := &state.TemplateOpts{
|
||||
Set: c.Set(),
|
||||
IncludeCRDs: c.IncludeCRDs(),
|
||||
@@ -1837,7 +1849,7 @@ func (a *App) test(r *Run, c TestConfigProvider) []error {
|
||||
|
||||
st := r.state
|
||||
|
||||
toTest, _, err := a.getSelectedReleases(r)
|
||||
toTest, _, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return []error{err}
|
||||
}
|
||||
@@ -1859,7 +1871,7 @@ func (a *App) writeValues(r *Run, c WriteValuesConfigProvider) (bool, []error) {
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
|
||||
toRender, _, err := a.getSelectedReleases(r)
|
||||
toRender, _, err := a.getSelectedReleases(r, false)
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ import (
|
||||
|
||||
func TestApply_3(t *testing.T) {
|
||||
type fields struct {
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
type testcase struct {
|
||||
@@ -109,11 +110,12 @@ func TestApply_3(t *testing.T) {
|
||||
|
||||
syncErr := app.Apply(applyConfig{
|
||||
// if we check log output, concurrency must be 1. otherwise the test becomes non-deterministic.
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
||||
})
|
||||
|
||||
var gotErr string
|
||||
|
||||
+131
-7
@@ -17,8 +17,9 @@ import (
|
||||
|
||||
func TestApply_2(t *testing.T) {
|
||||
type fields struct {
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
type testcase struct {
|
||||
@@ -109,11 +110,12 @@ func TestApply_2(t *testing.T) {
|
||||
|
||||
syncErr := app.Apply(applyConfig{
|
||||
// if we check log output, concurrency must be 1. otherwise the test becomes non-deterministic.
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
||||
})
|
||||
|
||||
var gotErr string
|
||||
@@ -960,6 +962,128 @@ NAME CHART VERSION
|
||||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("include-transitive-needs=true", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
fields: fields{
|
||||
skipNeeds: false,
|
||||
includeNeeds: true,
|
||||
includeTransitiveNeeds: true,
|
||||
},
|
||||
error: ``,
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
{{ $mark := "a" }}
|
||||
|
||||
releases:
|
||||
- name: serviceA
|
||||
chart: my/chart
|
||||
needs:
|
||||
- serviceB
|
||||
|
||||
- name: serviceB
|
||||
chart: my/chart
|
||||
needs:
|
||||
- serviceC
|
||||
|
||||
- name: serviceC
|
||||
chart: my/chart
|
||||
|
||||
- name: serviceD
|
||||
chart: my/chart
|
||||
`,
|
||||
},
|
||||
selectors: []string{"name=serviceA"},
|
||||
upgraded: []exectest.Release{},
|
||||
diffs: map[exectest.DiffKey]error{
|
||||
exectest.DiffKey{Name: "serviceA", Chart: "my/chart", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
exectest.DiffKey{Name: "serviceB", Chart: "my/chart", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
exectest.DiffKey{Name: "serviceC", Chart: "my/chart", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
0:
|
||||
1:
|
||||
2:
|
||||
3: releases:
|
||||
4: - name: serviceA
|
||||
5: chart: my/chart
|
||||
6: needs:
|
||||
7: - serviceB
|
||||
8:
|
||||
9: - name: serviceB
|
||||
10: chart: my/chart
|
||||
11: needs:
|
||||
12: - serviceC
|
||||
13:
|
||||
14: - name: serviceC
|
||||
15: chart: my/chart
|
||||
16:
|
||||
17: - name: serviceD
|
||||
18: chart: my/chart
|
||||
19:
|
||||
|
||||
first-pass produced: &{default map[] map[]}
|
||||
first-pass rendering result of "helmfile.yaml.part.0": {default map[] map[]}
|
||||
vals:
|
||||
map[]
|
||||
defaultVals:[]
|
||||
second-pass rendering result of "helmfile.yaml.part.0":
|
||||
0:
|
||||
1:
|
||||
2:
|
||||
3: releases:
|
||||
4: - name: serviceA
|
||||
5: chart: my/chart
|
||||
6: needs:
|
||||
7: - serviceB
|
||||
8:
|
||||
9: - name: serviceB
|
||||
10: chart: my/chart
|
||||
11: needs:
|
||||
12: - serviceC
|
||||
13:
|
||||
14: - name: serviceC
|
||||
15: chart: my/chart
|
||||
16:
|
||||
17: - name: serviceD
|
||||
18: chart: my/chart
|
||||
19:
|
||||
|
||||
merged environment: &{default map[] map[]}
|
||||
3 release(s) matching name=serviceA found in helmfile.yaml
|
||||
|
||||
Affected releases are:
|
||||
serviceA (my/chart) UPDATED
|
||||
serviceB (my/chart) UPDATED
|
||||
serviceC (my/chart) UPDATED
|
||||
|
||||
processing 3 groups of releases in this order:
|
||||
GROUP RELEASES
|
||||
1 default//serviceC
|
||||
2 default//serviceB
|
||||
3 default//serviceA
|
||||
|
||||
processing releases in group 1/3: default//serviceC
|
||||
getting deployed release version failed:unexpected list key: {^serviceC$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
processing releases in group 2/3: default//serviceB
|
||||
getting deployed release version failed:unexpected list key: {^serviceB$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
processing releases in group 3/3: default//serviceA
|
||||
getting deployed release version failed:unexpected list key: {^serviceA$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
|
||||
UPDATED RELEASES:
|
||||
NAME CHART VERSION
|
||||
serviceC my/chart
|
||||
serviceB my/chart
|
||||
serviceA my/chart
|
||||
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
||||
+131
-11
@@ -17,8 +17,9 @@ import (
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
type fields struct {
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
type testcase struct {
|
||||
@@ -107,11 +108,12 @@ func TestSync(t *testing.T) {
|
||||
|
||||
syncErr := app.Sync(applyConfig{
|
||||
// if we check log output, concurrency must be 1. otherwise the test becomes non-deterministic.
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||
skipNeeds: tc.fields.skipNeeds,
|
||||
includeNeeds: tc.fields.includeNeeds,
|
||||
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
||||
})
|
||||
|
||||
var gotErr string
|
||||
@@ -412,6 +414,122 @@ kubernetes-external-secrets incubator/raw
|
||||
external-secrets incubator/raw
|
||||
my-release incubator/raw
|
||||
|
||||
`,
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("include-transitive-needs=true", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
fields: fields{
|
||||
skipNeeds: false,
|
||||
includeTransitiveNeeds: true,
|
||||
},
|
||||
error: ``,
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
{{ $mark := "a" }}
|
||||
|
||||
releases:
|
||||
- name: serviceA
|
||||
chart: my/chart
|
||||
needs:
|
||||
- serviceB
|
||||
|
||||
- name: serviceB
|
||||
chart: my/chart
|
||||
needs:
|
||||
- serviceC
|
||||
|
||||
- name: serviceC
|
||||
chart: my/chart
|
||||
|
||||
- name: serviceD
|
||||
chart: my/chart
|
||||
`,
|
||||
},
|
||||
selectors: []string{"name=serviceA"},
|
||||
upgraded: []exectest.Release{},
|
||||
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||
concurrency: 1,
|
||||
log: `processing file "helmfile.yaml" in directory "."
|
||||
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||
first-pass uses: &{default map[] map[]}
|
||||
first-pass rendering output of "helmfile.yaml.part.0":
|
||||
0:
|
||||
1:
|
||||
2:
|
||||
3: releases:
|
||||
4: - name: serviceA
|
||||
5: chart: my/chart
|
||||
6: needs:
|
||||
7: - serviceB
|
||||
8:
|
||||
9: - name: serviceB
|
||||
10: chart: my/chart
|
||||
11: needs:
|
||||
12: - serviceC
|
||||
13:
|
||||
14: - name: serviceC
|
||||
15: chart: my/chart
|
||||
16:
|
||||
17: - name: serviceD
|
||||
18: chart: my/chart
|
||||
19:
|
||||
|
||||
first-pass produced: &{default map[] map[]}
|
||||
first-pass rendering result of "helmfile.yaml.part.0": {default map[] map[]}
|
||||
vals:
|
||||
map[]
|
||||
defaultVals:[]
|
||||
second-pass rendering result of "helmfile.yaml.part.0":
|
||||
0:
|
||||
1:
|
||||
2:
|
||||
3: releases:
|
||||
4: - name: serviceA
|
||||
5: chart: my/chart
|
||||
6: needs:
|
||||
7: - serviceB
|
||||
8:
|
||||
9: - name: serviceB
|
||||
10: chart: my/chart
|
||||
11: needs:
|
||||
12: - serviceC
|
||||
13:
|
||||
14: - name: serviceC
|
||||
15: chart: my/chart
|
||||
16:
|
||||
17: - name: serviceD
|
||||
18: chart: my/chart
|
||||
19:
|
||||
|
||||
merged environment: &{default map[] map[]}
|
||||
3 release(s) matching name=serviceA found in helmfile.yaml
|
||||
|
||||
Affected releases are:
|
||||
serviceA (my/chart) UPDATED
|
||||
serviceB (my/chart) UPDATED
|
||||
serviceC (my/chart) UPDATED
|
||||
|
||||
processing 3 groups of releases in this order:
|
||||
GROUP RELEASES
|
||||
1 default//serviceC
|
||||
2 default//serviceB
|
||||
3 default//serviceA
|
||||
|
||||
processing releases in group 1/3: default//serviceC
|
||||
getting deployed release version failed:unexpected list key: {^serviceC$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
processing releases in group 2/3: default//serviceB
|
||||
getting deployed release version failed:unexpected list key: {^serviceB$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
processing releases in group 3/3: default//serviceA
|
||||
getting deployed release version failed:unexpected list key: {^serviceA$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||
|
||||
UPDATED RELEASES:
|
||||
NAME CHART VERSION
|
||||
serviceC my/chart
|
||||
serviceB my/chart
|
||||
serviceA my/chart
|
||||
|
||||
`,
|
||||
})
|
||||
})
|
||||
@@ -419,8 +537,9 @@ my-release incubator/raw
|
||||
t.Run("skip-needs=false include-needs=true with installed but disabled release", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
fields: fields{
|
||||
skipNeeds: false,
|
||||
includeNeeds: true,
|
||||
skipNeeds: false,
|
||||
includeNeeds: true,
|
||||
includeTransitiveNeeds: false,
|
||||
},
|
||||
error: ``,
|
||||
files: map[string]string{
|
||||
@@ -561,8 +680,9 @@ kubernetes-external-secrets
|
||||
t.Run("skip-needs=false include-needs=true with not installed and disabled release", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
fields: fields{
|
||||
skipNeeds: false,
|
||||
includeNeeds: true,
|
||||
skipNeeds: false,
|
||||
includeTransitiveNeeds: false,
|
||||
includeNeeds: true,
|
||||
},
|
||||
error: ``,
|
||||
files: map[string]string{
|
||||
|
||||
+65
-28
@@ -106,6 +106,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -157,6 +158,7 @@ BAZ: 4
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -198,6 +200,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err == nil {
|
||||
@@ -242,6 +245,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -293,6 +297,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if testcase.expectErr && err == nil {
|
||||
@@ -359,6 +364,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if testcase.expectErr && err == nil {
|
||||
@@ -413,6 +419,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
Noop,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if testcase.expectErr && err == nil {
|
||||
@@ -531,6 +538,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if testcase.expectErr {
|
||||
@@ -774,6 +782,7 @@ func runFilterSubHelmFilesTests(testcases []struct {
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if testcase.expectErr {
|
||||
@@ -869,6 +878,7 @@ tillerNs: INLINE_TILLER_NS_2
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -970,6 +980,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetReverse(testcase.reverse),
|
||||
SetFilter(true),
|
||||
)
|
||||
@@ -1035,6 +1046,7 @@ bar: "bar1"
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1157,6 +1169,7 @@ x:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1209,6 +1222,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1266,6 +1280,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1316,6 +1331,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -1364,6 +1380,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -1407,6 +1424,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -1450,6 +1468,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -1497,6 +1516,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
|
||||
@@ -2246,8 +2266,9 @@ type configImpl struct {
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
func (a configImpl) Selectors() []string {
|
||||
@@ -2290,6 +2311,10 @@ func (c configImpl) IncludeNeeds() bool {
|
||||
return c.includeNeeds
|
||||
}
|
||||
|
||||
func (c configImpl) IncludeTransitiveNeeds() bool {
|
||||
return c.includeTransitiveNeeds
|
||||
}
|
||||
|
||||
func (c configImpl) OutputDir() string {
|
||||
return "output/subdir"
|
||||
}
|
||||
@@ -2315,30 +2340,31 @@ func (c configImpl) Output() string {
|
||||
}
|
||||
|
||||
type applyConfig struct {
|
||||
args string
|
||||
values []string
|
||||
retainValuesFiles bool
|
||||
set []string
|
||||
validate bool
|
||||
skipCleanup bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTests bool
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
suppressDiff bool
|
||||
noColor bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
logger *zap.SugaredLogger
|
||||
wait bool
|
||||
waitForJobs bool
|
||||
args string
|
||||
values []string
|
||||
retainValuesFiles bool
|
||||
set []string
|
||||
validate bool
|
||||
skipCleanup bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
includeTests bool
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
suppressDiff bool
|
||||
noColor bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
logger *zap.SugaredLogger
|
||||
wait bool
|
||||
waitForJobs bool
|
||||
}
|
||||
|
||||
func (a applyConfig) Args() string {
|
||||
@@ -2385,6 +2411,10 @@ func (c applyConfig) IncludeNeeds() bool {
|
||||
return c.includeNeeds
|
||||
}
|
||||
|
||||
func (c applyConfig) IncludeTransitiveNeeds() bool {
|
||||
return c.includeTransitiveNeeds
|
||||
}
|
||||
|
||||
func (a applyConfig) IncludeTests() bool {
|
||||
return a.includeTests
|
||||
}
|
||||
@@ -2438,13 +2468,18 @@ func (a applyConfig) SkipDiffOnInstall() bool {
|
||||
}
|
||||
|
||||
type depsConfig struct {
|
||||
skipRepos bool
|
||||
skipRepos bool
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
func (d depsConfig) SkipRepos() bool {
|
||||
return d.skipRepos
|
||||
}
|
||||
|
||||
func (d depsConfig) IncludeTransitiveNeeds() bool {
|
||||
return d.includeTransitiveNeeds
|
||||
}
|
||||
|
||||
func (d depsConfig) Args() string {
|
||||
return ""
|
||||
}
|
||||
@@ -4482,7 +4517,8 @@ See https://github.com/roboll/helmfile/issues/878 for more information.
|
||||
}, tc.files)
|
||||
|
||||
depsErr := app.Deps(depsConfig{
|
||||
skipRepos: false,
|
||||
skipRepos: false,
|
||||
includeTransitiveNeeds: false,
|
||||
})
|
||||
|
||||
if tc.error == "" && depsErr != nil {
|
||||
@@ -4777,6 +4813,7 @@ releases:
|
||||
|
||||
err := app.ForEachState(
|
||||
collectReleases,
|
||||
false,
|
||||
SetFilter(true),
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -23,15 +23,18 @@ type DeprecatedChartsConfigProvider interface {
|
||||
|
||||
concurrencyConfig
|
||||
loggingConfig
|
||||
IncludeTransitiveNeeds() bool
|
||||
}
|
||||
|
||||
type DepsConfigProvider interface {
|
||||
Args() string
|
||||
SkipRepos() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
}
|
||||
|
||||
type ReposConfigProvider interface {
|
||||
Args() string
|
||||
IncludeTransitiveNeeds() bool
|
||||
}
|
||||
|
||||
type ApplyConfigProvider interface {
|
||||
@@ -63,6 +66,7 @@ type ApplyConfigProvider interface {
|
||||
|
||||
SkipNeeds() bool
|
||||
IncludeNeeds() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
|
||||
concurrencyConfig
|
||||
interactive
|
||||
@@ -81,6 +85,7 @@ type SyncConfigProvider interface {
|
||||
|
||||
SkipNeeds() bool
|
||||
IncludeNeeds() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
|
||||
concurrencyConfig
|
||||
loggingConfig
|
||||
@@ -174,6 +179,7 @@ type TemplateConfigProvider interface {
|
||||
OutputDir() string
|
||||
IncludeCRDs() bool
|
||||
IncludeNeeds() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
|
||||
concurrencyConfig
|
||||
}
|
||||
@@ -183,6 +189,7 @@ type WriteValuesConfigProvider interface {
|
||||
Set() []string
|
||||
OutputFileTemplate() string
|
||||
SkipDeps() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
}
|
||||
|
||||
type StatusesConfigProvider interface {
|
||||
|
||||
@@ -103,8 +103,9 @@ func TestDestroy_2(t *testing.T) {
|
||||
|
||||
destroyErr := app.Destroy(destroyConfig{
|
||||
// if we check log output, concurrency must be 1. otherwise the test becomes non-deterministic.
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
concurrency: tc.concurrency,
|
||||
logger: logger,
|
||||
includeTransitiveNeeds: false,
|
||||
})
|
||||
|
||||
if tc.error == "" && destroyErr != nil {
|
||||
|
||||
+10
-5
@@ -23,11 +23,12 @@ const (
|
||||
)
|
||||
|
||||
type destroyConfig struct {
|
||||
args string
|
||||
concurrency int
|
||||
interactive bool
|
||||
skipDeps bool
|
||||
logger *zap.SugaredLogger
|
||||
args string
|
||||
concurrency int
|
||||
interactive bool
|
||||
skipDeps bool
|
||||
logger *zap.SugaredLogger
|
||||
includeTransitiveNeeds bool
|
||||
}
|
||||
|
||||
func (d destroyConfig) Args() string {
|
||||
@@ -50,6 +51,10 @@ func (d destroyConfig) SkipDeps() bool {
|
||||
return d.skipDeps
|
||||
}
|
||||
|
||||
func (d destroyConfig) IncludeTransitiveNeeds() bool {
|
||||
return d.includeTransitiveNeeds
|
||||
}
|
||||
|
||||
func TestDestroy(t *testing.T) {
|
||||
type testcase struct {
|
||||
helm3 bool
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ func (r *Run) withPreparedCharts(helmfileCommand string, opts state.ChartPrepare
|
||||
func (r *Run) Deps(c DepsConfigProvider) []error {
|
||||
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
||||
|
||||
return r.state.UpdateDeps(r.helm)
|
||||
return r.state.UpdateDeps(r.helm, c.IncludeTransitiveNeeds())
|
||||
}
|
||||
|
||||
func (r *Run) Repos(c ReposConfigProvider) error {
|
||||
|
||||
Reference in New Issue
Block a user