diff --git a/pkg/util/errors.go b/pkg/util/errors.go new file mode 100644 index 000000000..e596a2a82 --- /dev/null +++ b/pkg/util/errors.go @@ -0,0 +1,26 @@ +/* + 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 + + https://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 util + +import "fmt" + +// ErrCantExpandTildePath returned when malformed path is passed to ExpandTilde function +type ErrCantExpandTildePath struct { + Path string +} + +func (e *ErrCantExpandTildePath) Error() string { + return fmt.Sprintf("cannot expand user-specific home dir: %s", e.Path) +} diff --git a/pkg/util/homedir.go b/pkg/util/homedir.go index de516bec5..197c4ddd0 100644 --- a/pkg/util/homedir.go +++ b/pkg/util/homedir.go @@ -14,7 +14,10 @@ package util -import "os" +import ( + "os" + "path/filepath" +) // UserHomeDir is a utility function that wraps os.UserHomeDir and returns no // errors. If the user has no home directory, the returned value will be the @@ -26,3 +29,23 @@ func UserHomeDir() string { } return homeDir } + +// ExpandTilde expands the path to include the home directory if the path +// is prefixed with `~`. If it isn't prefixed with `~`, the path is +// returned as-is. +// Original source code: https://github.com/mitchellh/go-homedir/blob/master/homedir.go#L55-L77 +func ExpandTilde(path string) (string, error) { + if len(path) == 0 { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' { + return "", &ErrCantExpandTildePath{} + } + + return filepath.Join(UserHomeDir(), path[1:]), nil +} diff --git a/pkg/util/homedir_test.go b/pkg/util/homedir_test.go index 8fd2560cf..df99f40ec 100644 --- a/pkg/util/homedir_test.go +++ b/pkg/util/homedir_test.go @@ -16,6 +16,8 @@ package util_test import ( "os" + "path" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -41,3 +43,35 @@ func setHome(path string) (resetHome func()) { os.Setenv("HOME", oldHome) } } + +func TestExpandTilde(t *testing.T) { + t.Run("success home path", func(t *testing.T) { + airshipDir := ".airship" + dir := filepath.Join("~", airshipDir) + expandedDir, err := util.ExpandTilde(dir) + assert.NoError(t, err) + homedir := path.Join(util.UserHomeDir(), airshipDir) + assert.Equal(t, homedir, expandedDir) + }) + + t.Run("success nothing to expand", func(t *testing.T) { + dir := "/home/ubuntu/.airship" + expandedDir, err := util.ExpandTilde(dir) + assert.NoError(t, err) + assert.Equal(t, dir, expandedDir) + }) + + t.Run("error malformed path", func(t *testing.T) { + malformedDir := "~.home/ubuntu/.airship" + expandedDir, err := util.ExpandTilde(malformedDir) + assert.Error(t, err) + assert.Equal(t, "", expandedDir) + }) + + t.Run("success empty path", func(t *testing.T) { + emptyDir := "" + expandedDir, err := util.ExpandTilde(emptyDir) + assert.NoError(t, err) + assert.Equal(t, emptyDir, expandedDir) + }) +}