-
Notifications
You must be signed in to change notification settings - Fork 1
/
transform.go
196 lines (176 loc) · 5.01 KB
/
transform.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package gopath
import (
"os"
"path"
"path/filepath"
)
// Append appends the given string to this GoPath.
// It doesn't use any separator, especially no slash.
//
// If this GoPath is errorneous, it returns simply this GoPath.
func (g GoPath) Append(s string) GoPath {
if g.HasErr() {
return g
}
return g.withPath(g.Path() + s)
}
// Join appends the other GoPath to this GoPath, separated by the operating
// systems path separator.
//
// If this GoPath is errorneous, it returns simply this GoPath.
func (g GoPath) Join(other GoPath) GoPath {
return g.JoinPath(other.Path())
}
// Join appends the given path to this GoPath, separated by the operating
// systmes path separator.
//
// If this GoPath is errorneous, it returns simply this GoPath.
func (g GoPath) JoinPath(p string) GoPath {
if g.HasErr() {
return g
}
return g.withPath(path.Join(g.Path(), p))
}
// Dir calls path.Dir() and returns all but the last element of this GoPath,
// typically the directory containing the file or directory this path points to.
//
// If this GoPath is errorneous, it returns simply this GoPath.
func (g GoPath) Dir() GoPath {
if g.HasErr() {
return g
}
return g.withPath(path.Dir(g.Path()))
}
// Stat calls os.Stat and caches the FileInfo result inside the returned
// GoPath.
// When the Stat call fails, an errorneous GoPath is returned.
// Stat always calls os.Stat, even if the GoPath already contains a FileInfo.
//
// Be warned: Stat() might cause an errorneous path to be returned, even in
// normal operation (e.g. file does not exist).
// An errorneous GoPath will have all operations being no-ops, so take care
// when using this function.
//
// Note, that Stat() is only useful for caching purposes.
// FileInfo() delivers the Stat() results even if Stat() was not called
// explicitly.
func (g GoPath) Stat() GoPath {
if g.HasErr() {
return g
}
if fileInfo, err := os.Stat(g.path); err != nil {
return g.withErr(err)
} else {
return g.withFileInfo(fileInfo)
}
}
// Abs calls filepath.Abs() on the path.
//
// If the path is already absolute, it returns the path itself.
// Otherwise, it returns an absolute representation of the path using the
// current working directory.
//
// If an error occurs, it returns an errorneous GoPath.
func (g GoPath) Abs() GoPath {
if g.HasErr() {
return g
}
if absPath, err := filepath.Abs(g.path); err != nil {
return g.withErr(err)
} else {
return g.withPath(absPath)
}
}
// EvalSymlinks calls filepath.EvalSymlinks().
// It evaluates any symlinks in the path.
//
// If the path is relative, the result might be relative, too.
// If an error occurs, it returns an errorneous GoPath.
func (g GoPath) EvalSymlinks() GoPath {
if g.HasErr() {
return g
}
if hardPath, err := filepath.EvalSymlinks(g.path); err != nil {
return g.withErr(err)
} else {
return g.withPath(hardPath)
}
}
// Clean calls filepath.Clean().
// It returns the shortest path equivalent to the given path.
// It might not return an errorneous GoPath, unless the given GoPath is already
// errorneous.
func (g GoPath) Clean() GoPath {
if g.HasErr() {
return g
}
return g.withPath(filepath.Clean(g.path))
}
// GlobAny runs Glob() and selects the first match.
//
// If any error occurs, it returns an errorneous GoPath.
// Note, that -- according to https://godoc.org/path/filepath#Glob --
// this may only occur when the glob expression is not formatted
// correctly.
//
// If there is no match, an empty GoPath is returned.
func (g GoPath) GlobAny() GoPath {
matches, err := g.Glob()
if err != nil {
return FromErr(err)
}
if len(matches) > 0 {
return FromPath(matches[0])
}
return Empty()
}
// Rel returns the other (targpath) GoPath, expressed as path relative to this
// GoPath.
//
// var base = gopath.FromPath("/a")
// var target = gopath.FromPath("/b/c")
// var rel = base.Rel(target)
//
// assert.Equal(rel.Path(), "../b/c")
//
// Note that this func follows the argument order of the filepath.Rel func,
// while the RelTo() func implements the reverse argument order.
func (g GoPath) Rel(targpath GoPath) GoPath {
if g.HasErr() {
return g
}
if targpath.HasErr() {
return targpath
}
var result, err = filepath.Rel(g.Path(), targpath.Path())
if err != nil {
return targpath.withErr(err)
}
return targpath.withPath(result)
}
// RelTo returns this GoPath, expressed as path relative to the other (base)
// GoPath.
//
// var base = gopath.FromPath("/a")
// var target = gopath.FromPath("/b/c")
// var rel = target.RelTo(base)
//
// assert.Equal(rel.Path(), "../b/c")
//
// Note that this func uses the inverse argument order of the filepath.Rel func,
// while the Rel() func implements the exact argument order.
func (g GoPath) RelTo(base GoPath) GoPath {
if g.HasErr() {
return g
}
return base.Rel(g)
}
// ToSlash returns the result of replacing each separator character in this
// GoPath's path with a slash ('/') character.
// This is done simply by invoking filepath's ToSlash(string) func.
func (g GoPath) ToSlash() GoPath {
if g.HasErr() {
return g
}
return g.withPath(filepath.ToSlash(g.Path()))
}