-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath.go
119 lines (91 loc) · 2.22 KB
/
path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package gokit
import (
"os"
"path/filepath"
"runtime"
"strings"
)
type PathFn func() (path string, err error)
type xPath struct {
//
}
func (x xPath) Delim() string {
return string([]rune{os.PathSeparator})
}
func (x xPath) Join(paths ...any) string {
delim := x.Delim()
return JoinFunc(delim, paths, func(v string) string {
v = strings.TrimPrefix(v, delim)
v = strings.TrimSuffix(v, delim)
return v
})
}
func (x xPath) JoinPrefixed(paths ...any) string {
result := x.Join(paths...)
return x.Delim() + result
}
func (x xPath) FromExecutable(paths ...any) (file string, err error) {
return x.get(
x.getExecPathFromArgs(paths...),
x.getExecPathFromCaller(0, paths...),
x.getExecPathFromCaller(1, paths...),
x.getExecPathFromSource(paths...),
)
}
func (x xPath) IsDir(file string) bool {
info, err := os.Stat(file)
if os.IsNotExist(err) {
return false
}
return info.IsDir()
}
func (x xPath) IsFile(file string) bool {
info, err := os.Stat(file)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
func (x xPath) get(fns ...PathFn) (path string, err error) {
for _, fn := range fns {
path, err = fn()
if err != nil {
continue
}
if x.IsFile(path) {
break
}
}
return
}
func (x xPath) getExecPathFromCaller(skip int, paths ...any) PathFn {
return func() (path string, err error) {
_, file, _, _ := runtime.Caller(skip)
return x.getAbsolutePathFromFile(file, paths...)
}
}
func (x xPath) getExecPathFromArgs(paths ...any) PathFn {
return func() (path string, err error) {
return x.getAbsolutePathFromFile(os.Args[0], paths...)
}
}
func (x xPath) getExecPathFromSource(paths ...any) PathFn {
return func() (path string, err error) {
return x.getAbsolutePathFromDir("./", paths...)
}
}
func (x xPath) getAbsolutePathFromFile(fromFile string, paths ...any) (path string, err error) {
dir := filepath.Dir(fromFile)
return x.getAbsolutePathFromDir(dir, paths...)
}
func (x xPath) getAbsolutePathFromDir(dir string, paths ...any) (path string, err error) {
if dir, err = filepath.Abs(dir); err != nil {
return
}
allPaths := append([]any{dir}, paths...)
path = x.Join(allPaths...)
path = x.sanitize(path)
return
}
// ================================
var Path xPath