Repository: helm/helm (go)

Issue:
Helm3: list all namespaces not showing multiple releases with same name in different namespaces
I created two releases with same name in two different namespaces, and then tried to list releases in all namespaces, but only one of them showed up instead of two showing up

Output of `helm version`:
```
version.BuildInfo{Version:"v3.0.0-beta.4", GitCommit:"7ffc879f137bd3a69eea53349b01f05e3d1d2385", GitTreeState:"dirty", GoVersion:"go1.13.1"}
```

Pull request:
fix list not showing multiple releases with same name in different namespaces
**What this PR does / why we need it**:
Fixes #6658 
Twin of #6662 which got closed due to branch renaming

**Special notes for your reviewer**:

**If applicable**:
- [ ] this PR contains documentation
- [X] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility


Patch:
diff --git a/README.md b/README.md
index 91a06916a..9af358e10 100644
--- a/README.md
+++ b/README.md
@@ -20,8 +20,7 @@ Use Helm to:
 Helm is a tool that streamlines installing and managing Kubernetes applications.
 Think of it like apt/yum/homebrew for Kubernetes.
 
-- Helm has two parts: a client (`helm`) and a library
-- The library renders your templates and communicates with the Kubernetes API
+- Helm renders your templates and communicates with the Kubernetes API
 - Helm runs on your laptop, CI/CD, or wherever you want it to run.
 - Charts are Helm packages that contain at least two things:
   - A description of the package (`Chart.yaml`)
diff --git a/pkg/action/list.go b/pkg/action/list.go
index f72edc83b..4af0ef8e5 100644
--- a/pkg/action/list.go
+++ b/pkg/action/list.go
@@ -17,6 +17,7 @@ limitations under the License.
 package action
 
 import (
+	"path"
 	"regexp"
 
 	"helm.sh/helm/v3/pkg/release"
@@ -218,27 +219,23 @@ func (l *List) sort(rels []*release.Release) {
 }
 
 // filterList returns a list scrubbed of old releases.
-func filterList(rels []*release.Release) []*release.Release {
-	idx := map[string]int{}
-
-	for _, r := range rels {
-		name, version := r.Name, r.Version
-		if max, ok := idx[name]; ok {
-			// check if we have a greater version already
-			if max > version {
-				continue
-			}
+func filterList(releases []*release.Release) []*release.Release {
+	latestReleases := make(map[string]*release.Release)
+
+	for _, rls := range releases {
+		name, namespace := rls.Name, rls.Namespace
+		key := path.Join(namespace, name)
+		if latestRelease, exists := latestReleases[key]; exists && latestRelease.Version > rls.Version {
+			continue
 		}
-		idx[name] = version
+		latestReleases[key] = rls
 	}
 
-	uniq := make([]*release.Release, 0, len(idx))
-	for _, r := range rels {
-		if idx[r.Name] == r.Version {
-			uniq = append(uniq, r)
-		}
+	var list = make([]*release.Release, 0, len(latestReleases))
+	for _, rls := range latestReleases {
+		list = append(list, rls)
 	}
-	return uniq
+	return list
 }
 
 // setStateMask calculates the state mask based on parameters.


Test patch:
diff --git a/pkg/action/list_test.go b/pkg/action/list_test.go
index cab0111fd..cd86aee68 100644
--- a/pkg/action/list_test.go
+++ b/pkg/action/list_test.go
@@ -159,6 +159,7 @@ func TestList_LimitOffsetOutOfBounds(t *testing.T) {
 	is.NoError(err)
 	is.Len(list, 2)
 }
+
 func TestList_StateMask(t *testing.T) {
 	is := assert.New(t)
 	lister := newListFixture(t)
@@ -166,7 +167,8 @@ func TestList_StateMask(t *testing.T) {
 	one, err := lister.cfg.Releases.Get("one", 1)
 	is.NoError(err)
 	one.SetStatus(release.StatusUninstalled, "uninstalled")
-	lister.cfg.Releases.Update(one)
+	err = lister.cfg.Releases.Update(one)
+	is.NoError(err)
 
 	res, err := lister.Run()
 	is.NoError(err)
@@ -222,11 +224,6 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
 	three.Name = "three"
 	three.Namespace = "default"
 	three.Version = 3
-	four := releaseStub()
-	four.Name = "four"
-	four.Namespace = "default"
-	four.Version = 4
-	four.Info.Status = release.StatusSuperseded
 
 	for _, rel := range []*release.Release{one, two, three} {
 		if err := store.Create(rel); err != nil {
@@ -238,3 +235,29 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, all, 3, "sanity test: three items added")
 }
+
+func TestFilterList(t *testing.T) {
+	one := releaseStub()
+	one.Name = "one"
+	one.Namespace = "default"
+	one.Version = 1
+	two := releaseStub()
+	two.Name = "two"
+	two.Namespace = "default"
+	two.Version = 1
+	anotherOldOne := releaseStub()
+	anotherOldOne.Name = "one"
+	anotherOldOne.Namespace = "testing"
+	anotherOldOne.Version = 1
+	anotherOne := releaseStub()
+	anotherOne.Name = "one"
+	anotherOne.Namespace = "testing"
+	anotherOne.Version = 2
+
+	list := []*release.Release{one, two, anotherOne}
+	expectedFilteredList := []*release.Release{one, two, anotherOne}
+
+	filteredList := filterList(list)
+
+	assert.ElementsMatch(t, expectedFilteredList, filteredList)
+}
diff --git a/pkg/storage/driver/cfgmaps_test.go b/pkg/storage/driver/cfgmaps_test.go
index 6efd790ce..2aa38f284 100644
--- a/pkg/storage/driver/cfgmaps_test.go
+++ b/pkg/storage/driver/cfgmaps_test.go
@@ -51,7 +51,7 @@ func TestConfigMapGet(t *testing.T) {
 	}
 }
 
-func TestUNcompressedConfigMapGet(t *testing.T) {
+func TestUncompressedConfigMapGet(t *testing.T) {
 	vers := 1
 	name := "smug-pigeon"
 	namespace := "default"