diff --git a/pkg/action/install.go b/pkg/action/install.go index 605c423bc..0ec2f9056 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -844,7 +844,7 @@ OUTER: if err != nil { return err } - if dac.Name() == rac.Name() { + if dac.Name() == rac.Name() && (rac.Version() == "" || chartutil.IsCompatibleRange(rac.Version(), dac.Version())) { continue OUTER } } diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 2d83abe27..9c622f579 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -1196,6 +1196,27 @@ func TestCheckDependencies_MissingDependency(t *testing.T) { assert.ErrorContains(t, CheckDependencies(mockChart, []ci.Dependency{&dependency}), "missing in charts") } +func TestCheckDependencies_MatchingVersion(t *testing.T) { + dependency := chart.Dependency{Name: "hello", Version: "0.1.0"} + mockChart := buildChart(withDependency()) + + assert.NoError(t, CheckDependencies(mockChart, []ci.Dependency{&dependency})) +} + +func TestCheckDependencies_MismatchedVersion(t *testing.T) { + mismatched := chart.Dependency{Name: "hello", Version: "0.2.0"} + mockChart := buildChart(withDependency()) + + assert.ErrorContains(t, CheckDependencies(mockChart, []ci.Dependency{&mismatched}), "missing in charts") +} + +func TestCheckDependencies_WithoutVersionConstraint(t *testing.T) { + dependency := chart.Dependency{Name: "hello"} + mockChart := buildChart(withDependency()) + + assert.NoError(t, CheckDependencies(mockChart, []ci.Dependency{&dependency})) +} + func TestInstallCRDs_CheckNilErrors(t *testing.T) { tests := []struct { name string diff --git a/pkg/chart/common.go b/pkg/chart/common.go index be68eeb42..c8282d871 100644 --- a/pkg/chart/common.go +++ b/pkg/chart/common.go @@ -51,6 +51,10 @@ func (r *v2Accessor) Name() string { return r.chrt.Metadata.Name } +func (r *v2Accessor) Version() string { + return r.chrt.Metadata.Version +} + func (r *v2Accessor) IsRoot() bool { return r.chrt.IsRoot() } @@ -120,6 +124,10 @@ func (r *v3Accessor) Name() string { return r.chrt.Metadata.Name } +func (r *v3Accessor) Version() string { + return r.chrt.Metadata.Version +} + func (r *v3Accessor) IsRoot() bool { return r.chrt.IsRoot() } diff --git a/pkg/chart/dependency.go b/pkg/chart/dependency.go index 864fe6d2c..af06510b9 100644 --- a/pkg/chart/dependency.go +++ b/pkg/chart/dependency.go @@ -47,6 +47,10 @@ func (r *v2DependencyAccessor) Name() string { return r.dep.Name } +func (r *v2DependencyAccessor) Version() string { + return r.dep.Version +} + func (r *v2DependencyAccessor) Alias() string { return r.dep.Alias } @@ -59,6 +63,10 @@ func (r *v3DependencyAccessor) Name() string { return r.dep.Name } +func (r *v3DependencyAccessor) Version() string { + return r.dep.Version +} + func (r *v3DependencyAccessor) Alias() string { return r.dep.Alias } diff --git a/pkg/chart/interfaces.go b/pkg/chart/interfaces.go index 6d94ad3ea..e9ecb295c 100644 --- a/pkg/chart/interfaces.go +++ b/pkg/chart/interfaces.go @@ -25,6 +25,7 @@ type Dependency any type Accessor interface { Name() string + Version() string IsRoot() bool MetadataAsMap() map[string]any Files() []*common.File @@ -40,5 +41,6 @@ type Accessor interface { type DependencyAccessor interface { Name() string + Version() string Alias() string }