Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit fcfaa20

Browse files
committed
internal/fs: add EqualPaths()
Signed-off-by: Ibrahim AshShohail <[email protected]>
1 parent 44a454b commit fcfaa20

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

context.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (c *Ctx) DetectProjectGOPATH(p *Project) (string, error) {
179179
pGOPATH, perr := c.detectGOPATH(p.AbsRoot)
180180

181181
// If p.AbsRoot is a not symlink, attempt to detect GOPATH for p.AbsRoot only.
182-
if p.AbsRoot == p.ResolvedAbsRoot {
182+
if equal, _ := fs.EqualPaths(p.AbsRoot, p.ResolvedAbsRoot); equal {
183183
return pGOPATH, perr
184184
}
185185

@@ -191,7 +191,7 @@ func (c *Ctx) DetectProjectGOPATH(p *Project) (string, error) {
191191
}
192192

193193
// If pGOPATH equals rGOPATH, then both are within the same GOPATH.
194-
if pGOPATH == rGOPATH {
194+
if equal, _ := fs.EqualPaths(pGOPATH, rGOPATH); equal {
195195
return "", errors.Errorf("both %s and %s are in the same GOPATH %s", p.AbsRoot, p.ResolvedAbsRoot, pGOPATH)
196196
}
197197

internal/fs/fs.go

+30-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,36 @@ func HasFilepathPrefix(path, prefix string) bool {
100100
return true
101101
}
102102

103+
// EqualPaths compares the paths passed to check if the are equivalent.
104+
// It respects the case-sensitivity of the underlaying filesysyems.
105+
func EqualPaths(p1, p2 string) (bool, error) {
106+
p1 = filepath.Clean(p1)
107+
p2 = filepath.Clean(p2)
108+
109+
if isDir, err := IsDir(p2); err != nil && !strings.HasSuffix(err.Error(), "is not a directory") {
110+
return false, err
111+
} else if !isDir {
112+
// If p2 is not a directory, compare the bases of the paths to ensure
113+
// they are equivalent.
114+
var p1Base, p2Base string
115+
116+
p1, p1Base = filepath.Split(p1)
117+
p2, p2Base = filepath.Split(p2)
118+
119+
if isCaseSensitiveFilesystem(p1) {
120+
if p1Base != p2Base {
121+
return false, nil
122+
}
123+
} else {
124+
if strings.ToLower(p1Base) != strings.ToLower(p2Base) {
125+
return false, nil
126+
}
127+
}
128+
}
129+
130+
return len(p1) == len(p2) && HasFilepathPrefix(p1, p2), nil
131+
}
132+
103133
// RenameWithFallback attempts to rename a file or directory, but falls back to
104134
// copying in the event of a cross-device link error. If the fallback copy
105135
// succeeds, src is still removed, emulating normal rename behavior.
@@ -336,7 +366,6 @@ func cloneSymlink(sl, dst string) error {
336366

337367
// IsDir determines is the path given is a directory or not.
338368
func IsDir(name string) (bool, error) {
339-
// TODO: lstat?
340369
fi, err := os.Stat(name)
341370
if err != nil {
342371
return false, err

internal/fs/fs_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,46 @@ func TestHasFilepathPrefix_Files(t *testing.T) {
134134
}
135135
}
136136

137+
func TestEqualPaths(t *testing.T) {
138+
h := test.NewHelper(t)
139+
h.TempDir("dir")
140+
h.TempDir("dir2")
141+
142+
h.TempFile("file", "")
143+
h.TempFile("file2", "")
144+
145+
h.TempDir("DIR")
146+
h.TempFile("FILE", "")
147+
148+
caseSensitive := isCaseSensitiveFilesystem(h.Path("dir"))
149+
150+
testcases := []struct {
151+
p1, p2 string
152+
want bool
153+
err bool
154+
}{
155+
{h.Path("dir"), h.Path("dir"), true, false},
156+
{h.Path("file"), h.Path("file"), true, false},
157+
{h.Path("dir"), h.Path("dir2"), false, false},
158+
{h.Path("file"), h.Path("file2"), false, false},
159+
{h.Path("dir"), h.Path("file"), false, false},
160+
// !caseSensitive ensures that these cases are only equivalent on a
161+
// case-insensitive filesystem.
162+
{h.Path("dir"), h.Path("DIR"), !caseSensitive, false},
163+
{strings.ToLower(h.Path("dir")), strings.ToUpper(h.Path("dir")), !caseSensitive, true},
164+
}
165+
166+
for _, tc := range testcases {
167+
got, err := EqualPaths(tc.p1, tc.p2)
168+
if err != nil && !tc.err {
169+
t.Error("unexpected error:", err)
170+
}
171+
if got != tc.want {
172+
t.Errorf("expected EqualPaths(%q, %q) to be %t, got %t", tc.p1, tc.p2, tc.want, got)
173+
}
174+
}
175+
}
176+
137177
func TestRenameWithFallback(t *testing.T) {
138178
dir, err := ioutil.TempDir("", "dep")
139179
if err != nil {

0 commit comments

Comments
 (0)