From 3137bb2605265533ee0c6c6bce51a676c7def5b5 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 12 Jan 2021 22:36:31 +0000 Subject: [PATCH 1/3] Handle Windows 8.3 paths in EquivalentTo method --- paths.go | 19 +++++++++++++------ paths_test.go | 8 ++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/paths.go b/paths.go index 6a9578f..b20953e 100644 --- a/paths.go +++ b/paths.go @@ -524,15 +524,22 @@ func (p *Path) EquivalentTo(other *Path) bool { if p.Clean().path == other.Clean().path { return true } - absP, err := p.Abs() - if err != nil { - return false + + if infoP, err := p.Stat(); err != nil { + // go ahead with the next test... + } else if infoOther, err := other.Stat(); err != nil { + // go ahead with the next test... + } else if os.SameFile(infoP, infoOther) { + return true } - absOther, err := other.Abs() - if err != nil { + + if absP, err := p.Abs(); err != nil { + return false + } else if absOther, err := other.Abs(); err != nil { return false + } else { + return absP.path == absOther.path } - return absP.path == absOther.path } // Parents returns all the parents directories of the current path. If the path is absolute diff --git a/paths_test.go b/paths_test.go index 38ee8cd..8a25983 100644 --- a/paths_test.go +++ b/paths_test.go @@ -31,6 +31,7 @@ package paths import ( "path/filepath" + "runtime" "strings" "testing" @@ -311,6 +312,13 @@ func TestEquivalentPaths(t *testing.T) { require.True(t, New("file1", "abc").EquivalentTo(New("file1", "abc", "def", ".."))) require.True(t, wd.Join("file1").EquivalentTo(New("file1"))) require.True(t, wd.Join("file1").EquivalentTo(New("file1", "abc", ".."))) + + if runtime.GOOS == "windows" { + q := New("_testdata", "anotherFile") + r := New("_testdata", "ANOTHE~1") + require.True(t, q.EquivalentTo(r)) + require.True(t, r.EquivalentTo(q)) + } } func TestRelativeTo(t *testing.T) { From 1dcf6989b5bf59abdf38bde94f6dd8d09f621d88 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 12 Jan 2021 22:56:15 +0000 Subject: [PATCH 2/3] Added Canonical method --- paths.go | 15 +++++++++++++++ paths_test.go | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/paths.go b/paths.go index b20953e..c242a91 100644 --- a/paths.go +++ b/paths.go @@ -564,3 +564,18 @@ func (p *Path) Parents() []*Path { func (p *Path) String() string { return p.path } + +// Canonical return a "canonical" Path for the given filename. +// The meaning of "canonical" is OS-dependent but the goal of this method +// is to always return the same path for a given file (factoring out all the +// possibile ambiguities including, for example, relative paths traversal, +// symlinks, drive volume letter case, etc). +func (p *Path) Canonical() *Path { + canonical := p.Clone() + // https://github.com/golang/go/issues/17084#issuecomment-246645354 + canonical.FollowSymLink() + if absPath, err := canonical.Abs(); err == nil { + canonical = absPath + } + return canonical +} diff --git a/paths_test.go b/paths_test.go index 8a25983..9f7ef55 100644 --- a/paths_test.go +++ b/paths_test.go @@ -321,6 +321,25 @@ func TestEquivalentPaths(t *testing.T) { } } +func TestCanonicalize(t *testing.T) { + wd, err := Getwd() + require.NoError(t, err) + + p := New("_testdata", "anotherFile").Canonical() + require.Equal(t, wd.Join("_testdata", "anotherFile").String(), p.String()) + + p = New("_testdata", "nonexistentFile").Canonical() + require.Equal(t, wd.Join("_testdata", "nonexistentFile").String(), p.String()) + + if runtime.GOOS == "windows" { + q := New("_testdata", "ANOTHE~1").Canonical() + require.Equal(t, wd.Join("_testdata", "anotherFile").String(), q.String()) + + r := New("c:\\").Canonical() + require.Equal(t, "C:\\", r.String()) + } +} + func TestRelativeTo(t *testing.T) { res, err := New("/my/abs/path/123/456").RelTo(New("/my/abs/path")) require.NoError(t, err) From ad24217e4f69a1c33216bf7c25f2aff256c1f99e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Jan 2021 00:03:24 +0100 Subject: [PATCH 3/3] Fixed old test --- paths_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/paths_test.go b/paths_test.go index 9f7ef55..8548113 100644 --- a/paths_test.go +++ b/paths_test.go @@ -368,6 +368,10 @@ func TestRelativeTo(t *testing.T) { func TestWriteToTempFile(t *testing.T) { tmpDir := New("_testdata", "tmp") + err := tmpDir.MkdirAll() + require.NoError(t, err) + defer tmpDir.RemoveAll() + tmpData := []byte("test") tmp, err := WriteToTempFile(tmpData, tmpDir, "prefix") defer tmp.Remove()