From 629656cd8a182d1f4f02aef85b585997e7e928c4 Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Thu, 19 Nov 2020 19:59:30 -0800 Subject: [PATCH] fix(helm): Don't discard pre-releases upon index merge Previously, when attempting to merge a new version into an existing index.yaml which includes overlapping release and pre-release versions (such as 0.1.0 and 0.1-dev), the merge would silently discard the pre-release version from the newly merged index. Fix this by performing an exact semantic comparison of the versions from the provided index file. Signed-off-by: Joe Stringer --- pkg/repo/index.go | 9 +++-- pkg/repo/index_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/pkg/repo/index.go b/pkg/repo/index.go index 43f1e1c87..fb67bb34a 100644 --- a/pkg/repo/index.go +++ b/pkg/repo/index.go @@ -135,8 +135,13 @@ func (i IndexFile) Add(md *chart.Metadata, filename, baseURL, digest string) { // Has returns true if the index has an entry for a chart with the given name and exact version. func (i IndexFile) Has(name, version string) bool { - _, err := i.Get(name, version) - return err == nil + vs := i.Entries[name] + for _, v := range vs { + if v.Version == version { + return true + } + } + return false } // SortEntries sorts the entries by version in descending order. diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go index b3d91402b..a1a95ddf8 100644 --- a/pkg/repo/index_test.go +++ b/pkg/repo/index_test.go @@ -214,6 +214,81 @@ func TestMerge(t *testing.T) { } +func TestMergePrerelease(t *testing.T) { + ind1 := NewIndexFile() + ind1.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.2.0", + }, "dreadnought-0.2.0.tgz", "http://example.com", "aaaa") + + ind2 := NewIndexFile() + ind2.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.1.0", + }, "dreadnought-0.1.0.tgz", "http://example.com", "aaaabbbb") + ind2.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.1-dev", + }, "dreadnought-0.1-dev.tgz", "http://example.com", "ccccbbbb") + + ind1.Merge(ind2) + + if len(ind1.Entries) != 1 { + t.Errorf("Expected 1 entries, got %d", len(ind1.Entries)) + } + vs := ind1.Entries["dreadnought"] + if len(vs) != 3 { + t.Errorf("Expected 3 versions, got %d", len(vs)) + for i := 0; i < len(vs); i++ { + t.Errorf("* %+v", ind1.Entries["dreadnought"][i].Metadata.Version) + } + } + v := vs[0] + if v.Version != "0.2.0" { + t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version) + } + +} + +func TestMergeSameVersion(t *testing.T) { + ind1 := NewIndexFile() + ind1.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.2.0", + }, "dreadnought-0.2.0.tgz", "http://example.com", "aaaa") + + ind2 := NewIndexFile() + ind2.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.2.0", + }, "dreadnought-0.2.0.tgz", "http://example.com", "aaaabbbb") + ind2.Add(&chart.Metadata{ + Name: "dreadnought", + Version: "0.1-dev", + }, "dreadnought-0.1-dev.tgz", "http://example.com", "ccccbbbb") + + ind1.Merge(ind2) + + if len(ind1.Entries) != 1 { + t.Errorf("Expected 1 entries, got %d", len(ind1.Entries)) + } + vs := ind1.Entries["dreadnought"] + if len(vs) != 2 { + t.Errorf("Expected 2 versions, got %d", len(vs)) + for i := 0; i < len(vs); i++ { + t.Errorf("* %+v", ind1.Entries["dreadnought"][i].Metadata.Version) + } + } + v := vs[0] + if v.Version != "0.2.0" { + t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version) + } + expectedDigest := "aaaa" + if v.Digest != expectedDigest { + t.Errorf("Expected merged %q digest to be %q, got %s", v.Name, expectedDigest, v.Digest) + } +} + func TestDownloadIndexFile(t *testing.T) { t.Run("should download index file", func(t *testing.T) { srv, err := startLocalServerForTests(nil)