-
Notifications
You must be signed in to change notification settings - Fork 1k
[WIP]: internal/fs: add EquivalentPaths function #940
Conversation
22f4852
to
fcfaa20
Compare
fcfaa20
to
0ec076d
Compare
@sdboyer I believe I found a bug in I wasted a few hours debugging why the tests for This is where it happens: // d,p are initialized with "" on *nix and volume name on Windows
d := vnPath
p := vnPrefix The next On *nix, for i := range prefixes {
// need to test each component of the path for
// case-sensitiveness because on Unix we could have
// something like ext4 filesystem mounted on FAT
// mountpoint, mounted on ext4 filesystem, i.e. the
// problematic filesystem is not the last one.
if isCaseSensitiveFilesystem(filepath.Join(d, dirs[i])) {
d = filepath.Join(d, dirs[i])
p = filepath.Join(p, prefixes[i])
} else {
d = filepath.Join(d, strings.ToLower(dirs[i]))
p = filepath.Join(p, strings.ToLower(prefixes[i]))
}
// ...
}
I've pushed a commit with my proposed fix, which is to update both |
context_test.go
Outdated
@@ -341,49 +334,49 @@ func TestDetectProjectGOPATH(t *testing.T) { | |||
{ | |||
name: "project-with-no-AbsRoot", | |||
root: "", | |||
resolvedRoot: filepath.Join(ctx.GOPATHs[0], "src", "real", "path"), | |||
resolvedRoot: filepath.Join(ctx.GOPATHs[0], "src/real/path"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why these changes? AFAIK this isn't safe for windows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sdboyer you're right, it isn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm under the impression that filepath.Join
will call filepath.Clean
which calls filepath.FromSlash
on the passed path. Am I missing something else?
Anyhow, this is a purposeless change and I can revert it. 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool, ty; yes, it does call filepath.Clean()
, but that func doesn't do separator transformations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just trying to clarify, shouldn't this line do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh. guess i'm wrong on that!
internal/fs/fs.go
Outdated
@@ -100,6 +102,53 @@ func HasFilepathPrefix(path, prefix string) bool { | |||
return true | |||
} | |||
|
|||
// EqualPaths compares the paths passed to check if the are equivalent. | |||
// It respects the case-sensitivity of the underlaying filesysyems. | |||
func EqualPaths(p1, p2 string) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EquivalentPaths
would probably be a better name here than EqualPaths
, as it emphasizes that we are testing for logically equivalent paths rather than byte-identical ones (which is the whole point!)
4c1cbbb
to
b60c5a9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just two little comment nits, then i think this is 👍 (feel free to merge once you fix those)
internal/fs/fs.go
Outdated
@@ -98,6 +102,53 @@ func HasFilepathPrefix(path, prefix string) bool { | |||
return true | |||
} | |||
|
|||
// EquivalentPaths compares the paths passed to check if the are equivalent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/if the are/if they are/
internal/fs/fs.go
Outdated
@@ -98,6 +102,53 @@ func HasFilepathPrefix(path, prefix string) bool { | |||
return true | |||
} | |||
|
|||
// EquivalentPaths compares the paths passed to check if the are equivalent. | |||
// It respects the case-sensitivity of the underlaying filesysyems. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/underlaying/underlying/
well that's some catastrophic failure on linux :( |
I figured out what's happening finally. 😓 |
7d6b41a
to
a64d6b7
Compare
Signed-off-by: Ibrahim AshShohail <[email protected]>
isCaseSensitiveFilesystem returns true when os.Stat fails on the dir passed. This caused HasFilepathPrefix to always treat *nix systems as case-sensitive, since it passed a relative path (missing the root) to isCaseSensitiveFilesystem. This commit updates isCaseSensitiveFilesystem to return an error in addtion to the boolean check. Also, HasFilepathPrefix now passes absolute paths to isCaseSensitiveFilesystem. Signed-off-by: Ibrahim AshShohail <[email protected]>
Signed-off-by: Ibrahim AshShohail <[email protected]>
Signed-off-by: Ibrahim AshShohail <[email protected]>
Signed-off-by: Ibrahim AshShohail <[email protected]>
Signed-off-by: Ibrahim AshShohail <[email protected]>
a64d6b7
to
67f83fc
Compare
@sdboyer Should we merge this? 😀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, i think this is probably good to go. (sorry, busy week). just one comment - up to you if you want to address
{th.Path("go"), filepath.Join(th.Path("go"), "src/github.com/username/package"), false}, | ||
{th.Path("gotwo"), filepath.Join(th.Path("gotwo"), "src/github.com/username/package"), false}, | ||
{"", filepath.Join(th.Path("."), "code/src/github.com/username/package"), true}, | ||
{th.Path("go"), th.Path(filepath.Join("go", "src", "github.com", "username", "package")), false}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think that after looking through, you turned out to be totally right on this - it'll convert to windows line endings automatically. i'm fine with changing it back, though it's not really necessary either
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not worth changing, to be honest. 😛
@ibrasho Could you please tell me why you are not using func EquivalentPaths(p1, p2 string) (bool, error) {
p1 = filepath.Clean(p1)
p2 = filepath.Clean(p2)
fi1, err := os.Stat(p1)
if err != nil {
return false, errors.Wrapf(err, "could not check for path equivalence")
}
fi2, err := os.Stat(p2)
if err != nil {
return false, errors.Wrapf(err, "could not check for path equivalence")
}
return os.SameFile(fi1, fi2), nil
} |
i'd swear we have a good reason for this, because we certainly knew that function existed beforehand. i can't remember that reason now, though 😢 |
Hmm.. What do you suggest we do? I can make a PR with the changes above. We can see if everything works as expected. |
no, we need to trace back over the lines of thinking that got us to here. hasty PRs in areas related to casing just lead to more headaches; "see if everything works as expected" is not something we can do, as there is no well-formed definition of "everything," let alone one codified into tests. |
Okay. At the very least, we should identify and add a test which fails for |
@sudo-suhas As Sam has said, we are trying to handle something that If I remember correctly, it has to do with nested filesystems that handle case-sensitivity differently. But I can't remember the exact case. 😕 |
* internal/fs: add EquivalentPaths * internal/fs: fix isCaseSensitiveFilesystem bug isCaseSensitiveFilesystem returns true when os.Stat fails on the dir passed. This caused HasFilepathPrefix to always treat *nix systems as case-sensitive, since it passed a relative path (missing the root) to isCaseSensitiveFilesystem. This commit updates isCaseSensitiveFilesystem to return an error in addtion to the boolean check. Also, HasFilepathPrefix now passes absolute paths to isCaseSensitiveFilesystem. Signed-off-by: Ibrahim AshShohail <[email protected]>
What does this do / why do we need it?
Add a new method to
internal/fs
to check for path equivalence.What should your reviewer look out for in this PR?
Does this work as expected?
Which issue(s) does this PR fix?
fixes #772
fixes #805