ref(cmd/helm): remove init command

Signed-off-by: Adam Reese <adam@reese.io>
pull/6272/head
Adam Reese 6 years ago
parent b6fdd8783b
commit 1779ad5302
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

@ -33,8 +33,8 @@ import (
func TestCreateCmd(t *testing.T) { func TestCreateCmd(t *testing.T) {
defer ensure.HelmHome(t)() defer ensure.HelmHome(t)()
cname := "testchart" cname := "testchart"
os.MkdirAll(helmpath.CachePath(), 0755) dir := ensure.TempDir(t)
defer testChdir(t, helmpath.CachePath())() defer testChdir(t, dir)()
// Run a create // Run a create
if _, _, err := executeActionCommand("create " + cname); err != nil { if _, _, err := executeActionCommand("create " + cname); err != nil {

@ -35,18 +35,19 @@ func TestDependencyBuildCmd(t *testing.T) {
} }
rootDir := srv.Root() rootDir := srv.Root()
srv.LinkIndices()
chartname := "depbuild" chartname := "depbuild"
createTestingChart(t, rootDir, chartname, srv.URL()) createTestingChart(t, rootDir, chartname, srv.URL())
repoFile := filepath.Join(srv.Root(), "repositories.yaml") repoFile := filepath.Join(rootDir, "repositories.yaml")
cmd := fmt.Sprintf("dependency build '%s' --repository-config %s", filepath.Join(rootDir, chartname), repoFile) cmd := fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s", filepath.Join(rootDir, chartname), repoFile, rootDir)
_, out, err := executeActionCommand(cmd) _, out, err := executeActionCommand(cmd)
// In the first pass, we basically want the same results as an update. // In the first pass, we basically want the same results as an update.
if err != nil { if err != nil {
t.Logf("Output: %s", out) t.Logf("Output: %s", out)
t.Fatalf("%+v", err) t.Fatal(err)
} }
if !strings.Contains(out, `update from the "test" chart repository`) { if !strings.Contains(out, `update from the "test" chart repository`) {
@ -54,14 +55,14 @@ func TestDependencyBuildCmd(t *testing.T) {
} }
// Make sure the actual file got downloaded. // Make sure the actual file got downloaded.
expect := filepath.Join(srv.Root(), chartname, "charts/reqtest-0.1.0.tgz") expect := filepath.Join(rootDir, chartname, "charts/reqtest-0.1.0.tgz")
if _, err := os.Stat(expect); err != nil { if _, err := os.Stat(expect); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// In the second pass, we want to remove the chart's request dependency, // In the second pass, we want to remove the chart's request dependency,
// then see if it restores from the lock. // then see if it restores from the lock.
lockfile := filepath.Join(srv.Root(), chartname, "Chart.lock") lockfile := filepath.Join(rootDir, chartname, "Chart.lock")
if _, err := os.Stat(lockfile); err != nil { if _, err := os.Stat(lockfile); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -86,7 +87,7 @@ func TestDependencyBuildCmd(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
i, err := repo.LoadIndexFile(filepath.Join(srv.Root(), "index.yaml")) i, err := repo.LoadIndexFile(filepath.Join(rootDir, "index.yaml"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -40,21 +40,23 @@ func TestDependencyUpdateCmd(t *testing.T) {
defer srv.Stop() defer srv.Stop()
t.Logf("Listening on directory %s", srv.Root()) t.Logf("Listening on directory %s", srv.Root())
dir := srv.Root()
if err := srv.LinkIndices(); err != nil { if err := srv.LinkIndices(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
dir := func(p ...string) string {
return filepath.Join(append([]string{srv.Root()}, p...)...)
}
chartname := "depup" chartname := "depup"
ch := createTestingMetadata(chartname, srv.URL()) ch := createTestingMetadata(chartname, srv.URL())
md := ch.Metadata md := ch.Metadata
if err := chartutil.SaveDir(ch, dir); err != nil { if err := chartutil.SaveDir(ch, dir()); err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, out, err := executeActionCommand( _, out, err := executeActionCommand(
fmt.Sprintf("dependency update '%s' --repository-config %s", filepath.Join(dir, chartname), filepath.Join(dir, "repositories.yaml")), fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()),
) )
if err != nil { if err != nil {
t.Logf("Output: %s", out) t.Logf("Output: %s", out)
@ -67,7 +69,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
} }
// Make sure the actual file got downloaded. // Make sure the actual file got downloaded.
expect := filepath.Join(dir, chartname, "charts/reqtest-0.1.0.tgz") expect := dir(chartname, "charts/reqtest-0.1.0.tgz")
if _, err := os.Stat(expect); err != nil { if _, err := os.Stat(expect); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -77,7 +79,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
i, err := repo.LoadIndexFile(filepath.Join(srv.Root(), helmpath.CacheIndexFile("test"))) i, err := repo.LoadIndexFile(dir(helmpath.CacheIndexFile("test")))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -93,12 +95,11 @@ func TestDependencyUpdateCmd(t *testing.T) {
{Name: "reqtest", Version: "0.1.0", Repository: srv.URL()}, {Name: "reqtest", Version: "0.1.0", Repository: srv.URL()},
{Name: "compressedchart", Version: "0.3.0", Repository: srv.URL()}, {Name: "compressedchart", Version: "0.3.0", Repository: srv.URL()},
} }
fname := filepath.Join(dir, chartname, "Chart.yaml") if err := chartutil.SaveChartfile(dir(chartname, "Chart.yaml"), md); err != nil {
if err := chartutil.SaveChartfile(fname, md); err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s", filepath.Join(dir, chartname), filepath.Join(dir, "repositories.yaml"))) _, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
if err != nil { if err != nil {
t.Logf("Output: %s", out) t.Logf("Output: %s", out)
t.Fatal(err) t.Fatal(err)
@ -106,11 +107,11 @@ func TestDependencyUpdateCmd(t *testing.T) {
// In this second run, we should see compressedchart-0.3.0.tgz, and not // In this second run, we should see compressedchart-0.3.0.tgz, and not
// the 0.1.0 version. // the 0.1.0 version.
expect = filepath.Join(dir, chartname, "charts/compressedchart-0.3.0.tgz") expect = dir(chartname, "charts/compressedchart-0.3.0.tgz")
if _, err := os.Stat(expect); err != nil { if _, err := os.Stat(expect); err != nil {
t.Fatalf("Expected %q: %s", expect, err) t.Fatalf("Expected %q: %s", expect, err)
} }
dontExpect := filepath.Join(dir, chartname, "charts/compressedchart-0.1.0.tgz") dontExpect := dir(chartname, "charts/compressedchart-0.1.0.tgz")
if _, err := os.Stat(dontExpect); err == nil { if _, err := os.Stat(dontExpect); err == nil {
t.Fatalf("Unexpected %q", dontExpect) t.Fatalf("Unexpected %q", dontExpect)
} }
@ -147,19 +148,25 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
defer resetEnv()() defer resetEnv()()
defer ensure.HelmHome(t)() defer ensure.HelmHome(t)()
srv := repotest.NewServer(helmpath.ConfigPath()) srv, err := repotest.NewTempServer("testdata/testcharts/*.tgz")
defer srv.Stop()
copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Logf("Copied charts:\n%s", strings.Join(copied, "\n")) defer srv.Stop()
t.Logf("Listening on directory %s", srv.Root()) t.Logf("Listening on directory %s", srv.Root())
if err := srv.LinkIndices(); err != nil {
t.Fatal(err)
}
chartname := "depupdelete" chartname := "depupdelete"
createTestingChart(t, helmpath.DataPath(), chartname, srv.URL())
_, output, err := executeActionCommand(fmt.Sprintf("dependency update %s", helmpath.DataPath(chartname))) dir := func(p ...string) string {
return filepath.Join(append([]string{srv.Root()}, p...)...)
}
createTestingChart(t, dir(), chartname, srv.URL())
_, output, err := executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
if err != nil { if err != nil {
t.Logf("Output: %s", output) t.Logf("Output: %s", output)
t.Fatal(err) t.Fatal(err)
@ -168,14 +175,14 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
// Chart repo is down // Chart repo is down
srv.Stop() srv.Stop()
_, output, err = executeActionCommand(fmt.Sprintf("dependency update %s", helmpath.DataPath(chartname))) _, output, err = executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
if err == nil { if err == nil {
t.Logf("Output: %s", output) t.Logf("Output: %s", output)
t.Fatal("Expected error, got nil") t.Fatal("Expected error, got nil")
} }
// Make sure charts dir still has dependencies // Make sure charts dir still has dependencies
files, err := ioutil.ReadDir(helmpath.DataPath(chartname, "charts")) files, err := ioutil.ReadDir(filepath.Join(dir(chartname), "charts"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -191,7 +198,7 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
} }
// Make sure tmpcharts is deleted // Make sure tmpcharts is deleted
if _, err := os.Stat(helmpath.DataPath(chartname, "tmpcharts")); !os.IsNotExist(err) { if _, err := os.Stat(filepath.Join(dir(chartname), "tmpcharts")); !os.IsNotExist(err) {
t.Fatalf("tmpcharts dir still exists") t.Fatalf("tmpcharts dir still exists")
} }
} }

@ -42,11 +42,6 @@ func init() {
action.Timestamper = testTimestamper action.Timestamper = testTimestamper
} }
func TestMain(m *testing.M) {
exitCode := m.Run()
os.Exit(exitCode)
}
func runTestCmd(t *testing.T, tests []cmdTestCase) { func runTestCmd(t *testing.T, tests []cmdTestCase) {
t.Helper() t.Helper()
for _, tt := range tests { for _, tt := range tests {
@ -62,7 +57,7 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) {
t.Log("running cmd: ", tt.cmd) t.Log("running cmd: ", tt.cmd)
_, out, err := executeActionCommandC(storage, tt.cmd) _, out, err := executeActionCommandC(storage, tt.cmd)
if (err != nil) != tt.wantError { if (err != nil) != tt.wantError {
t.Errorf("expected error, got '%+v'", err) t.Errorf("expected error, got '%v'", err)
} }
if tt.golden != "" { if tt.golden != "" {
test.AssertGoldenString(t, out, tt.golden) test.AssertGoldenString(t, out, tt.golden)

@ -1,200 +0,0 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
"github.com/Masterminds/semver"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
"helm.sh/helm/cmd/helm/require"
"helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/plugin"
"helm.sh/helm/pkg/plugin/installer"
)
const initDesc = `
This command sets up local configuration.
Helm stores configuration based on the XDG base directory specification, so
- cached files are stored in $XDG_CACHE_HOME/helm
- configuration is stored in $XDG_CONFIG_HOME/helm
- data is stored in $XDG_DATA_HOME/helm
By default, the default directories depend on the Operating System. The defaults are listed below:
+------------------+---------------------------+--------------------------------+-------------------------+
| Operating System | Cache Path | Configuration Path | Data Path |
+------------------+---------------------------+--------------------------------+-------------------------+
| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm |
| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm |
| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm |
+------------------+---------------------------+--------------------------------+-------------------------+
`
type initOptions struct {
skipRefresh bool // --skip-refresh
pluginsFilename string // --plugins
}
type pluginsFileEntry struct {
URL string `json:"url"`
Version string `json:"version,omitempty"`
}
type pluginsFile struct {
Plugins []*pluginsFileEntry `json:"plugins"`
}
func newInitCmd(out io.Writer) *cobra.Command {
o := &initOptions{}
cmd := &cobra.Command{
Use: "init",
Short: "initialize Helm client",
Long: initDesc,
Args: require.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&o.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")
f.StringVar(&o.pluginsFilename, "plugins", "", "a YAML file specifying plugins to install")
return cmd
}
// run initializes local config.
func (o *initOptions) run(out io.Writer) error {
if err := ensureDirectories(out); err != nil {
return err
}
if o.pluginsFilename != "" {
if err := ensurePluginsInstalled(o.pluginsFilename, out); err != nil {
return err
}
}
fmt.Fprintln(out, "Helm is now configured to use the following directories:")
fmt.Fprintf(out, "Cache: %s\n", helmpath.CachePath())
fmt.Fprintf(out, "Configuration: %s\n", helmpath.ConfigPath())
fmt.Fprintf(out, "Data: %s\n", helmpath.DataPath())
fmt.Fprintln(out, "Happy Helming!")
return nil
}
// ensureDirectories checks to see if the directories Helm uses exists.
//
// If they do not exist, this function will create it.
func ensureDirectories(out io.Writer) error {
directories := []string{
helmpath.CachePath(),
helmpath.ConfigPath(),
helmpath.DataPath(),
helmpath.CachePath("repository"),
helmpath.DataPath("plugins"),
helmpath.CachePath("plugins"),
}
for _, p := range directories {
if fi, err := os.Stat(p); err != nil {
fmt.Fprintf(out, "Creating %s \n", p)
if err := os.MkdirAll(p, 0755); err != nil {
return errors.Wrapf(err, "could not create %s", p)
}
} else if !fi.IsDir() {
return errors.Errorf("%s must be a directory", p)
}
}
return nil
}
func ensurePluginsInstalled(pluginsFilename string, out io.Writer) error {
bytes, err := ioutil.ReadFile(pluginsFilename)
if err != nil {
return err
}
pf := new(pluginsFile)
if err := yaml.Unmarshal(bytes, &pf); err != nil {
return errors.Wrapf(err, "failed to parse %s", pluginsFilename)
}
for _, requiredPlugin := range pf.Plugins {
if err := ensurePluginInstalled(requiredPlugin, pluginsFilename, out); err != nil {
return errors.Wrapf(err, "failed to install plugin from %s", requiredPlugin.URL)
}
}
return nil
}
func ensurePluginInstalled(requiredPlugin *pluginsFileEntry, pluginsFilename string, out io.Writer) error {
i, err := installer.NewForSource(requiredPlugin.URL, requiredPlugin.Version)
if err != nil {
return err
}
if _, pathErr := os.Stat(i.Path()); os.IsNotExist(pathErr) {
if err := installer.Install(i); err != nil {
return err
}
p, err := plugin.LoadDir(i.Path())
if err != nil {
return err
}
if err := runHook(p, plugin.Install); err != nil {
return err
}
fmt.Fprintf(out, "Installed plugin: %s\n", p.Metadata.Name)
} else if requiredPlugin.Version != "" {
p, err := plugin.LoadDir(i.Path())
if err != nil {
return err
}
if p.Metadata.Version != "" {
pluginVersion, err := semver.NewVersion(p.Metadata.Version)
if err != nil {
return err
}
constraint, err := semver.NewConstraint(requiredPlugin.Version)
if err != nil {
return err
}
if !constraint.Check(pluginVersion) {
fmt.Fprintf(out, "WARNING: Installed plugin '%s' is at version %s, while %s specifies %s\n",
p.Metadata.Name, p.Metadata.Version, pluginsFilename, requiredPlugin.Version)
}
}
}
return nil
}

@ -1,57 +0,0 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"os"
"testing"
"helm.sh/helm/internal/test/ensure"
"helm.sh/helm/pkg/helmpath"
)
const testPluginsFile = "testdata/plugins.yaml"
func TestEnsureHome(t *testing.T) {
defer ensure.HelmHome(t)()
b := bytes.NewBuffer(nil)
if err := ensureDirectories(b); err != nil {
t.Error(err)
}
if err := ensurePluginsInstalled(testPluginsFile, b); err != nil {
t.Error(err)
}
expectedDirs := []string{helmpath.CachePath(), helmpath.ConfigPath(), helmpath.DataPath()}
for _, dir := range expectedDirs {
if fi, err := os.Stat(dir); err != nil {
t.Errorf("%s", err)
} else if !fi.IsDir() {
t.Errorf("%s is not a directory", fi)
}
}
if plugins, err := findPlugins(helmpath.DataPath("plugins")); err != nil {
t.Error(err)
} else if len(plugins) != 1 {
t.Errorf("Expected 1 plugin, got %d", len(plugins))
} else if plugins[0].Metadata.Name != "testplugin" {
t.Errorf("Expected %s to be installed", "testplugin")
}
}

@ -26,7 +26,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/plugin" "helm.sh/helm/pkg/plugin"
) )
@ -77,7 +76,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
// Call setupEnv before PrepareCommand because // Call setupEnv before PrepareCommand because
// PrepareCommand uses os.ExpandEnv and expects the // PrepareCommand uses os.ExpandEnv and expects the
// setupEnv vars. // setupEnv vars.
SetupPluginEnv(md.Name, plug.Dir) plugin.SetupPluginEnv(settings, md.Name, plug.Dir)
main, argv, prepCmdErr := plug.PrepareCommand(u) main, argv, prepCmdErr := plug.PrepareCommand(u)
if prepCmdErr != nil { if prepCmdErr != nil {
os.Stderr.WriteString(prepCmdErr.Error()) os.Stderr.WriteString(prepCmdErr.Error())
@ -153,27 +152,3 @@ func findPlugins(plugdirs string) ([]*plugin.Plugin, error) {
} }
return found, nil return found, nil
} }
// SetupPluginEnv prepares os.Env for plugins. It operates on os.Env because
// the plugin subsystem itself needs access to the environment variables
// created here.
func SetupPluginEnv(shortName, base string) {
for key, val := range map[string]string{
"HELM_PLUGIN_NAME": shortName,
"HELM_PLUGIN_DIR": base,
"HELM_BIN": os.Args[0],
"HELM_PLUGIN": settings.PluginsDirectory,
// Set vars that convey common information.
"HELM_PATH_REPOSITORY_FILE": settings.RepositoryConfig,
"HELM_PATH_REPOSITORY_CACHE": settings.RepositoryCache,
"HELM_PATH_STARTER": helmpath.DataPath("starters"),
"HELM_HOME": helmpath.DataPath(), // for backwards compatibility with Helm 2 plugins
} {
os.Setenv(key, val)
}
if settings.Debug {
os.Setenv("HELM_DEBUG", "1")
}
}

@ -35,11 +35,8 @@ import (
) )
func TestPackage(t *testing.T) { func TestPackage(t *testing.T) {
t.Skip("TODO")
statExe := "stat"
statFileMsg := "no such file or directory" statFileMsg := "no such file or directory"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
statExe = "FindFirstFile"
statFileMsg = "The system cannot find the file specified." statFileMsg = "The system cannot find the file specified."
} }
@ -98,13 +95,6 @@ func TestPackage(t *testing.T) {
expect: "", expect: "",
hasfile: "toot/alpine-0.1.0.tgz", hasfile: "toot/alpine-0.1.0.tgz",
}, },
{
name: "package --destination does-not-exist",
args: []string{"testdata/testcharts/alpine"},
flags: map[string]string{"destination": "does-not-exist"},
expect: fmt.Sprintf("failed to save: %s does-not-exist: %s", statExe, statFileMsg),
err: true,
},
{ {
name: "package --sign --key=KEY --keyring=KEYRING testdata/testcharts/alpine", name: "package --sign --key=KEY --keyring=KEYRING testdata/testcharts/alpine",
args: []string{"testdata/testcharts/alpine"}, args: []string{"testdata/testcharts/alpine"},
@ -137,11 +127,9 @@ func TestPackage(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
cachePath := ensure.TempDir(t)
t.Logf("Running tests in %s", cachePath)
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
cachePath := ensure.TempDir(t)
defer testChdir(t, cachePath)() defer testChdir(t, cachePath)()
if err := os.MkdirAll("toot", 0777); err != nil { if err := os.MkdirAll("toot", 0777); err != nil {

@ -59,7 +59,7 @@ func runHook(p *plugin.Plugin, event string) error {
debug("running %s hook: %s", event, prog) debug("running %s hook: %s", event, prog)
SetupPluginEnv(p.Metadata.Name, p.Dir) plugin.SetupPluginEnv(settings, p.Metadata.Name, p.Dir)
prog.Stdout, prog.Stderr = os.Stdout, os.Stderr prog.Stdout, prog.Stderr = os.Stdout, os.Stderr
if err := prog.Run(); err != nil { if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok { if eerr, ok := err.(*exec.ExitError); ok {

@ -18,14 +18,11 @@ package main
import ( import (
"bytes" "bytes"
"os" "os"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"helm.sh/helm/pkg/helmpath"
) )
func TestManuallyProcessArgs(t *testing.T) { func TestManuallyProcessArgs(t *testing.T) {
@ -62,7 +59,8 @@ func TestManuallyProcessArgs(t *testing.T) {
func TestLoadPlugins(t *testing.T) { func TestLoadPlugins(t *testing.T) {
settings.PluginsDirectory = "testdata/helmhome/helm/plugins" settings.PluginsDirectory = "testdata/helmhome/helm/plugins"
settings.RepositoryConfig = "testdata/helmhome/helm/repository" settings.RepositoryConfig = "testdata/helmhome/helm/repositories.yaml"
settings.RepositoryCache = "testdata/helmhome/helm/repository"
var ( var (
out bytes.Buffer out bytes.Buffer
@ -74,8 +72,8 @@ func TestLoadPlugins(t *testing.T) {
"fullenv", "fullenv",
"testdata/helmhome/helm/plugins/fullenv", "testdata/helmhome/helm/plugins/fullenv",
"testdata/helmhome/helm/plugins", "testdata/helmhome/helm/plugins",
"testdata/helmhome/helm/repositories.yaml",
"testdata/helmhome/helm/repository", "testdata/helmhome/helm/repository",
helmpath.CachePath("repository"),
os.Args[0], os.Args[0],
}, "\n") }, "\n")
@ -117,7 +115,7 @@ func TestLoadPlugins(t *testing.T) {
// tests until this is fixed // tests until this is fixed
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
if err := pp.RunE(pp, tt.args); err != nil { if err := pp.RunE(pp, tt.args); err != nil {
t.Errorf("Error running %s: %s", tt.use, err) t.Errorf("Error running %s: %+v", tt.use, err)
} }
if out.String() != tt.expect { if out.String() != tt.expect {
t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String()) t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String())
@ -141,21 +139,3 @@ func TestLoadPlugins_HelmNoPlugins(t *testing.T) {
t.Fatalf("Expected 0 plugins, got %d", len(plugins)) t.Fatalf("Expected 0 plugins, got %d", len(plugins))
} }
} }
func TestSetupEnv(t *testing.T) {
name := "pequod"
base := filepath.Join("testdata/helmhome/helm/plugins", name)
SetupPluginEnv(name, base)
for _, tt := range []struct {
name string
expect string
}{
{"HELM_PLUGIN_NAME", name},
{"HELM_PLUGIN_DIR", base},
} {
if got := os.Getenv(tt.name); got != tt.expect {
t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got)
}
}
}

@ -21,15 +21,12 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings"
"testing" "testing"
"helm.sh/helm/internal/test/ensure"
"helm.sh/helm/pkg/repo/repotest" "helm.sh/helm/pkg/repo/repotest"
) )
func TestPullCmd(t *testing.T) { func TestPullCmd(t *testing.T) {
t.Skip("TODO")
srv, err := repotest.NewTempServer("testdata/testcharts/*.tgz*") srv, err := repotest.NewTempServer("testdata/testcharts/*.tgz*")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -43,7 +40,7 @@ func TestPullCmd(t *testing.T) {
// all flags will get "-d outdir" appended. // all flags will get "-d outdir" appended.
tests := []struct { tests := []struct {
name string name string
args []string args string
wantError bool wantError bool
failExpect string failExpect string
expectFile string expectFile string
@ -52,47 +49,47 @@ func TestPullCmd(t *testing.T) {
}{ }{
{ {
name: "Basic chart fetch", name: "Basic chart fetch",
args: []string{"test/signtest"}, args: "test/signtest",
expectFile: "./signtest-0.1.0.tgz", expectFile: "./signtest-0.1.0.tgz",
}, },
{ {
name: "Chart fetch with version", name: "Chart fetch with version",
args: []string{"test/signtest --version=0.1.0"}, args: "test/signtest --version=0.1.0",
expectFile: "./signtest-0.1.0.tgz", expectFile: "./signtest-0.1.0.tgz",
}, },
{ {
name: "Fail chart fetch with non-existent version", name: "Fail chart fetch with non-existent version",
args: []string{"test/signtest --version=99.1.0"}, args: "test/signtest --version=99.1.0",
wantError: true, wantError: true,
failExpect: "no such chart", failExpect: "no such chart",
}, },
{ {
name: "Fail fetching non-existent chart", name: "Fail fetching non-existent chart",
args: []string{"test/nosuchthing"}, args: "test/nosuchthing",
failExpect: "Failed to fetch", failExpect: "Failed to fetch",
wantError: true, wantError: true,
}, },
{ {
name: "Fetch and verify", name: "Fetch and verify",
args: []string{"test/signtest --verify --keyring testdata/helm-test-key.pub"}, args: "test/signtest --verify --keyring testdata/helm-test-key.pub",
expectFile: "./signtest-0.1.0.tgz", expectFile: "./signtest-0.1.0.tgz",
expectVerify: true, expectVerify: true,
}, },
{ {
name: "Fetch and fail verify", name: "Fetch and fail verify",
args: []string{"test/reqtest --verify --keyring testdata/helm-test-key.pub"}, args: "test/reqtest --verify --keyring testdata/helm-test-key.pub",
failExpect: "Failed to fetch provenance", failExpect: "Failed to fetch provenance",
wantError: true, wantError: true,
}, },
{ {
name: "Fetch and untar", name: "Fetch and untar",
args: []string{"test/signtest --untar --untardir signtest"}, args: "test/signtest --untar --untardir signtest",
expectFile: "./signtest", expectFile: "./signtest",
expectDir: true, expectDir: true,
}, },
{ {
name: "Fetch, verify, untar", name: "Fetch, verify, untar",
args: []string{"test/signtest --verify --keyring=testdata/helm-test-key.pub --untar --untardir signtest"}, args: "test/signtest --verify --keyring=testdata/helm-test-key.pub --untar --untardir signtest",
expectFile: "./signtest", expectFile: "./signtest",
expectDir: true, expectDir: true,
expectVerify: true, expectVerify: true,
@ -100,37 +97,36 @@ func TestPullCmd(t *testing.T) {
{ {
name: "Chart fetch using repo URL", name: "Chart fetch using repo URL",
expectFile: "./signtest-0.1.0.tgz", expectFile: "./signtest-0.1.0.tgz",
args: []string{"signtest --repo", srv.URL()}, args: "signtest --repo " + srv.URL(),
}, },
{ {
name: "Fail fetching non-existent chart on repo URL", name: "Fail fetching non-existent chart on repo URL",
args: []string{"someChart --repo", srv.URL()}, args: "someChart --repo " + srv.URL(),
failExpect: "Failed to fetch chart", failExpect: "Failed to fetch chart",
wantError: true, wantError: true,
}, },
{ {
name: "Specific version chart fetch using repo URL", name: "Specific version chart fetch using repo URL",
expectFile: "./signtest-0.1.0.tgz", expectFile: "./signtest-0.1.0.tgz",
args: []string{"signtest --version=0.1.0 --repo", srv.URL()}, args: "signtest --version=0.1.0 --repo " + srv.URL(),
}, },
{ {
name: "Specific version chart fetch using repo URL", name: "Specific version chart fetch using repo URL",
args: []string{"signtest --version=0.2.0 --repo", srv.URL()}, args: "signtest --version=0.2.0 --repo " + srv.URL(),
failExpect: "Failed to fetch chart version", failExpect: "Failed to fetch chart version",
wantError: true, wantError: true,
}, },
} }
settings.RepositoryConfig = filepath.Join(srv.Root(), "repositories.yaml")
settings.RepositoryCache = srv.Root()
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
outdir := ensure.TempDir(t) outdir := srv.Root()
outdir = srv.Root() cmd := fmt.Sprintf("fetch %s -d '%s' --repository-config %s --repository-cache %s ",
cmd := "fetch " + strings.Join(tt.args, " ") tt.args,
cmd += fmt.Sprintf(" -d '%s' --repository-config %s --repository-cache %s ", outdir,
outdir, filepath.Join(srv.Root(), "repositories.yaml"), outdir) filepath.Join(outdir, "repositories.yaml"),
outdir,
)
_, out, err := executeActionCommand(cmd) _, out, err := executeActionCommand(cmd)
if err != nil { if err != nil {
if tt.wantError { if tt.wantError {

@ -77,8 +77,10 @@ func (o *repoRemoveOptions) run(out io.Writer) error {
func removeRepoCache(root, name string) error { func removeRepoCache(root, name string) error {
idx := filepath.Join(root, helmpath.CacheIndexFile(name)) idx := filepath.Join(root, helmpath.CacheIndexFile(name))
if _, err := os.Stat(idx); err != nil { if _, err := os.Stat(idx); os.IsNotExist(err) {
return nil return nil
} else if err != nil {
return errors.Wrapf(err, "can't remove index file %s", idx)
} }
return os.Remove(idx) return os.Remove(idx)
} }

@ -154,7 +154,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
newUpgradeCmd(actionConfig, out), newUpgradeCmd(actionConfig, out),
newCompletionCmd(out), newCompletionCmd(out),
newInitCmd(out),
newPluginCmd(out), newPluginCmd(out),
newVersionCmd(out), newVersionCmd(out),

@ -16,15 +16,12 @@ limitations under the License.
package resolver package resolver
import ( import (
"os"
"testing" "testing"
"helm.sh/helm/pkg/chart" "helm.sh/helm/pkg/chart"
"helm.sh/helm/pkg/helmpath/xdg"
) )
func TestResolve(t *testing.T) { func TestResolve(t *testing.T) {
os.Setenv(xdg.CacheHomeEnvVar, "testdata")
tests := []struct { tests := []struct {
name string name string
req []*chart.Dependency req []*chart.Dependency
@ -91,14 +88,14 @@ func TestResolve(t *testing.T) {
} }
repoNames := map[string]string{"alpine": "kubernetes-charts", "redis": "kubernetes-charts"} repoNames := map[string]string{"alpine": "kubernetes-charts", "redis": "kubernetes-charts"}
r := New("testdata/chartpath", "testdata/helm/repository") r := New("testdata/chartpath", "testdata/repository")
for _, tt := range tests { for _, tt := range tests {
l, err := r.Resolve(tt.req, repoNames) l, err := r.Resolve(tt.req, repoNames)
if err != nil { if err != nil {
if tt.err { if tt.err {
continue continue
} }
t.Fatalf("%+v", err) t.Fatal(err)
} }
if tt.err { if tt.err {

@ -21,52 +21,25 @@ import (
"os" "os"
"testing" "testing"
"helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/helmpath/xdg" "helm.sh/helm/pkg/helmpath/xdg"
) )
// HelmHome sets up a Helm Home in a temp dir. // HelmHome sets up a Helm Home in a temp dir.
func HelmHome(t *testing.T) func() { func HelmHome(t *testing.T) func() {
t.Helper() t.Helper()
cachePath := TempDir(t) base := TempDir(t)
configPath := TempDir(t) os.Setenv(xdg.CacheHomeEnvVar, base)
dataPath := TempDir(t) os.Setenv(xdg.ConfigHomeEnvVar, base)
os.Setenv(xdg.CacheHomeEnvVar, cachePath) os.Setenv(xdg.DataHomeEnvVar, base)
os.Setenv(xdg.ConfigHomeEnvVar, configPath) return func() {
os.Setenv(xdg.DataHomeEnvVar, dataPath) os.RemoveAll(base)
return HomeDirs(t)
}
var dirs = [...]string{
helmpath.CachePath(),
helmpath.ConfigPath(),
helmpath.DataPath(),
helmpath.CachePath("repository"),
}
// HomeDirs creates a home directory like ensureHome, but without remote references.
func HomeDirs(t *testing.T) func() {
return func() {}
t.Helper()
for _, p := range dirs {
if err := os.MkdirAll(p, 0755); err != nil {
t.Fatal(err)
}
}
cleanup := func() {
for _, p := range dirs {
if err := os.RemoveAll(p); err != nil {
t.Log(err)
}
}
} }
return cleanup
} }
// TempDir ensures a scratch test directory for unit testing purposes. // TempDir ensures a scratch test directory for unit testing purposes.
func TempDir(t *testing.T) string { func TempDir(t *testing.T) string {
t.Helper() t.Helper()
d, err := ioutil.TempDir("helm", "") d, err := ioutil.TempDir("", "helm")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -37,7 +37,6 @@ import (
"helm.sh/helm/pkg/downloader" "helm.sh/helm/pkg/downloader"
"helm.sh/helm/pkg/engine" "helm.sh/helm/pkg/engine"
"helm.sh/helm/pkg/getter" "helm.sh/helm/pkg/getter"
"helm.sh/helm/pkg/helmpath"
kubefake "helm.sh/helm/pkg/kube/fake" kubefake "helm.sh/helm/pkg/kube/fake"
"helm.sh/helm/pkg/release" "helm.sh/helm/pkg/release"
"helm.sh/helm/pkg/releaseutil" "helm.sh/helm/pkg/releaseutil"
@ -563,7 +562,7 @@ OUTER:
// - if path is absolute or begins with '.', error out here // - if path is absolute or begins with '.', error out here
// - URL // - URL
// //
// If 'verify' is true, this will attempt to also verify the chart. // If 'verify' was set on ChartPathOptions, this will attempt to also verify the chart.
func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (string, error) { func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (string, error) {
name = strings.TrimSpace(name) name = strings.TrimSpace(name)
version := strings.TrimSpace(c.Version) version := strings.TrimSpace(c.Version)
@ -604,12 +603,11 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (
name = chartURL name = chartURL
} }
archivePath := helmpath.CachePath("archive") if err := os.MkdirAll(settings.RepositoryCache, 0755); err != nil {
if err := os.MkdirAll(archivePath, 0744); err != nil {
return "", err return "", err
} }
filename, _, err := dl.DownloadTo(name, version, archivePath) filename, _, err := dl.DownloadTo(name, version, settings.RepositoryCache)
if err == nil { if err == nil {
lname, err := filepath.Abs(filename) lname, err := filepath.Abs(filename)
if err != nil { if err != nil {

@ -64,6 +64,8 @@ func (p *Pull) Run(chartRef string) (string, error) {
Options: []getter.Option{ Options: []getter.Option{
getter.WithBasicAuth(p.Username, p.Password), getter.WithBasicAuth(p.Username, p.Password),
}, },
RepositoryConfig: p.Settings.RepositoryConfig,
RepositoryCache: p.Settings.RepositoryCache,
} }
if p.Verify { if p.Verify {

@ -80,7 +80,7 @@ func TestCreateFrom(t *testing.T) {
srcdir := "./testdata/mariner" srcdir := "./testdata/mariner"
if err := CreateFrom(cf, tdir, srcdir); err != nil { if err := CreateFrom(cf, tdir, srcdir); err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
dir := filepath.Join(tdir, "foo") dir := filepath.Join(tdir, "foo")

@ -45,7 +45,7 @@ type EnvSettings struct {
RegistryConfig string RegistryConfig string
// RepositoryConfig is the path to the repositories file. // RepositoryConfig is the path to the repositories file.
RepositoryConfig string RepositoryConfig string
// Repositoryache is the path to the repositories cache directory. // Repositoryache is the path to the repository cache directory.
RepositoryCache string RepositoryCache string
// PluginsDirectory is the path to the plugins directory. // PluginsDirectory is the path to the plugins directory.
PluginsDirectory string PluginsDirectory string
@ -54,6 +54,9 @@ type EnvSettings struct {
func New() *EnvSettings { func New() *EnvSettings {
return &EnvSettings{ return &EnvSettings{
PluginsDirectory: helmpath.DataPath("plugins"), PluginsDirectory: helmpath.DataPath("plugins"),
RegistryConfig: helmpath.ConfigPath("registry.json"),
RepositoryConfig: helmpath.ConfigPath("repositories.yaml"),
RepositoryCache: helmpath.CachePath("repository"),
} }
} }
@ -64,9 +67,9 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use") fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use")
fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output")
fs.StringVar(&s.RegistryConfig, "registry-config", helmpath.ConfigPath("registry.json"), "path to the registry config file") fs.StringVar(&s.RegistryConfig, "registry-config", s.RegistryConfig, "path to the registry config file")
fs.StringVar(&s.RepositoryConfig, "repository-config", helmpath.ConfigPath("repositories.yaml"), "path to the repositories config file") fs.StringVar(&s.RepositoryConfig, "repository-config", s.RepositoryConfig, "path to the repositories config file")
fs.StringVar(&s.RepositoryCache, "repository-cache", helmpath.CachePath("repository"), "path to the repositories config file") fs.StringVar(&s.RepositoryCache, "repository-cache", s.RepositoryCache, "path to the repositories config file")
} }
// Init sets values from the environment. // Init sets values from the environment.

@ -24,15 +24,13 @@ import (
"helm.sh/helm/internal/test/ensure" "helm.sh/helm/internal/test/ensure"
"helm.sh/helm/pkg/cli" "helm.sh/helm/pkg/cli"
"helm.sh/helm/pkg/getter" "helm.sh/helm/pkg/getter"
"helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/helmpath/xdg"
"helm.sh/helm/pkg/repo" "helm.sh/helm/pkg/repo"
"helm.sh/helm/pkg/repo/repotest" "helm.sh/helm/pkg/repo/repotest"
) )
const ( const (
repoConfig = "testdata/helmhome/helm/repositories.yaml" repoConfig = "testdata/repositories.yaml"
repoCache = "testdata/helmhome/helm/repository" repoCache = "testdata/repository"
) )
func TestResolveChartRef(t *testing.T) { func TestResolveChartRef(t *testing.T) {
@ -196,7 +194,7 @@ func TestDownloadTo_VerifyLater(t *testing.T) {
cname := "/signtest-0.1.0.tgz" cname := "/signtest-0.1.0.tgz"
where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) where, _, err := c.DownloadTo(srv.URL()+cname, "", dest)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if expect := filepath.Join(dest, cname); where != expect { if expect := filepath.Join(dest, cname); where != expect {
@ -212,19 +210,19 @@ func TestDownloadTo_VerifyLater(t *testing.T) {
} }
func TestScanReposForURL(t *testing.T) { func TestScanReposForURL(t *testing.T) {
os.Setenv(xdg.CacheHomeEnvVar, "testdata/helmhome")
os.Setenv(xdg.ConfigHomeEnvVar, "testdata/helmhome")
c := ChartDownloader{ c := ChartDownloader{
Out: os.Stderr, Out: os.Stderr,
Verify: VerifyLater, Verify: VerifyLater,
RepositoryConfig: repoConfig, RepositoryConfig: repoConfig,
RepositoryCache: repoCache, RepositoryCache: repoCache,
Getters: getter.All(&cli.EnvSettings{}), Getters: getter.All(&cli.EnvSettings{
RepositoryConfig: repoConfig,
RepositoryCache: repoCache,
}),
} }
u := "http://example.com/alpine-0.2.0.tgz" u := "http://example.com/alpine-0.2.0.tgz"
rf, err := repo.LoadFile(helmpath.ConfigPath("repositories.yaml")) rf, err := repo.LoadFile(repoConfig)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -108,7 +108,7 @@ type Providers []Provider
// ByScheme returns a Provider that handles the given scheme. // ByScheme returns a Provider that handles the given scheme.
// //
// If no provider handles this scheme, this will return an error. // If no provider handles this scheme, this will return an error.
func (p Providers) ByScheme(scheme string, options ...Option) (Getter, error) { func (p Providers) ByScheme(scheme string) (Getter, error) {
for _, pp := range p { for _, pp := range p {
if pp.Provides(scheme) { if pp.Provides(scheme) {
return pp.New() return pp.New()

@ -17,28 +17,13 @@ package helmpath
const lp = lazypath("helm") const lp = lazypath("helm")
// ConfigPath returns the path where Helm stores configuration. // ConfigPath returns the path where Helm stores configuration.
func ConfigPath(elem ...string) string { func ConfigPath(elem ...string) string { return lp.configPath(elem...) }
return lp.configPath(elem...)
}
// CachePath returns the path where Helm stores cached objects. // CachePath returns the path where Helm stores cached objects.
func CachePath(elem ...string) string { func CachePath(elem ...string) string { return lp.cachePath(elem...) }
return lp.cachePath(elem...)
}
// DataPath returns the path where Helm stores data. // DataPath returns the path where Helm stores data.
func DataPath(elem ...string) string { func DataPath(elem ...string) string { return lp.dataPath(elem...) }
return lp.dataPath(elem...)
}
// Registry returns the path to the local registry cache.
// func Registry() string { return CachePath("registry") }
// RepositoryFile returns the path to the repositories.yaml file.
// func RepositoryFile() string { return ConfigPath("repositories.yaml") }
// RepositoryCache returns the cache path for repository metadata.
// func RepositoryCache() string { return CachePath("repository") }
// CacheIndex returns the path to an index for the given named repository. // CacheIndex returns the path to an index for the given named repository.
func CacheIndexFile(name string) string { func CacheIndexFile(name string) string {
@ -47,20 +32,3 @@ func CacheIndexFile(name string) string {
} }
return name + "index.yaml" return name + "index.yaml"
} }
func CacheIndex(name string) string {
if name != "" {
name += "-"
}
name += "index.yaml"
return CachePath("repository", name)
}
// Starters returns the path to the Helm starter packs.
// func Starters() string { return DataPath("starters") }
// PluginCache returns the cache path for plugins.
// func PluginCache() string { return CachePath("plugins") }
// Plugins returns the path to the plugins directory.
// func Plugins() string { return DataPath("plugins") }

@ -38,8 +38,6 @@ func TestHelmHome(t *testing.T) {
isEq(t, CachePath(), "/cache/helm") isEq(t, CachePath(), "/cache/helm")
isEq(t, ConfigPath(), "/config/helm") isEq(t, ConfigPath(), "/config/helm")
isEq(t, DataPath(), "/data/helm") isEq(t, DataPath(), "/data/helm")
isEq(t, CacheIndex("t"), "/cache/helm/repository/t-index.yaml")
isEq(t, CacheIndex(""), "/cache/helm/repository/index.yaml")
// test to see if lazy-loading environment variables at runtime works // test to see if lazy-loading environment variables at runtime works
os.Setenv(xdg.CacheHomeEnvVar, "/cache2") os.Setenv(xdg.CacheHomeEnvVar, "/cache2")

@ -35,8 +35,6 @@ func TestHelmHome(t *testing.T) {
isEq(t, CachePath(), "c:\\helm") isEq(t, CachePath(), "c:\\helm")
isEq(t, ConfigPath(), "d:\\helm") isEq(t, ConfigPath(), "d:\\helm")
isEq(t, DataPath(), "e:\\helm") isEq(t, DataPath(), "e:\\helm")
isEq(t, CacheIndex("t"), "c:\\helm\\repository\\t-index.yaml")
isEq(t, CacheIndex(""), "c:\\helm\\repository\\index.yaml")
// test to see if lazy-loading environment variables at runtime works // test to see if lazy-loading environment variables at runtime works
os.Setenv(xdg.CacheHomeEnvVar, "f:\\") os.Setenv(xdg.CacheHomeEnvVar, "f:\\")

@ -44,7 +44,7 @@ func TestLocalInstaller(t *testing.T) {
} }
if err := Install(i); err != nil { if err := Install(i); err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if i.Path() != helmpath.DataPath("plugins", "echo") { if i.Path() != helmpath.DataPath("plugins", "echo") {

@ -109,14 +109,15 @@ type Plugin struct {
// - If both OS and Arch match the current platform, search will stop and the command will be prepared for execution // - If both OS and Arch match the current platform, search will stop and the command will be prepared for execution
// - If OS matches and there is no more specific match, the command will be prepared for execution // - If OS matches and there is no more specific match, the command will be prepared for execution
// - If no OS/Arch match is found, return nil // - If no OS/Arch match is found, return nil
func getPlatformCommand(platformCommands []PlatformCommand) []string { func getPlatformCommand(cmds []PlatformCommand) []string {
var command []string var command []string
for _, platformCommand := range platformCommands { eq := strings.EqualFold
if strings.EqualFold(platformCommand.OperatingSystem, runtime.GOOS) { for _, c := range cmds {
command = strings.Split(os.ExpandEnv(platformCommand.Command), " ") if eq(c.OperatingSystem, runtime.GOOS) {
command = strings.Split(os.ExpandEnv(c.Command), " ")
} }
if strings.EqualFold(platformCommand.OperatingSystem, runtime.GOOS) && strings.EqualFold(platformCommand.Architecture, runtime.GOARCH) { if eq(c.OperatingSystem, runtime.GOOS) && eq(c.Architecture, runtime.GOARCH) {
return strings.Split(os.ExpandEnv(platformCommand.Command), " ") return strings.Split(os.ExpandEnv(c.Command), " ")
} }
} }
return command return command
@ -215,24 +216,20 @@ func FindPlugins(plugdirs string) ([]*Plugin, error) {
// SetupPluginEnv prepares os.Env for plugins. It operates on os.Env because // SetupPluginEnv prepares os.Env for plugins. It operates on os.Env because
// the plugin subsystem itself needs access to the environment variables // the plugin subsystem itself needs access to the environment variables
// created here. // created here.
func SetupPluginEnv(settings *cli.EnvSettings, func SetupPluginEnv(settings *cli.EnvSettings, name, base string) {
shortName, base string) {
for key, val := range map[string]string{ for key, val := range map[string]string{
"HELM_PLUGIN_NAME": shortName, "HELM_PLUGIN_NAME": name,
"HELM_PLUGIN_DIR": base, "HELM_PLUGIN_DIR": base,
"HELM_BIN": os.Args[0], "HELM_BIN": os.Args[0],
"HELM_PLUGIN": settings.PluginsDirectory, "HELM_PLUGIN": settings.PluginsDirectory,
// Set vars that convey common information. // Set vars that convey common information.
"HELM_PATH_REPOSITORY_FILE": settings.RepositoryConfig, "HELM_PATH_REPOSITORY_FILE": settings.RepositoryConfig,
"HELM_PATH_REPOSITORY_CACHE": helmpath.CachePath("repository"), "HELM_PATH_REPOSITORY_CACHE": settings.RepositoryCache,
"HELM_PATH_STARTER": helmpath.DataPath("starters"), "HELM_PATH_STARTER": helmpath.DataPath("starters"),
"HELM_HOME": helmpath.DataPath(), // for backwards compatibility with Helm 2 plugins "HELM_HOME": helmpath.DataPath(), // for backwards compatibility with Helm 2 plugins
"HELM_DEBUG": fmt.Sprint(settings.Debug),
} { } {
os.Setenv(key, val) os.Setenv(key, val)
} }
if settings.Debug {
os.Setenv("HELM_DEBUG", "1")
}
} }

@ -16,9 +16,13 @@ limitations under the License.
package plugin // import "helm.sh/helm/pkg/plugin" package plugin // import "helm.sh/helm/pkg/plugin"
import ( import (
"os"
"path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"testing" "testing"
"helm.sh/helm/pkg/cli"
) )
func checkCommand(p *Plugin, extraArgs []string, osStrCmp string, t *testing.T) { func checkCommand(p *Plugin, extraArgs []string, osStrCmp string, t *testing.T) {
@ -250,3 +254,24 @@ func TestLoadAll(t *testing.T) {
t.Errorf("Expected second plugin to be hello, got %q", plugs[1].Metadata.Name) t.Errorf("Expected second plugin to be hello, got %q", plugs[1].Metadata.Name)
} }
} }
func TestSetupEnv(t *testing.T) {
name := "pequod"
base := filepath.Join("testdata/helmhome/helm/plugins", name)
s := &cli.EnvSettings{
PluginsDirectory: "testdata/helmhome/helm/plugins",
}
SetupPluginEnv(s, name, base)
for _, tt := range []struct {
name, expect string
}{
{"HELM_PLUGIN_NAME", name},
{"HELM_PLUGIN_DIR", base},
} {
if got := os.Getenv(tt.name); got != tt.expect {
t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got)
}
}
}

@ -136,7 +136,7 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) {
return "", err return "", err
} }
fname := filepath.Join(r.CachePath, r.Config.Name+"-index.yaml") fname := filepath.Join(r.CachePath, helmpath.CacheIndexFile(r.Config.Name))
os.MkdirAll(filepath.Dir(fname), 0755) os.MkdirAll(filepath.Dir(fname), 0755)
return fname, ioutil.WriteFile(fname, index, 0644) return fname, ioutil.WriteFile(fname, index, 0644)
} }

@ -34,8 +34,6 @@ import (
"helm.sh/helm/pkg/chart" "helm.sh/helm/pkg/chart"
"helm.sh/helm/pkg/cli" "helm.sh/helm/pkg/cli"
"helm.sh/helm/pkg/getter" "helm.sh/helm/pkg/getter"
"helm.sh/helm/pkg/helmpath"
"helm.sh/helm/pkg/helmpath/xdg"
) )
const ( const (
@ -159,7 +157,7 @@ func TestIndexCustomSchemeDownload(t *testing.T) {
idx, err := repo.DownloadIndexFile() idx, err := repo.DownloadIndexFile()
if err != nil { if err != nil {
t.Fatalf("Failed to download index file to %s: %+v", idx, err) t.Fatalf("Failed to download index file to %s: %v", idx, err)
} }
if len(myCustomGetter.repoUrls) != 1 { if len(myCustomGetter.repoUrls) != 1 {
@ -303,13 +301,14 @@ func TestFindChartInRepoURL(t *testing.T) {
} }
func TestErrorFindChartInRepoURL(t *testing.T) { func TestErrorFindChartInRepoURL(t *testing.T) {
setupCacheHome(t)
_, err := FindChartInRepoURL("http://someserver/something", "nginx", "", "", "", "", getter.All(&cli.EnvSettings{})) g := getter.All(&cli.EnvSettings{
if err == nil { RepositoryCache: ensure.TempDir(t),
})
if _, err := FindChartInRepoURL("http://someserver/something", "nginx", "", "", "", "", g); err == nil {
t.Errorf("Expected error for bad chart URL, but did not get any errors") t.Errorf("Expected error for bad chart URL, but did not get any errors")
} } else if !strings.Contains(err.Error(), `looks like "http://someserver/something" is not a valid chart repository or cannot be reached: Get http://someserver/something/index.yaml`) {
if err != nil && !strings.Contains(err.Error(), `looks like "http://someserver/something" is not a valid chart repository or cannot be reached: Get http://someserver/something/index.yaml`) {
t.Errorf("Expected error for bad chart URL, but got a different error (%v)", err) t.Errorf("Expected error for bad chart URL, but got a different error (%v)", err)
} }
@ -319,27 +318,21 @@ func TestErrorFindChartInRepoURL(t *testing.T) {
} }
defer srv.Close() defer srv.Close()
_, err = FindChartInRepoURL(srv.URL, "nginx1", "", "", "", "", getter.All(&cli.EnvSettings{})) if _, err = FindChartInRepoURL(srv.URL, "nginx1", "", "", "", "", g); err == nil {
if err == nil {
t.Errorf("Expected error for chart not found, but did not get any errors") t.Errorf("Expected error for chart not found, but did not get any errors")
} } else if err.Error() != `chart "nginx1" not found in `+srv.URL+` repository` {
if err != nil && err.Error() != `chart "nginx1" not found in `+srv.URL+` repository` {
t.Errorf("Expected error for chart not found, but got a different error (%v)", err) t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
} }
_, err = FindChartInRepoURL(srv.URL, "nginx1", "0.1.0", "", "", "", getter.All(&cli.EnvSettings{})) if _, err = FindChartInRepoURL(srv.URL, "nginx1", "0.1.0", "", "", "", g); err == nil {
if err == nil {
t.Errorf("Expected error for chart not found, but did not get any errors") t.Errorf("Expected error for chart not found, but did not get any errors")
} } else if err.Error() != `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository` {
if err != nil && err.Error() != `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository` {
t.Errorf("Expected error for chart not found, but got a different error (%v)", err) t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
} }
_, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", "", "", "", "", getter.All(&cli.EnvSettings{})) if _, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", "", "", "", "", g); err == nil {
if err == nil {
t.Errorf("Expected error for no chart URLs available, but did not get any errors") t.Errorf("Expected error for no chart URLs available, but did not get any errors")
} } else if err.Error() != `chart "chartWithNoURL" has no downloadable URLs` {
if err != nil && err.Error() != `chart "chartWithNoURL" has no downloadable URLs` {
t.Errorf("Expected error for chart not found, but got a different error (%v)", err) t.Errorf("Expected error for chart not found, but got a different error (%v)", err)
} }
} }
@ -369,16 +362,3 @@ func TestResolveReferenceURL(t *testing.T) {
t.Errorf("%s", chartURL) t.Errorf("%s", chartURL)
} }
} }
func setupCacheHome(t *testing.T) {
t.Helper()
d, err := ioutil.TempDir("", "helm")
if err != nil {
t.Fatal(err)
}
os.Setenv(xdg.CacheHomeEnvVar, d)
if err := os.MkdirAll(helmpath.CachePath("repository"), 0755); err != nil {
t.Fatal(err)
}
}

@ -144,7 +144,7 @@ func TestDownloadIndexFile(t *testing.T) {
idx, err := r.DownloadIndexFile() idx, err := r.DownloadIndexFile()
if err != nil { if err != nil {
t.Fatalf("Failed to download index file to %s: %+v", idx, err) t.Fatalf("Failed to download index file to %s: %#v", idx, err)
} }
if _, err := os.Stat(idx); err != nil { if _, err := os.Stat(idx); err != nil {

@ -49,7 +49,7 @@ func LoadFile(path string) (*File, error) {
b, err := ioutil.ReadFile(path) b, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, errors.Wrapf(err, "couldn't load repositories file (%s).\nYou might need to run `helm init`", path) return nil, errors.Wrapf(err, "couldn't load repositories file (%s)", path)
} }
return nil, err return nil, err
} }

@ -183,7 +183,7 @@ func TestWriteFile(t *testing.T) {
func TestRepoNotExists(t *testing.T) { func TestRepoNotExists(t *testing.T) {
if _, err := LoadFile("/this/path/does/not/exist.yaml"); err == nil { if _, err := LoadFile("/this/path/does/not/exist.yaml"); err == nil {
t.Errorf("expected err to be non-nil when path does not exist") t.Errorf("expected err to be non-nil when path does not exist")
} else if !strings.Contains(err.Error(), "You might need to run `helm init`") { } else if !strings.Contains(err.Error(), "couldn't load repositories file") {
t.Errorf("expected prompt to run `helm init` when repositories file does not exist") t.Errorf("expected prompt `couldn't load repositories file`")
} }
} }

Loading…
Cancel
Save