mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-19 15:53:15 +02:00
fix: --include-needs should only include direct dependencies
Fixes #1003 Previously, --include-needs was incorrectly including transitive dependencies (dependencies of dependencies). This fix ensures that: - --include-needs only includes direct needs - --include-transitive-needs includes both direct and transitive needs Changes: - Add separate handling for direct vs transitive needs in state.go - Add IncludeNeeds field to ChartPrepareOptions - Add unmarkNeedsDirectOnly() and collectDirectNeedsOnly() functions - Update ForEachState and related functions to accept both flags - Fix incorrect usage of c.IncludeNeeds() for IncludeTransitiveNeeds - Update tests to verify the correct behavior Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
@@ -117,7 +117,7 @@ func TestSelectReleasesWithOverrides(t *testing.T) {
|
||||
}
|
||||
state.Releases = state.GetReleasesWithLabels()
|
||||
|
||||
rs, err := state.GetSelectedReleases(false)
|
||||
rs, err := state.GetSelectedReleases(false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("%s %s: %v", tc.selector, tc.subject, err)
|
||||
}
|
||||
@@ -192,7 +192,7 @@ func TestSelectReleasesWithOverridesWithIncludedTransitives(t *testing.T) {
|
||||
}
|
||||
state.Releases = state.GetReleasesWithLabels()
|
||||
|
||||
rs, err := state.GetSelectedReleases(tc.includeTransitiveNeeds)
|
||||
rs, err := state.GetSelectedReleases(tc.includeTransitiveNeeds, tc.includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
t.Fatalf("%s %s: %v", tc.selector, tc.subject, err)
|
||||
}
|
||||
|
||||
+30
-10
@@ -1346,6 +1346,7 @@ type ChartPrepareOptions struct {
|
||||
WaitForJobs bool
|
||||
OutputDir string
|
||||
OutputDirTemplate string
|
||||
IncludeNeeds bool
|
||||
IncludeTransitiveNeeds bool
|
||||
Concurrency int
|
||||
KubeVersion string
|
||||
@@ -1822,7 +1823,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre
|
||||
}
|
||||
*st = *updated
|
||||
}
|
||||
selected, err := st.GetSelectedReleases(opts.IncludeTransitiveNeeds)
|
||||
selected, err := st.GetSelectedReleases(opts.IncludeNeeds, opts.IncludeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
@@ -2945,16 +2946,16 @@ func (st *HelmState) GetReleasesWithLabels() []ReleaseSpec {
|
||||
return rs
|
||||
}
|
||||
|
||||
func (st *HelmState) SelectReleases(includeTransitiveNeeds bool) ([]Release, error) {
|
||||
func (st *HelmState) SelectReleases(includeNeeds bool, includeTransitiveNeeds bool) ([]Release, error) {
|
||||
values := st.Values()
|
||||
rs, err := markExcludedReleases(st.Releases, st.Selectors, values, includeTransitiveNeeds)
|
||||
rs, err := markExcludedReleases(st.Releases, st.Selectors, values, includeNeeds, includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func markExcludedReleases(releases []ReleaseSpec, selectors []string, values map[string]any, includeTransitiveNeeds bool) ([]Release, error) {
|
||||
func markExcludedReleases(releases []ReleaseSpec, selectors []string, values map[string]any, includeNeeds bool, includeTransitiveNeeds bool) ([]Release, error) {
|
||||
var filteredReleases []Release
|
||||
filters := []ReleaseFilter{}
|
||||
for _, label := range selectors {
|
||||
@@ -2986,6 +2987,8 @@ func markExcludedReleases(releases []ReleaseSpec, selectors []string, values map
|
||||
}
|
||||
if includeTransitiveNeeds {
|
||||
unmarkNeedsAndTransitives(filteredReleases, releases)
|
||||
} else if includeNeeds {
|
||||
unmarkNeedsDirectOnly(filteredReleases, releases)
|
||||
}
|
||||
return filteredReleases, nil
|
||||
}
|
||||
@@ -3043,6 +3046,23 @@ func unmarkNeedsAndTransitives(filteredReleases []Release, allReleases []Release
|
||||
unmarkReleases(needsWithTranstives, filteredReleases)
|
||||
}
|
||||
|
||||
func unmarkNeedsDirectOnly(filteredReleases []Release, allReleases []ReleaseSpec) {
|
||||
directNeeds := collectDirectNeedsOnly(filteredReleases)
|
||||
unmarkReleases(directNeeds, filteredReleases)
|
||||
}
|
||||
|
||||
func collectDirectNeedsOnly(filteredReleases []Release) map[string]struct{} {
|
||||
directNeeds := map[string]struct{}{}
|
||||
for _, r := range filteredReleases {
|
||||
if !r.Filtered {
|
||||
for _, id := range r.ReleaseSpec.Needs {
|
||||
directNeeds[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return directNeeds
|
||||
}
|
||||
|
||||
func collectAllNeedsWithTransitives(filteredReleases []Release, allReleases []ReleaseSpec) map[string]struct{} {
|
||||
needsWithTranstives := map[string]struct{}{}
|
||||
for _, r := range filteredReleases {
|
||||
@@ -3076,8 +3096,8 @@ func collectNeedsWithTransitives(release ReleaseSpec, allReleases []ReleaseSpec,
|
||||
}
|
||||
}
|
||||
|
||||
func (st *HelmState) GetSelectedReleases(includeTransitiveNeeds bool) ([]ReleaseSpec, error) {
|
||||
filteredReleases, err := st.SelectReleases(includeTransitiveNeeds)
|
||||
func (st *HelmState) GetSelectedReleases(includeNeeds bool, includeTransitiveNeeds bool) ([]ReleaseSpec, error) {
|
||||
filteredReleases, err := st.SelectReleases(includeNeeds, includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -3092,8 +3112,8 @@ func (st *HelmState) GetSelectedReleases(includeTransitiveNeeds bool) ([]Release
|
||||
}
|
||||
|
||||
// FilterReleases allows for the execution of helm commands against a subset of the releases in the helmfile.
|
||||
func (st *HelmState) FilterReleases(includeTransitiveNeeds bool) error {
|
||||
releases, err := st.GetSelectedReleases(includeTransitiveNeeds)
|
||||
func (st *HelmState) FilterReleases(includeNeeds bool, includeTransitiveNeeds bool) error {
|
||||
releases, err := st.GetSelectedReleases(includeNeeds, includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -3173,7 +3193,7 @@ func (st *HelmState) ResolveDeps() (*HelmState, error) {
|
||||
}
|
||||
|
||||
// UpdateDeps wrapper for updating dependencies on the releases
|
||||
func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeTransitiveNeeds bool) []error {
|
||||
func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeNeeds bool, includeTransitiveNeeds bool) []error {
|
||||
var selected []ReleaseSpec
|
||||
|
||||
if len(st.Selectors) > 0 {
|
||||
@@ -3181,7 +3201,7 @@ func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeTransitiveNeeds
|
||||
|
||||
// This and releasesNeedCharts ensures that we run operations like helm-dep-build and prepare-hook calls only on
|
||||
// releases that are (1) selected by the selectors and (2) to be installed.
|
||||
selected, err = st.GetSelectedReleases(includeTransitiveNeeds)
|
||||
selected, err = st.GetSelectedReleases(includeNeeds, includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return []error{err}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ type PlanOptions struct {
|
||||
}
|
||||
|
||||
func (st *HelmState) PlanReleases(opts PlanOptions) ([][]Release, error) {
|
||||
marked, err := st.SelectReleases(opts.IncludeTransitiveNeeds)
|
||||
marked, err := st.SelectReleases(opts.IncludeNeeds, opts.IncludeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2589,7 +2589,7 @@ generated: 2019-05-16T15:42:45.50486+09:00
|
||||
})
|
||||
fs.Cwd = basePath
|
||||
state = injectFs(state, fs)
|
||||
errs := state.UpdateDeps(helm, false)
|
||||
errs := state.UpdateDeps(helm, false, false)
|
||||
|
||||
want := []string{"/example", "./example", generatedDir}
|
||||
if !reflect.DeepEqual(helm.Charts, want) {
|
||||
@@ -3058,7 +3058,7 @@ func TestHelmState_NoReleaseMatched(t *testing.T) {
|
||||
RenderedValues: map[string]any{},
|
||||
}
|
||||
state.Selectors = []string{tt.labels}
|
||||
errs := state.FilterReleases(false)
|
||||
errs := state.FilterReleases(false, false)
|
||||
if (errs != nil) != tt.wantErr {
|
||||
t.Errorf("ReleaseStatuses() for %s error = %v, wantErr %v", tt.name, errs, tt.wantErr)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user