From 282f918cf0c375d0b62b720bc5aa9ceaa23a0b13 Mon Sep 17 00:00:00 2001 From: Alexander Nesterenko Date: Wed, 16 Jan 2019 21:46:13 +0200 Subject: [PATCH] Decouple determining home dir to custom directory and add tests. Signed-off-by: Alexander Nesterenko --- cmd/helm/init.go | 4 +- cmd/helm/root.go | 6 +- pkg/helm/environment/environment.go | 30 ++------- pkg/helm/environment/environment_test.go | 5 +- .../helmpath/default_helm_home_dir_test.go | 53 ++++++++++++++++ pkg/helm/helmpath/default_home_dir.go | 63 +++++++++++++++++++ 6 files changed, 132 insertions(+), 29 deletions(-) create mode 100644 pkg/helm/helmpath/default_helm_home_dir_test.go create mode 100644 pkg/helm/helmpath/default_home_dir.go diff --git a/cmd/helm/init.go b/cmd/helm/init.go index ad91308d4..2c2761b09 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -36,7 +36,9 @@ import ( ) const initDesc = ` -This command sets up local configuration in $HELM_HOME (default $XDG_CONFIG_DIR/helm/). +This command sets up local configuration in $HELM_HOME (defaults to, based on system to: +$XDG_CONFIG_DIR/helm (default ~/.config/helm) on Linux, %APPDATA%\helm on Windows and +$HOME/Library/Preferences on OSX. ` const ( diff --git a/cmd/helm/root.go b/cmd/helm/root.go index dba679e93..fb7644fb0 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -26,6 +26,7 @@ import ( "k8s.io/helm/pkg/action" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/registry" + "k8s.io/helm/pkg/helm/helmpath" ) var globalUsage = `The Kubernetes package manager @@ -45,8 +46,8 @@ Common actions from this point include: Environment: $HELM_HOME set an alternative location for Helm files. By default, these are stored in - "$XDG_CONFIG_DIR/helm"" on *nix, "%APPDATA%\helm" on Windows and - "$HOME/Library/Preferences" on OSX. + "$XDG_CONFIG_DIR/helm" (defaults to ~/.config/helm) on Linux, + "%APPDATA%\helm" on Windows and "$HOME/Library/Preferences" on OSX. NOTE: if you have old-style "~/.helm" directory, it will be used, but consider moving it to a new home. $HELM_DRIVER set the backend storage driver. Values are: configmap, secret, memory @@ -66,6 +67,7 @@ func newRootCmd(c helm.Interface, actionConfig *action.Configuration, out io.Wri flags := cmd.PersistentFlags() settings.AddFlags(flags) + settings.AddHomeFlag(flags, helmpath.GetDefaultConfigHome(out)) flags.Parse(args) diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go index 73744b78b..f4f3f1c7c 100644 --- a/pkg/helm/environment/environment.go +++ b/pkg/helm/environment/environment.go @@ -23,33 +23,11 @@ These dependencies are expressed as interfaces so that alternate implementations package environment import ( - "fmt" - "github.com/casimir/xdg-go" - "os" - "path/filepath" - "github.com/spf13/pflag" - "k8s.io/client-go/util/homedir" - "k8s.io/helm/pkg/helm/helmpath" + "os" ) -var oldDefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm") -var defaultHelmHome = filepath.Join(xdg.ConfigHome(), "helm") - -// Get configuration home dir. -// -// Note: Temporal until all migrate to XDG Base Directory spec -func getDefaultConfigHome() string { - if _, err := os.Stat(defaultHelmHome); err != nil { - return defaultHelmHome - } else if _, err := os.Stat(oldDefaultHelmHome); err != nil { - return defaultHelmHome - } - fmt.Printf("WARNING: using old-style configuration directiry. Please, consider moving it to %s\n", defaultHelmHome) - return oldDefaultHelmHome -} - // EnvSettings describes all of the environment settings. type EnvSettings struct { // Home is the local path to the Helm home directory. @@ -66,13 +44,17 @@ type EnvSettings struct { // AddFlags binds flags to the given flagset. func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) { - fs.StringVar((*string)(&s.Home), "home", getDefaultConfigHome(), "location of your Helm config. Overrides $HELM_HOME") fs.StringVarP(&s.Namespace, "namespace", "n", "", "namespace scope for this request") fs.StringVar(&s.KubeConfig, "kubeconfig", "", "path to the kubeconfig file") fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") } +// Binds home flag. +func (s *EnvSettings) AddHomeFlag(fs *pflag.FlagSet, defaultHomePath string) { + fs.StringVar((*string)(&s.Home), "home", defaultHomePath, "location of your Helm config. Overrides $HELM_HOME") +} + // Init sets values from the environment. func (s *EnvSettings) Init(fs *pflag.FlagSet) { for name, envar := range envMap { diff --git a/pkg/helm/environment/environment_test.go b/pkg/helm/environment/environment_test.go index f54127c6d..3cba11827 100644 --- a/pkg/helm/environment/environment_test.go +++ b/pkg/helm/environment/environment_test.go @@ -40,8 +40,8 @@ func TestEnvSettings(t *testing.T) { }{ { name: "defaults", - home: defaultHelmHome, - plugins: helmpath.Home(defaultHelmHome).Plugins(), + home: "~/.helm", + plugins: helmpath.Home("~/.helm").Plugins(), ns: "", }, { @@ -83,6 +83,7 @@ func TestEnvSettings(t *testing.T) { settings := &EnvSettings{} settings.AddFlags(flags) + settings.AddHomeFlag(flags, "~/.helm") flags.Parse(strings.Split(tt.args, " ")) settings.Init(flags) diff --git a/pkg/helm/helmpath/default_helm_home_dir_test.go b/pkg/helm/helmpath/default_helm_home_dir_test.go new file mode 100644 index 000000000..2b2c30710 --- /dev/null +++ b/pkg/helm/helmpath/default_helm_home_dir_test.go @@ -0,0 +1,53 @@ +// 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 helmpath + +import ( + "os" + "runtime" + "testing" +) + +func StringEquals(t *testing.T, a, b string) { + if a != b { + t.Error(runtime.GOOS) + t.Errorf("Expected %q, got %q", a, b) + } +} + +func returns(what bool) func() bool { return func() bool { return what } } + +func TestGetDefaultConfigHome(t *testing.T) { + var _OldDefaultHelmHomeExists = OldDefaultHelmHomeExists + var _DefaultHelmHomeExists = DefaultHelmHomeExists + + OldDefaultHelmHomeExists = returns(false) + DefaultHelmHomeExists = returns(false) + StringEquals(t, GetDefaultConfigHome(os.Stdout), defaultHelmHome) + + OldDefaultHelmHomeExists = returns(true) + DefaultHelmHomeExists = returns(false) + StringEquals(t, GetDefaultConfigHome(os.Stdout), oldDefaultHelmHome) + + OldDefaultHelmHomeExists = returns(false) + DefaultHelmHomeExists = returns(true) + StringEquals(t, GetDefaultConfigHome(os.Stdout), defaultHelmHome) + + OldDefaultHelmHomeExists = returns(true) + DefaultHelmHomeExists = returns(true) + StringEquals(t, GetDefaultConfigHome(os.Stdout), defaultHelmHome) + + OldDefaultHelmHomeExists = _OldDefaultHelmHomeExists + DefaultHelmHomeExists = _DefaultHelmHomeExists +} diff --git a/pkg/helm/helmpath/default_home_dir.go b/pkg/helm/helmpath/default_home_dir.go new file mode 100644 index 000000000..daea8c9fb --- /dev/null +++ b/pkg/helm/helmpath/default_home_dir.go @@ -0,0 +1,63 @@ +/* +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 helmpath + +import ( + "fmt" + "github.com/casimir/xdg-go" + "io" + "k8s.io/client-go/util/homedir" + "os" + "path/filepath" +) + +// Old default helm home, it's old good ~/.helm +var oldDefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm") + +// New default helm home, with different paths for different OS: +// - %APPDATA%\helm on Windows +// - ~/Library/Preferences/helm on OSX +// - $XDG_CONFIG_DIR/helm (typically ~/.config/helm for linux) +var defaultHelmHome = filepath.Join(xdg.ConfigHome(), "helm") + +func DirExists(path string) bool { + osStat, err := os.Stat(path) + return err == nil && osStat.IsDir() +} + +// Check whether new default helm home exists +// TODO: improve me +var DefaultHelmHomeExists = func() bool { + return DirExists(defaultHelmHome) +} + +// Checks whether old-style ~/.helm exists +// TODO: improve me +var OldDefaultHelmHomeExists = func() bool { + return DirExists(oldDefaultHelmHome) +} + +// Get configuration home dir. +// +// Note: Temporal until all migrate to XDG Base Directory spec +func GetDefaultConfigHome(out io.Writer) string { + if DefaultHelmHomeExists() || !OldDefaultHelmHomeExists() { + return defaultHelmHome + } + fmt.Fprintf(out, "WARNING: using old-style configuration directory. Please, consider moving it to %s\n", defaultHelmHome) + return oldDefaultHelmHome +}