fix: deduplicate chart dependencies in helmfile.lock (#2567)
When multiple releases reference the same chart with the same name, repository, and version, helmfile deps would write duplicate entries to helmfile.lock. This adds deduplication of resolved dependencies after sorting and before writing the lock file. Fixes #2562 Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
parent
d3c68299da
commit
dac42105dd
|
|
@ -129,6 +129,20 @@ func (d *ResolvedDependencies) Get(chart, versionConstraint string) (string, err
|
|||
return "", fmt.Errorf("no resolved dependency found for \"%s\", running \"helmfile deps\" may resolve the issue", chart)
|
||||
}
|
||||
|
||||
func dedupResolvedDependencies(deps []ResolvedChartDependency) []ResolvedChartDependency {
|
||||
seen := map[string]bool{}
|
||||
result := make([]ResolvedChartDependency, 0, len(deps))
|
||||
for _, dep := range deps {
|
||||
key := dep.ChartName + "|" + dep.Repository + "|" + dep.Version
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
result = append(result, dep)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (st *HelmState) mergeLockedDependencies() (*HelmState, error) {
|
||||
filename, unresolved := getUnresolvedDependenciess(st)
|
||||
|
||||
|
|
@ -369,6 +383,8 @@ func (m *chartDependencyManager) doUpdate(chartLockFile string, unresolved *Unre
|
|||
return lockedReqs.ResolvedDependencies[i].ChartName < lockedReqs.ResolvedDependencies[j].ChartName
|
||||
})
|
||||
|
||||
lockedReqs.ResolvedDependencies = dedupResolvedDependencies(lockedReqs.ResolvedDependencies)
|
||||
|
||||
lockedReqs.Version = version.Version()
|
||||
|
||||
updatedLockFileContent, err = yaml.Marshal(lockedReqs)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,69 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDedupResolvedDependencies(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []ResolvedChartDependency
|
||||
expected []ResolvedChartDependency
|
||||
}{
|
||||
{
|
||||
name: "no duplicates",
|
||||
input: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "redis", Repository: "https://charts.bitnami.com/bitnami", Version: "17.0.7"},
|
||||
},
|
||||
expected: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "redis", Repository: "https://charts.bitnami.com/bitnami", Version: "17.0.7"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "duplicates removed",
|
||||
input: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
},
|
||||
expected: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "same chart different versions kept",
|
||||
input: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.1"},
|
||||
},
|
||||
expected: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "same chart different repos kept",
|
||||
input: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "app-template", Repository: "https://other.com", Version: "4.6.2"},
|
||||
},
|
||||
expected: []ResolvedChartDependency{
|
||||
{ChartName: "app-template", Repository: "https://example.com", Version: "4.6.2"},
|
||||
{ChartName: "app-template", Repository: "https://other.com", Version: "4.6.2"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty input",
|
||||
input: []ResolvedChartDependency{},
|
||||
expected: []ResolvedChartDependency{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := dedupResolvedDependencies(tt.input)
|
||||
require.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUnresolvedDependenciess(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Reference in New Issue