Skip to content

Commit 1dcf698

Browse files
committed
Added Canonical method
1 parent 3137bb2 commit 1dcf698

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

paths.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,18 @@ func (p *Path) Parents() []*Path {
564564
func (p *Path) String() string {
565565
return p.path
566566
}
567+
568+
// Canonical return a "canonical" Path for the given filename.
569+
// The meaning of "canonical" is OS-dependent but the goal of this method
570+
// is to always return the same path for a given file (factoring out all the
571+
// possibile ambiguities including, for example, relative paths traversal,
572+
// symlinks, drive volume letter case, etc).
573+
func (p *Path) Canonical() *Path {
574+
canonical := p.Clone()
575+
// https://github.com/golang/go/issues/17084#issuecomment-246645354
576+
canonical.FollowSymLink()
577+
if absPath, err := canonical.Abs(); err == nil {
578+
canonical = absPath
579+
}
580+
return canonical
581+
}

paths_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,25 @@ func TestEquivalentPaths(t *testing.T) {
321321
}
322322
}
323323

324+
func TestCanonicalize(t *testing.T) {
325+
wd, err := Getwd()
326+
require.NoError(t, err)
327+
328+
p := New("_testdata", "anotherFile").Canonical()
329+
require.Equal(t, wd.Join("_testdata", "anotherFile").String(), p.String())
330+
331+
p = New("_testdata", "nonexistentFile").Canonical()
332+
require.Equal(t, wd.Join("_testdata", "nonexistentFile").String(), p.String())
333+
334+
if runtime.GOOS == "windows" {
335+
q := New("_testdata", "ANOTHE~1").Canonical()
336+
require.Equal(t, wd.Join("_testdata", "anotherFile").String(), q.String())
337+
338+
r := New("c:\\").Canonical()
339+
require.Equal(t, "C:\\", r.String())
340+
}
341+
}
342+
324343
func TestRelativeTo(t *testing.T) {
325344
res, err := New("/my/abs/path/123/456").RelTo(New("/my/abs/path"))
326345
require.NoError(t, err)

0 commit comments

Comments
 (0)