Skip to content

Commit ee1ed1f

Browse files
godreiMate Herber
authored andcommitted
Step 1212 pathutil (#141)
* Regroup pathutil functions. * Group functions in pathutil.go. * Introduce PathProvider and PathModifier. * Fix lint issue. * Regenerate pathutil mocks. * Introduce PathChecker. * Add IsPathExists to PathChecker interface. * Use default prefix for implementation structs. * Rename TempDir to CreateTempDir. * Regenerate pathutil mocks.
1 parent 0d0978a commit ee1ed1f

File tree

6 files changed

+179
-160
lines changed

6 files changed

+179
-160
lines changed

pathutil/glob.go

Lines changed: 0 additions & 13 deletions
This file was deleted.

pathutil/glob_test.go

Lines changed: 0 additions & 43 deletions
This file was deleted.

pathutil/path_filter.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@ import (
99
"strings"
1010
)
1111

12+
// ListEntries filters contents of a directory using the provided filters
13+
func ListEntries(dir string, filters ...FilterFunc) ([]string, error) {
14+
absDir, err := filepath.Abs(dir)
15+
if err != nil {
16+
return []string{}, err
17+
}
18+
19+
entries, err := ioutil.ReadDir(absDir)
20+
if err != nil {
21+
return []string{}, err
22+
}
23+
24+
var paths []string
25+
for _, entry := range entries {
26+
pth := filepath.Join(absDir, entry.Name())
27+
paths = append(paths, pth)
28+
}
29+
30+
return FilterPaths(paths, filters...)
31+
}
32+
1233
// FilterPaths ...
1334
func FilterPaths(fileList []string, filters ...FilterFunc) ([]string, error) {
1435
var filtered []string

pathutil/pathutil.go

Lines changed: 87 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -10,47 +10,34 @@ import (
1010
"strings"
1111
)
1212

13-
// RevokableChangeDir ...
14-
func RevokableChangeDir(dir string) (func() error, error) {
15-
origDir, err := CurrentWorkingDirectoryAbsolutePath()
16-
if err != nil {
17-
return nil, err
18-
}
19-
20-
revokeFn := func() error {
21-
return os.Chdir(origDir)
13+
// NormalizedOSTempDirPath ...
14+
// Creates a temp dir, and returns its path.
15+
// If tmpDirNamePrefix is provided it'll be used
16+
// as the tmp dir's name prefix.
17+
// Normalized: it's guaranteed that the path won't end with '/'.
18+
func NormalizedOSTempDirPath(tmpDirNamePrefix string) (retPth string, err error) {
19+
retPth, err = ioutil.TempDir("", tmpDirNamePrefix)
20+
if strings.HasSuffix(retPth, "/") {
21+
retPth = retPth[:len(retPth)-1]
2222
}
23-
24-
return revokeFn, os.Chdir(dir)
23+
return
2524
}
2625

27-
// ChangeDirForFunction ...
28-
func ChangeDirForFunction(dir string, fn func()) error {
29-
revokeFn, err := RevokableChangeDir(dir)
30-
if err != nil {
31-
return err
32-
}
33-
34-
fn()
35-
36-
return revokeFn()
26+
// CurrentWorkingDirectoryAbsolutePath ...
27+
func CurrentWorkingDirectoryAbsolutePath() (string, error) {
28+
return filepath.Abs("./")
3729
}
3830

39-
// IsRelativePath ...
40-
func IsRelativePath(pth string) bool {
41-
if strings.HasPrefix(pth, "./") {
42-
return true
43-
}
44-
45-
if strings.HasPrefix(pth, "/") {
46-
return false
47-
}
48-
49-
if strings.HasPrefix(pth, "$") {
50-
return false
31+
// UserHomeDir ...
32+
func UserHomeDir() string {
33+
if runtime.GOOS == "windows" {
34+
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
35+
if home == "" {
36+
home = os.Getenv("USERPROFILE")
37+
}
38+
return home
5139
}
52-
53-
return true
40+
return os.Getenv("HOME")
5441
}
5542

5643
// EnsureDirExist ...
@@ -76,12 +63,6 @@ func genericIsPathExists(pth string) (os.FileInfo, bool, error) {
7663
return fileInf, false, err
7764
}
7865

79-
// IsPathExists ...
80-
func IsPathExists(pth string) (bool, error) {
81-
_, isExists, err := genericIsPathExists(pth)
82-
return isExists, err
83-
}
84-
8566
// PathCheckAndInfos ...
8667
// Returns:
8768
// 1. file info or nil
@@ -106,6 +87,32 @@ func IsDirExists(pth string) (bool, error) {
10687
return fileInf.IsDir(), nil
10788
}
10889

90+
// IsPathExists ...
91+
func IsPathExists(pth string) (bool, error) {
92+
_, isExists, err := genericIsPathExists(pth)
93+
return isExists, err
94+
}
95+
96+
//
97+
// Path modifier functions
98+
99+
// PathModifier ...
100+
type PathModifier interface {
101+
AbsPath(pth string) (string, error)
102+
}
103+
104+
type defaultPathModifier struct{}
105+
106+
// NewPathModifier ...
107+
func NewPathModifier() PathModifier {
108+
return defaultPathModifier{}
109+
}
110+
111+
// AbsPath ...
112+
func (defaultPathModifier) AbsPath(pth string) (string, error) {
113+
return AbsPath(pth)
114+
}
115+
109116
// AbsPath expands ENV vars and the ~ character
110117
// then call Go's Abs
111118
func AbsPath(pth string) (string, error) {
@@ -150,89 +157,65 @@ func ExpandTilde(pth string) (string, error) {
150157
return pth, nil
151158
}
152159

153-
// CurrentWorkingDirectoryAbsolutePath ...
154-
func CurrentWorkingDirectoryAbsolutePath() (string, error) {
155-
return filepath.Abs("./")
156-
}
160+
// IsRelativePath ...
161+
func IsRelativePath(pth string) bool {
162+
if strings.HasPrefix(pth, "./") {
163+
return true
164+
}
157165

158-
// UserHomeDir ...
159-
func UserHomeDir() string {
160-
if runtime.GOOS == "windows" {
161-
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
162-
if home == "" {
163-
home = os.Getenv("USERPROFILE")
164-
}
165-
return home
166+
if strings.HasPrefix(pth, "/") {
167+
return false
166168
}
167-
return os.Getenv("HOME")
168-
}
169169

170-
// NormalizedOSTempDirPath ...
171-
// Creates a temp dir, and returns its path.
172-
// If tmpDirNamePrefix is provided it'll be used
173-
// as the tmp dir's name prefix.
174-
// Normalized: it's guaranteed that the path won't end with '/'.
175-
func NormalizedOSTempDirPath(tmpDirNamePrefix string) (retPth string, err error) {
176-
retPth, err = ioutil.TempDir("", tmpDirNamePrefix)
177-
if strings.HasSuffix(retPth, "/") {
178-
retPth = retPth[:len(retPth)-1]
170+
if strings.HasPrefix(pth, "$") {
171+
return false
179172
}
180-
return
173+
174+
return true
181175
}
182176

183177
// GetFileName returns the name of the file from a given path or the name of the directory if it is a directory
184178
func GetFileName(path string) string {
185179
return strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
186180
}
187181

188-
// ListPathInDirSortedByComponents ...
189-
func ListPathInDirSortedByComponents(searchDir string, relPath bool) ([]string, error) {
190-
searchDir, err := filepath.Abs(searchDir)
191-
if err != nil {
192-
return []string{}, err
193-
}
194-
195-
var fileList []string
196-
197-
if err := filepath.Walk(searchDir, func(path string, _ os.FileInfo, walkErr error) error {
198-
if walkErr != nil {
199-
return walkErr
200-
}
201-
202-
if relPath {
203-
rel, err := filepath.Rel(searchDir, path)
204-
if err != nil {
205-
return err
206-
}
207-
path = rel
182+
// EscapeGlobPath escapes a partial path, determined at runtime, used as a parameter for filepath.Glob
183+
func EscapeGlobPath(path string) string {
184+
var escaped string
185+
for _, ch := range path {
186+
if ch == '[' || ch == ']' || ch == '-' || ch == '*' || ch == '?' || ch == '\\' {
187+
escaped += "\\"
208188
}
209-
210-
fileList = append(fileList, path)
211-
212-
return nil
213-
}); err != nil {
214-
return []string{}, err
189+
escaped += string(ch)
215190
}
216-
return SortPathsByComponents(fileList)
191+
return escaped
217192
}
218193

219-
// ListEntries filters contents of a directory using the provided filters
220-
func ListEntries(dir string, filters ...FilterFunc) ([]string, error) {
221-
absDir, err := filepath.Abs(dir)
194+
//
195+
// Change dir functions
196+
197+
// RevokableChangeDir ...
198+
func RevokableChangeDir(dir string) (func() error, error) {
199+
origDir, err := CurrentWorkingDirectoryAbsolutePath()
222200
if err != nil {
223-
return []string{}, err
201+
return nil, err
224202
}
225203

226-
entries, err := ioutil.ReadDir(absDir)
227-
if err != nil {
228-
return []string{}, err
204+
revokeFn := func() error {
205+
return os.Chdir(origDir)
229206
}
230207

231-
var paths []string
232-
for _, entry := range entries {
233-
pth := filepath.Join(absDir, entry.Name())
234-
paths = append(paths, pth)
208+
return revokeFn, os.Chdir(dir)
209+
}
210+
211+
// ChangeDirForFunction ...
212+
func ChangeDirForFunction(dir string, fn func()) error {
213+
revokeFn, err := RevokableChangeDir(dir)
214+
if err != nil {
215+
return err
235216
}
236217

237-
return FilterPaths(paths, filters...)
218+
fn()
219+
220+
return revokeFn()
238221
}

pathutil/pathutil_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,46 @@ import (
1313
"github.com/stretchr/testify/require"
1414
)
1515

16+
func Test_globEscapePath(t *testing.T) {
17+
type args struct {
18+
path string
19+
}
20+
tests := []struct {
21+
name string
22+
args args
23+
want string
24+
}{
25+
{
26+
name: "Escaping test",
27+
args: args{path: "[]-?*"},
28+
want: "\\[\\]\\-\\?\\*",
29+
},
30+
// filepath.Glob(1) does not match for `test\.xcodeproj` if go version 1.8.3
31+
{
32+
name: "'.' is not escaped",
33+
args: args{path: "test.xcodeproj"},
34+
want: "test.xcodeproj",
35+
},
36+
{
37+
name: "`\\` in path",
38+
args: args{path: "\\"},
39+
want: "\\\\",
40+
},
41+
{
42+
name: "`\\` with",
43+
args: args{path: "\\[?"},
44+
want: "\\\\\\[\\?",
45+
},
46+
}
47+
for _, tt := range tests {
48+
t.Run(tt.name, func(t *testing.T) {
49+
if got := EscapeGlobPath(tt.args.path); got != tt.want {
50+
t.Errorf("globEscapePath() = %v, want %v", got, tt.want)
51+
}
52+
})
53+
}
54+
}
55+
1656
func TestChangeDirForFunction(t *testing.T) {
1757
origDir, err := CurrentWorkingDirectoryAbsolutePath()
1858
require.NoError(t, err)

0 commit comments

Comments
 (0)