Merge pull request #8137 from edolstra/lazy-trees-cherrypicks
Add CanonPath::makeRelative()
This commit is contained in:
commit
cf76b38e27
|
@ -100,4 +100,30 @@ std::ostream & operator << (std::ostream & stream, const CanonPath & path)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CanonPath::makeRelative(const CanonPath & path) const
|
||||||
|
{
|
||||||
|
auto p1 = begin();
|
||||||
|
auto p2 = path.begin();
|
||||||
|
|
||||||
|
for (; p1 != end() && p2 != path.end() && *p1 == *p2; ++p1, ++p2) ;
|
||||||
|
|
||||||
|
if (p1 == end() && p2 == path.end())
|
||||||
|
return ".";
|
||||||
|
else if (p1 == end())
|
||||||
|
return std::string(p2.remaining);
|
||||||
|
else {
|
||||||
|
std::string res;
|
||||||
|
while (p1 != end()) {
|
||||||
|
++p1;
|
||||||
|
if (!res.empty()) res += '/';
|
||||||
|
res += "..";
|
||||||
|
}
|
||||||
|
if (p2 != path.end()) {
|
||||||
|
if (!res.empty()) res += '/';
|
||||||
|
res += p2.remaining;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,9 @@ public:
|
||||||
bool operator != (const Iterator & x) const
|
bool operator != (const Iterator & x) const
|
||||||
{ return remaining.data() != x.remaining.data(); }
|
{ return remaining.data() != x.remaining.data(); }
|
||||||
|
|
||||||
|
bool operator == (const Iterator & x) const
|
||||||
|
{ return !(*this != x); }
|
||||||
|
|
||||||
const std::string_view operator * () const
|
const std::string_view operator * () const
|
||||||
{ return remaining.substr(0, slash); }
|
{ return remaining.substr(0, slash); }
|
||||||
|
|
||||||
|
@ -166,6 +169,10 @@ public:
|
||||||
the `allowed` paths are within `this`. (The latter condition
|
the `allowed` paths are within `this`. (The latter condition
|
||||||
ensures access to the parents of allowed paths.) */
|
ensures access to the parents of allowed paths.) */
|
||||||
bool isAllowed(const std::set<CanonPath> & allowed) const;
|
bool isAllowed(const std::set<CanonPath> & allowed) const;
|
||||||
|
|
||||||
|
/* Return a representation `x` of `path` relative to `this`, i.e.
|
||||||
|
`CanonPath(this.makeRelative(x), this) == path`. */
|
||||||
|
std::string makeRelative(const CanonPath & path) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & stream, const CanonPath & path);
|
std::ostream & operator << (std::ostream & stream, const CanonPath & path);
|
||||||
|
|
|
@ -107,15 +107,13 @@ namespace nix {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CanonPath, within) {
|
TEST(CanonPath, within) {
|
||||||
{
|
ASSERT_TRUE(CanonPath("foo").isWithin(CanonPath("foo")));
|
||||||
ASSERT_TRUE(CanonPath("foo").isWithin(CanonPath("foo")));
|
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("bar")));
|
||||||
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("bar")));
|
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("fo")));
|
||||||
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("fo")));
|
ASSERT_TRUE(CanonPath("foo/bar").isWithin(CanonPath("foo")));
|
||||||
ASSERT_TRUE(CanonPath("foo/bar").isWithin(CanonPath("foo")));
|
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("foo/bar")));
|
||||||
ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("foo/bar")));
|
ASSERT_TRUE(CanonPath("/foo/bar/default.nix").isWithin(CanonPath("/")));
|
||||||
ASSERT_TRUE(CanonPath("/foo/bar/default.nix").isWithin(CanonPath("/")));
|
ASSERT_TRUE(CanonPath("/").isWithin(CanonPath("/")));
|
||||||
ASSERT_TRUE(CanonPath("/").isWithin(CanonPath("/")));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CanonPath, sort) {
|
TEST(CanonPath, sort) {
|
||||||
|
@ -127,29 +125,38 @@ namespace nix {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CanonPath, allowed) {
|
TEST(CanonPath, allowed) {
|
||||||
{
|
std::set<CanonPath> allowed {
|
||||||
std::set<CanonPath> allowed {
|
CanonPath("foo/bar"),
|
||||||
CanonPath("foo/bar"),
|
CanonPath("foo!"),
|
||||||
CanonPath("foo!"),
|
CanonPath("xyzzy"),
|
||||||
CanonPath("xyzzy"),
|
CanonPath("a/b/c"),
|
||||||
CanonPath("a/b/c"),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
ASSERT_TRUE (CanonPath("foo/bar").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("foo/bar").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("foo/bar/bla").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("foo/bar/bla").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("foo").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("foo").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("bar").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("bar").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("bar/a").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("bar/a").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("a").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("a").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("a/b").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("a/b").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("a/b/c").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("a/b/c").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("a/b/c/d").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("a/b/c/d").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("a/b/c/d/e").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("a/b/c/d/e").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("a/b/a").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("a/b/a").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("a/b/d").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("a/b/d").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("aaa").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("aaa").isAllowed(allowed));
|
||||||
ASSERT_FALSE(CanonPath("zzz").isAllowed(allowed));
|
ASSERT_FALSE(CanonPath("zzz").isAllowed(allowed));
|
||||||
ASSERT_TRUE (CanonPath("/").isAllowed(allowed));
|
ASSERT_TRUE (CanonPath("/").isAllowed(allowed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CanonPath, makeRelative) {
|
||||||
|
CanonPath d("/foo/bar");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar")), ".");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/foo")), "..");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/")), "../..");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar/xyzzy")), "xyzzy");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar/xyzzy/bla")), "xyzzy/bla");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/foo/xyzzy/bla")), "../xyzzy/bla");
|
||||||
|
ASSERT_EQ(d.makeRelative(CanonPath("/xyzzy/bla")), "../../xyzzy/bla");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue