diff --git a/go.mod b/go.mod index 12e0b28e5ebd..0762bc991424 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,6 @@ require ( github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 github.com/mattn/go-colorable v0.1.13 github.com/mgechev/revive v1.5.1 - github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-ps v1.0.0 github.com/moricho/tparallel v0.3.2 github.com/nakabonne/nestif v0.3.1 diff --git a/go.sum b/go.sum index bddf925521b0..c310ad06c1e1 100644 --- a/go.sum +++ b/go.sum @@ -387,8 +387,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgechev/revive v1.5.1 h1:hE+QPeq0/wIzJwOphdVyUJ82njdd8Khp4fUIHGZHW3M= github.com/mgechev/revive v1.5.1/go.mod h1:lC9AhkJIBs5zwx8wkudyHrU+IJkrEKmpCmGMnIJPk4o= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= diff --git a/pkg/config/loader.go b/pkg/config/loader.go index 256bda8d3b55..b7fb3d43dba0 100644 --- a/pkg/config/loader.go +++ b/pkg/config/loader.go @@ -7,9 +7,9 @@ import ( "os" "path/filepath" "slices" + "strings" "github.com/go-viper/mapstructure/v2" - "github.com/mitchellh/go-homedir" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -129,9 +129,9 @@ func (l *Loader) evaluateOptions() (string, error) { return "", errConfigDisabled } - configFile, err := homedir.Expand(l.opts.Config) + configFile, err := expandHomeDir(l.opts.Config) if err != nil { - return "", errors.New("failed to expand configuration path") + return "", fmt.Errorf("failed to expand configuration path: %w", err) } return configFile, nil @@ -184,7 +184,7 @@ func (l *Loader) getConfigSearchPaths() []string { } // find home directory for global config - if home, err := homedir.Dir(); err != nil { + if home, err := os.UserHomeDir(); err != nil { l.log.Warnf("Can't get user's home directory: %v", err) } else if !slices.Contains(searchPaths, home) { searchPaths = append(searchPaths, home) @@ -473,3 +473,25 @@ func customDecoderHook() viper.DecoderConfigOption { mapstructure.TextUnmarshallerHookFunc(), )) } + +// expandHomeDir expands file paths relative to the user's home directory (~) into absolute paths. +func expandHomeDir(path string) (string, error) { + if !strings.HasPrefix(path, "~") { + return path, nil + } + + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + + if path == "~" { + return homeDir, nil + } + + if !strings.HasPrefix(path, "~"+string(filepath.Separator)) { + return "", errors.New("cannot expand user-specific home dir") + } + + return filepath.Join(homeDir, strings.TrimPrefix(path, "~")), nil +} diff --git a/pkg/config/loader_test.go b/pkg/config/loader_test.go new file mode 100644 index 000000000000..0549111a5428 --- /dev/null +++ b/pkg/config/loader_test.go @@ -0,0 +1,40 @@ +package config + +import ( + "os/user" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_expandHomeDir(t *testing.T) { + u, err := user.Current() + require.NoError(t, err) + + testCases := []struct { + path string + expected string + expectedErr bool + }{ + {path: "", expected: ""}, + {path: "~", expected: u.HomeDir}, + {path: "/foo", expected: "/foo"}, + {path: "\\foo", expected: "\\foo"}, + {path: "C:\foo", expected: "C:\foo"}, + {path: "~/foo/bar", expected: filepath.Join(u.HomeDir, "foo", "bar")}, + {path: "~foo/foo", expectedErr: true}, + } + + for _, tc := range testCases { + actual, err := expandHomeDir(tc.path) + + if tc.expectedErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tc.expected, actual) + } +}