summaryrefslogtreecommitdiff
path: root/strutil
diff options
authorZygmunt Krynicki <me@zygoon.pl>2018-06-26 11:36:30 +0200
committerGitHub <noreply@github.com>2018-06-26 11:36:30 +0200
commitc9f8a1191e65d4a4a40ea9c5e94baa8548b92ee0 (patch)
tree5218f2d6cc1662c927c1b9b6757ae3fae5595368 /strutil
parent8362e4b121b5860b54d42de8524adb4897862d9c (diff)
parentd7878ae51d9af8511706394d3676d47b9aba1f7d (diff)
Merge pull request #5394 from zyga/tweak/pathiter-almost-clean-path
strutil: support iteration over almost clean paths
Diffstat (limited to 'strutil')
-rw-r--r--strutil/pathiter.go4
-rw-r--r--strutil/pathiter_test.go37
2 files changed, 33 insertions, 8 deletions
diff --git a/strutil/pathiter.go b/strutil/pathiter.go
index 7c54de86a1..8e53280e9f 100644
--- a/strutil/pathiter.go
+++ b/strutil/pathiter.go
@@ -50,10 +50,10 @@ type PathIterator struct {
// The path is passed through filepath.Clean automatically.
func NewPathIterator(path string) (*PathIterator, error) {
cleanPath := filepath.Clean(path)
- if path != cleanPath {
+ if cleanPath != path && cleanPath+"/" != path {
return nil, fmt.Errorf("cannot iterate over unclean path %q", path)
}
- return &PathIterator{path: cleanPath}, nil
+ return &PathIterator{path: path}, nil
}
// Path returns the path being traversed.
diff --git a/strutil/pathiter_test.go b/strutil/pathiter_test.go
index dffd9c2417..5063a744ad 100644
--- a/strutil/pathiter_test.go
+++ b/strutil/pathiter_test.go
@@ -76,6 +76,37 @@ func (s *pathIterSuite) TestPathIteratorRelative(c *C) {
c.Assert(iter.Depth(), Equals, 2)
}
+func (s *pathIterSuite) TestPathIteratorAbsoluteAlmostClean(c *C) {
+ iter, err := strutil.NewPathIterator("/foo/bar/")
+ c.Assert(err, IsNil)
+ c.Assert(iter.Path(), Equals, "/foo/bar/")
+ c.Assert(iter.Depth(), Equals, 0)
+
+ c.Assert(iter.Next(), Equals, true)
+ c.Assert(iter.CurrentBase(), Equals, "")
+ c.Assert(iter.CurrentPath(), Equals, "/")
+ c.Assert(iter.CurrentName(), Equals, "/")
+ c.Assert(iter.CurrentCleanName(), Equals, "")
+ c.Assert(iter.Depth(), Equals, 1)
+
+ c.Assert(iter.Next(), Equals, true)
+ c.Assert(iter.CurrentBase(), Equals, "/")
+ c.Assert(iter.CurrentPath(), Equals, "/foo/")
+ c.Assert(iter.CurrentName(), Equals, "foo/")
+ c.Assert(iter.CurrentCleanName(), Equals, "foo")
+ c.Assert(iter.Depth(), Equals, 2)
+
+ c.Assert(iter.Next(), Equals, true)
+ c.Assert(iter.CurrentBase(), Equals, "/foo/")
+ c.Assert(iter.CurrentPath(), Equals, "/foo/bar/")
+ c.Assert(iter.CurrentName(), Equals, "bar/")
+ c.Assert(iter.CurrentCleanName(), Equals, "bar")
+ c.Assert(iter.Depth(), Equals, 3)
+
+ c.Assert(iter.Next(), Equals, false)
+ c.Assert(iter.Depth(), Equals, 3)
+}
+
func (s *pathIterSuite) TestPathIteratorAbsoluteClean(c *C) {
iter, err := strutil.NewPathIterator("/foo/bar")
c.Assert(err, IsNil)
@@ -107,12 +138,6 @@ func (s *pathIterSuite) TestPathIteratorAbsoluteClean(c *C) {
c.Assert(iter.Depth(), Equals, 3)
}
-func (s *pathIterSuite) TestPathIteratorAbsoluteUnclean(c *C) {
- iter, err := strutil.NewPathIterator("/foo/bar/")
- c.Assert(err, ErrorMatches, `cannot iterate over unclean path "/foo/bar/"`)
- c.Assert(iter, IsNil)
-}
-
func (s *pathIterSuite) TestPathIteratorRootDir(c *C) {
iter, err := strutil.NewPathIterator("/")
c.Assert(err, IsNil)