Skip to content

Commit

Permalink
feat(super-flags): Add GetPath method in superflags (#258)
Browse files Browse the repository at this point in the history
Add GetPath() method on super flags. It is required because paths
needs to handled differently than normal string arguments. For example,
a path `~/abc` needs to be resolved to `/home/user/abc`.
  • Loading branch information
ahsanbarkati authored Mar 10, 2021
1 parent ecb55b4 commit a4346e5
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
34 changes: 34 additions & 0 deletions z/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package z
import (
"fmt"
"log"
"os"
"os/user"
"path/filepath"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -275,3 +278,34 @@ func (sf *SuperFlag) GetString(opt string) string {
}
return sf.m[opt]
}

func (sf *SuperFlag) GetPath(opt string) string {
p := sf.GetString(opt)
path, err := expandPath(p)
if err != nil {
log.Fatalf("Failed to get path: %+v", err)
}
return path
}

// expandPath expands the paths containing ~ to /home/user. It also computes the absolute path
// from the relative paths. For example: ~/abc/../cef will be transformed to /home/user/cef.
func expandPath(path string) (string, error) {
if len(path) == 0 {
return "", nil
}
if path[0] == '~' && (len(path) == 1 || os.IsPathSeparator(path[1])) {
usr, err := user.Current()
if err != nil {
return "", errors.Wrap(err, "Failed to get the home directory of the user")
}
path = filepath.Join(usr.HomeDir, path[1:])
}

var err error
path, err = filepath.Abs(path)
if err != nil {
return "", errors.Wrap(err, "Failed to generate absolute path")
}
return path, nil
}
50 changes: 50 additions & 0 deletions z/flags_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package z

import (
"fmt"
"os"
"os/user"
"path/filepath"
"testing"
"time"

Expand Down Expand Up @@ -37,3 +41,49 @@ func TestFlagDefault(t *testing.T) {
require.Equal(t, true, f.GetBool("one"))
require.Equal(t, int64(4), f.GetInt64("two"))
}

func TestGetPath(t *testing.T) {

usr, err := user.Current()
require.NoError(t, err)
homeDir := usr.HomeDir
cwd, err := os.Getwd()
require.NoError(t, err)

tests := []struct {
path string
expected string
}{
{
"/home/user/file.txt",
"/home/user/file.txt",
},
{
"~/file.txt",
filepath.Join(homeDir, "file.txt"),
},
{
"~/abc/../file.txt",
filepath.Join(homeDir, "file.txt"),
},
{
"~/",
homeDir,
},
{
"~filename",
filepath.Join(cwd, "~filename"),
},
}

get := func(p string) string {
opt := fmt.Sprintf("file=%s", p)
sf := NewSuperFlag(opt)
return sf.GetPath("file")
}

for _, tc := range tests {
actual := get(tc.path)
require.Equalf(t, tc.expected, actual, "Failed on testcase: %s", tc.path)
}
}

0 comments on commit a4346e5

Please sign in to comment.