Repository: helm/helm (go)

Issue:
[Helm 3] helm package requires argument
<!-- If you need help or think you have found a bug, please help us with your issue by entering the following information (otherwise you can delete this text): -->

According to the description for `helm package`:

> If no path is given, this will look in the present working directory for a
Chart.yaml file, and (if found) build the current directory into a chart.

But this is not the case, shown by running `helm package`:
```
Error: need at least one argument, the path to the chart
```

Recommended solution, rather than throwing an error if no args are provided, append to `args`:
```
if len(args) == 0 {
  args = append(args, ".")
}
```

Should be an easy enough PR. 😉 Only one change to the tests should be needed. I don't have `golangci-lint`, so I couldn't run the tests locally.

Output of `helm version`:
```
version.BuildInfo{Version:"v3.0.0", GitCommit:"e29ce2a54e96cd02ccfce88bee4f58bb6e2a28b6", GitTreeState:"clean", GoVersion:"go1.13.4"}
```

Output of `kubectl version`: N/A

Cloud Provider/Platform (AKS, GKE, Minikube etc.): N/A




Pull request:
fix this inconsistency in the docs
fix #7155 

fix this inconsistency in the docs

Patch:
diff --git a/cmd/helm/package.go b/cmd/helm/package.go
index dd4bb2d17..f82c0950d 100644
--- a/cmd/helm/package.go
+++ b/cmd/helm/package.go
@@ -36,9 +36,6 @@ This command packages a chart into a versioned chart archive file. If a path
 is given, this will look at that path for a chart (which must contain a
 Chart.yaml file) and then package that directory.
 
-If no path is given, this will look in the present working directory for a
-Chart.yaml file, and (if found) build the current directory into a chart.
-
 Versioned chart archives are used by Helm package repositories.
 `
 
diff --git a/code-of-conduct.md b/code-of-conduct.md
index 0d15c00cf..91ccaf035 100644
--- a/code-of-conduct.md
+++ b/code-of-conduct.md
@@ -1,3 +1,3 @@
-# Kubernetes Community Code of Conduct
+# Community Code of Conduct
 
-Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)
+Helm follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
diff --git a/pkg/action/get_values.go b/pkg/action/get_values.go
index 5bc3a7005..9c32db213 100644
--- a/pkg/action/get_values.go
+++ b/pkg/action/get_values.go
@@ -39,6 +39,10 @@ func NewGetValues(cfg *Configuration) *GetValues {
 
 // Run executes 'helm get values' against the given release.
 func (g *GetValues) Run(name string) (map[string]interface{}, error) {
+	if err := g.cfg.KubeClient.IsReachable(); err != nil {
+		return nil, err
+	}
+
 	rel, err := g.cfg.releaseContent(name, g.Version)
 	if err != nil {
 		return nil, err
diff --git a/pkg/action/pull.go b/pkg/action/pull.go
index aaf63861e..b0a3d2598 100644
--- a/pkg/action/pull.go
+++ b/pkg/action/pull.go
@@ -63,6 +63,7 @@ func (p *Pull) Run(chartRef string) (string, error) {
 		Getters: getter.All(p.Settings),
 		Options: []getter.Option{
 			getter.WithBasicAuth(p.Username, p.Password),
+			getter.WithTLSClientConfig(p.CertFile, p.KeyFile, p.CaFile),
 		},
 		RepositoryConfig: p.Settings.RepositoryConfig,
 		RepositoryCache:  p.Settings.RepositoryCache,
diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go
index 8e251bc89..f3d4321c5 100644
--- a/pkg/downloader/chart_downloader.go
+++ b/pkg/downloader/chart_downloader.go
@@ -214,6 +214,10 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, er
 		c.Options = append(c.Options, getter.WithBasicAuth(r.Config.Username, r.Config.Password))
 	}
 
+	if r.Config.CertFile != "" || r.Config.KeyFile != "" || r.Config.CAFile != "" {
+		c.Options = append(c.Options, getter.WithTLSClientConfig(r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile))
+	}
+
 	// Next, we need to load the index, and actually look up the chart.
 	idxFile := filepath.Join(c.RepositoryCache, helmpath.CacheIndexFile(r.Config.Name))
 	i, err := repo.LoadIndexFile(idxFile)
diff --git a/pkg/lint/rules/chartfile.go b/pkg/lint/rules/chartfile.go
index 35bb81571..70cb83bc5 100644
--- a/pkg/lint/rules/chartfile.go
+++ b/pkg/lint/rules/chartfile.go
@@ -46,7 +46,6 @@ func Chartfile(linter *support.Linter) {
 	}
 
 	linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartName(chartFile))
-	linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartNameDirMatch(linter.ChartDir, chartFile))
 
 	// Chart metadata
 	linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartAPIVersion(chartFile))
@@ -82,13 +81,6 @@ func validateChartName(cf *chart.Metadata) error {
 	return nil
 }
 
-func validateChartNameDirMatch(chartDir string, cf *chart.Metadata) error {
-	if cf.Name != filepath.Base(chartDir) {
-		return errors.Errorf("directory name (%s) and chart name (%s) must be the same", filepath.Base(chartDir), cf.Name)
-	}
-	return nil
-}
-
 func validateChartAPIVersion(cf *chart.Metadata) error {
 	if cf.APIVersion == "" {
 		return errors.New("apiVersion is required. The value must be either \"v1\" or \"v2\"")


Test patch:
diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go
index 80249e240..e0692c8c8 100644
--- a/pkg/downloader/chart_downloader_test.go
+++ b/pkg/downloader/chart_downloader_test.go
@@ -80,6 +80,67 @@ func TestResolveChartRef(t *testing.T) {
 	}
 }
 
+func TestResolveChartOpts(t *testing.T) {
+	tests := []struct {
+		name, ref, version string
+		expect             []getter.Option
+	}{
+		{
+			name: "repo with CA-file",
+			ref:  "testing-ca-file/foo",
+			expect: []getter.Option{
+				getter.WithURL("https://example.com/foo-1.2.3.tgz"),
+				getter.WithTLSClientConfig("cert", "key", "ca"),
+			},
+		},
+	}
+
+	c := ChartDownloader{
+		Out:              os.Stderr,
+		RepositoryConfig: repoConfig,
+		RepositoryCache:  repoCache,
+		Getters: getter.All(&cli.EnvSettings{
+			RepositoryConfig: repoConfig,
+			RepositoryCache:  repoCache,
+		}),
+	}
+
+	// snapshot options
+	snapshotOpts := c.Options
+
+	for _, tt := range tests {
+		// reset chart downloader options for each test case
+		c.Options = snapshotOpts
+
+		expect, err := getter.NewHTTPGetter(tt.expect...)
+		if err != nil {
+			t.Errorf("%s: failed to setup http client: %s", tt.name, err)
+			continue
+		}
+
+		u, err := c.ResolveChartVersion(tt.ref, tt.version)
+		if err != nil {
+			t.Errorf("%s: failed with error %s", tt.name, err)
+			continue
+		}
+
+		got, err := getter.NewHTTPGetter(
+			append(
+				c.Options,
+				getter.WithURL(u.String()),
+			)...,
+		)
+		if err != nil {
+			t.Errorf("%s: failed to create http client: %s", tt.name, err)
+			continue
+		}
+
+		if *(got.(*getter.HTTPGetter)) != *(expect.(*getter.HTTPGetter)) {
+			t.Errorf("%s: expected %s, got %s", tt.name, expect, got)
+		}
+	}
+}
+
 func TestVerifyChart(t *testing.T) {
 	v, err := VerifyChart("testdata/signtest-0.1.0.tgz", "testdata/helm-test-key.pub")
 	if err != nil {
diff --git a/pkg/downloader/testdata/repositories.yaml b/pkg/downloader/testdata/repositories.yaml
index 374d95c8a..430865269 100644
--- a/pkg/downloader/testdata/repositories.yaml
+++ b/pkg/downloader/testdata/repositories.yaml
@@ -15,4 +15,9 @@ repositories:
   - name: testing-relative
     url: "http://example.com/helm"
   - name: testing-relative-trailing-slash
-    url: "http://example.com/helm/"
\ No newline at end of file
+    url: "http://example.com/helm/"
+  - name: testing-ca-file
+    url: "https://example.com"
+    certFile: "cert"
+    keyFile: "key"
+    caFile: "ca"
diff --git a/pkg/downloader/testdata/repository/testing-ca-file-index.yaml b/pkg/downloader/testdata/repository/testing-ca-file-index.yaml
new file mode 100644
index 000000000..17cdde1c6
--- /dev/null
+++ b/pkg/downloader/testdata/repository/testing-ca-file-index.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+entries:
+  foo:
+    - name: foo
+      description: Foo Chart
+      home: https://helm.sh/helm
+      keywords: []
+      maintainers: []
+      sources:
+        - https://github.com/helm/charts
+      urls:
+        - https://example.com/foo-1.2.3.tgz
+      version: 1.2.3
+      checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
diff --git a/pkg/lint/lint_test.go b/pkg/lint/lint_test.go
index b770704c6..2a982d088 100644
--- a/pkg/lint/lint_test.go
+++ b/pkg/lint/lint_test.go
@@ -35,12 +35,12 @@ const goodChartDir = "rules/testdata/goodone"
 
 func TestBadChart(t *testing.T) {
 	m := All(badChartDir, values, namespace, strict).Messages
-	if len(m) != 8 {
+	if len(m) != 7 {
 		t.Errorf("Number of errors %v", len(m))
 		t.Errorf("All didn't fail with expected errors, got %#v", m)
 	}
 	// There should be one INFO, 2 WARNINGs and one ERROR messages, check for them
-	var i, w, e, e2, e3, e4, e5, e6 bool
+	var i, w, e, e2, e3, e4, e5 bool
 	for _, msg := range m {
 		if msg.Severity == support.InfoSev {
 			if strings.Contains(msg.Err.Error(), "icon is recommended") {
@@ -59,24 +59,21 @@ func TestBadChart(t *testing.T) {
 			if strings.Contains(msg.Err.Error(), "name is required") {
 				e2 = true
 			}
-			if strings.Contains(msg.Err.Error(), "directory name (badchartfile) and chart name () must be the same") {
-				e3 = true
-			}
 
 			if strings.Contains(msg.Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") {
-				e4 = true
+				e3 = true
 			}
 
 			if strings.Contains(msg.Err.Error(), "chart type is not valid in apiVersion") {
-				e5 = true
+				e4 = true
 			}
 
 			if strings.Contains(msg.Err.Error(), "dependencies are not valid in the Chart file with apiVersion") {
-				e6 = true
+				e5 = true
 			}
 		}
 	}
-	if !e || !e2 || !e3 || !e4 || !e5 || !e6 || !w || !i {
+	if !e || !e2 || !e3 || !e4 || !e5 || !w || !i {
 		t.Errorf("Didn't find all the expected errors, got %#v", m)
 	}
 }
diff --git a/pkg/lint/rules/chartfile_test.go b/pkg/lint/rules/chartfile_test.go
index ff2a63583..d032dd12f 100644
--- a/pkg/lint/rules/chartfile_test.go
+++ b/pkg/lint/rules/chartfile_test.go
@@ -30,18 +30,15 @@ import (
 )
 
 const (
-	badChartDir  = "testdata/badchartfile"
-	goodChartDir = "testdata/goodone"
+	badChartDir = "testdata/badchartfile"
 )
 
 var (
 	badChartFilePath         = filepath.Join(badChartDir, "Chart.yaml")
-	goodChartFilePath        = filepath.Join(goodChartDir, "Chart.yaml")
 	nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
 )
 
 var badChart, _ = chartutil.LoadChartfile(badChartFilePath)
-var goodChart, _ = chartutil.LoadChartfile(goodChartFilePath)
 
 // Validation functions Test
 func TestValidateChartYamlNotDirectory(t *testing.T) {
@@ -73,24 +70,6 @@ func TestValidateChartName(t *testing.T) {
 	}
 }
 
-func TestValidateChartNameDirMatch(t *testing.T) {
-	err := validateChartNameDirMatch(goodChartDir, goodChart)
-	if err != nil {
-		t.Errorf("validateChartNameDirMatch to return no error, gor a linter error")
-	}
-	// It has not name
-	err = validateChartNameDirMatch(badChartDir, badChart)
-	if err == nil {
-		t.Errorf("validatechartnamedirmatch to return a linter error, got no error")
-	}
-
-	// Wrong path
-	err = validateChartNameDirMatch(badChartDir, goodChart)
-	if err == nil {
-		t.Errorf("validatechartnamedirmatch to return a linter error, got no error")
-	}
-}
-
 func TestValidateChartVersion(t *testing.T) {
 	var failTest = []struct {
 		Version  string
@@ -209,36 +188,32 @@ func TestChartfile(t *testing.T) {
 	Chartfile(&linter)
 	msgs := linter.Messages
 
-	if len(msgs) != 7 {
-		t.Errorf("Expected 7 errors, got %d", len(msgs))
+	if len(msgs) != 6 {
+		t.Errorf("Expected 6 errors, got %d", len(msgs))
 	}
 
 	if !strings.Contains(msgs[0].Err.Error(), "name is required") {
 		t.Errorf("Unexpected message 0: %s", msgs[0].Err)
 	}
 
-	if !strings.Contains(msgs[1].Err.Error(), "directory name (badchartfile) and chart name () must be the same") {
+	if !strings.Contains(msgs[1].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") {
 		t.Errorf("Unexpected message 1: %s", msgs[1].Err)
 	}
 
-	if !strings.Contains(msgs[2].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") {
+	if !strings.Contains(msgs[2].Err.Error(), "version '0.0.0.0' is not a valid SemVer") {
 		t.Errorf("Unexpected message 2: %s", msgs[2].Err)
 	}
 
-	if !strings.Contains(msgs[3].Err.Error(), "version '0.0.0.0' is not a valid SemVer") {
+	if !strings.Contains(msgs[3].Err.Error(), "icon is recommended") {
 		t.Errorf("Unexpected message 3: %s", msgs[3].Err)
 	}
 
-	if !strings.Contains(msgs[4].Err.Error(), "icon is recommended") {
+	if !strings.Contains(msgs[4].Err.Error(), "chart type is not valid in apiVersion") {
 		t.Errorf("Unexpected message 4: %s", msgs[4].Err)
 	}
 
-	if !strings.Contains(msgs[5].Err.Error(), "chart type is not valid in apiVersion") {
+	if !strings.Contains(msgs[5].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") {
 		t.Errorf("Unexpected message 5: %s", msgs[5].Err)
 	}
 
-	if !strings.Contains(msgs[6].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") {
-		t.Errorf("Unexpected message 6: %s", msgs[6].Err)
-	}
-
 }