diff --git a/internal/adapter/handlebars/handlebars.go b/internal/adapter/handlebars/handlebars.go index 6b89fa07..f1c4d80e 100644 --- a/internal/adapter/handlebars/handlebars.go +++ b/internal/adapter/handlebars/handlebars.go @@ -61,7 +61,6 @@ type LoaderOpts struct { } // NewLoader creates a new instance of Loader. -// func NewLoader(opts LoaderOpts) *Loader { return &Loader{ strings: make(map[string]*Template), diff --git a/internal/cli/container.go b/internal/cli/container.go index 8e659100..4aaf203e 100644 --- a/internal/cli/container.go +++ b/internal/cli/container.go @@ -4,7 +4,6 @@ import ( "io" "os" "path/filepath" - "strings" "github.com/zk-org/zk/internal/adapter/editor" "github.com/zk-org/zk/internal/adapter/fs" @@ -75,14 +74,9 @@ func NewContainer(version string) (*Container, error) { // Set the default notebook if not already set // might be overrided if --notebook-dir flag is present if osutil.GetOptEnv("ZK_NOTEBOOK_DIR").IsNull() && !config.Notebook.Dir.IsNull() { - // Expand in case there are environment variables on the path - notebookDir := os.Expand(config.Notebook.Dir.Unwrap(), os.Getenv) - if strings.HasPrefix(notebookDir, "~") { - dirname, err := os.UserHomeDir() - if err != nil { - return nil, wrap(err) - } - notebookDir = filepath.Join(dirname, notebookDir[1:]) + notebookDir, err := paths.ExpandPath(config.Notebook.Dir.Unwrap()) + if err != nil { + return nil, wrap(err) } os.Setenv("ZK_NOTEBOOK_DIR", notebookDir) } diff --git a/internal/core/config.go b/internal/core/config.go index d2a05e30..1425bbea 100644 --- a/internal/core/config.go +++ b/internal/core/config.go @@ -313,7 +313,7 @@ func ParseConfig(content []byte, path string, parentConfig Config, isGlobal bool config.Note.Extension = note.Extension } if note.Template != "" { - expanded, err := paths.ExpandTilde(note.Template) + expanded, err := paths.ExpandPath(note.Template) if err != nil { return config, wrap(err) } diff --git a/internal/util/paths/paths.go b/internal/util/paths/paths.go index 3c706a63..a342bc52 100644 --- a/internal/util/paths/paths.go +++ b/internal/util/paths/paths.go @@ -1,12 +1,13 @@ package paths import ( - "fmt" "os" "os/user" "path/filepath" "strings" "time" + + "github.com/zk-org/zk/internal/util/errors" ) // Metadata holds information about a file path. @@ -79,17 +80,30 @@ func WriteString(path string, content string) error { return err } -// Expands leading tilde. -func ExpandTilde(path string) (string, error) { - usr, err := user.Current() - if err != nil { - return "", fmt.Errorf("failed to determine current user") - } - home := usr.HomeDir - if path == "~" { - path = home - } else if strings.HasPrefix(path, "~/") { - path = filepath.Join(home, path[2:]) +// Expands environment variables and `~`, returning an absolute path. +func ExpandPath(path string) (string, error) { + + if strings.HasPrefix(path, "~") { + // resolve necessary variables + usr, err := user.Current() + if err != nil { + return "", err + } + home := usr.HomeDir + if home == "" { + err := errors.New("Could not find user's home directory.") + return "", err + } + + // construct as abs path + if path == "~" { + path = home + } else if strings.HasPrefix(path, "~/") { + path = filepath.Join(home, path[2:]) + } } + + path = os.ExpandEnv(path) + return path, nil } diff --git a/internal/util/paths/paths_test.go b/internal/util/paths/paths_test.go new file mode 100644 index 00000000..e62988f8 --- /dev/null +++ b/internal/util/paths/paths_test.go @@ -0,0 +1,43 @@ +package paths + +import ( + "os/user" + "strings" + "testing" + + "github.com/zk-org/zk/internal/util/test/assert" +) + +func TestExpandPath(t *testing.T) { + usr, err := user.Current() + if err != nil { + t.Error(err) + } + + test := func(path string, expected string) { + expanded, err := ExpandPath(path) + if err != nil { + t.Error(err) + } + + assert.Equal(t, expanded, expected) + } + home := usr.HomeDir + + s1 := []string{home, "foo"} + homefoo := strings.Join(s1, "/") + s2 := []string{"E.T phone", home} + etph := strings.Join(s2, " ") + + // base cases + test("~", home) + test("~/", home) + test("~/foo", homefoo) + test("${HOME}/foo", homefoo) + test("/usr/opt", "/usr/opt") + + // edge cases + test("~foo", "~foo") + test("not a path", "not a path") + test("E.T phone ${HOME}", etph) +}