bundle: Remove extra root name in bundle file id's

Previously if we provided a "root" to the bundle directory loader that
was a relative path, it would matter whether or not it was prefixed
with "./". The logic to trim that path from the paths found walking
the root was not taking into account the prefix so the resulting ones
that had "./" would leave behind the root path.

Later on the bundle loader would generate a "full" path to set on the
module file for its location which is the root+path.. which resulted
in duplicate "root"s on those id's.

To fix this we just normalize the relative paths in the directory
loader so that we can not worry about what type of relative path it
is.

Fixes: #2117
Signed-off-by: Patrick East <east.patrick@gmail.com>
This commit is contained in:
Patrick East
2020-04-06 18:51:53 -07:00
parent 4e5f791673
commit e0156fa1f8
2 changed files with 78 additions and 0 deletions
+14
View File
@@ -76,6 +76,20 @@ type dirLoader struct {
// NewDirectoryLoader returns a basic DirectoryLoader implementation
// that will load files from a given root directory path.
func NewDirectoryLoader(root string) DirectoryLoader {
if len(root) > 1 {
// Normalize relative directories, ex "./src/bundle" -> "src/bundle"
// We don't need an absolute path, but this makes the joined/trimmed
// paths more uniform.
if root[0] == '.' && root[1] == filepath.Separator {
if len(root) == 2 {
root = root[:1] // "./" -> "."
} else {
root = root[2:] // remove leading "./"
}
}
}
d := dirLoader{
root: root,
}
+64
View File
@@ -106,3 +106,67 @@ func testLoader(t *testing.T, loader DirectoryLoader, expectedFiles map[string]s
t.Fatalf("Expected to read %d files, read %d", len(expectedFiles), fileCount)
}
}
func TestNewDirectoryLoaderNormalizedRoot(t *testing.T) {
cases := []struct {
note string
root string
expected string
}{
{
note: "abs",
root: "/a/b/c",
expected: "/a/b/c",
},
{
note: "trailing slash",
root: "/a/b/c/",
expected: "/a/b/c/",
},
{
note: "empty",
root: "",
expected: "",
},
{
note: "single abs",
root: "/",
expected: "/",
},
{
note: "single relative",
root: "foo",
expected: "foo",
},
{
note: "single relative dot",
root: ".",
expected: ".",
},
{
note: "single relative dot slash",
root: "./",
expected: ".",
},
{
note: "relative leading dot slash",
root: "./a/b/c",
expected: "a/b/c",
},
{
note: "relative",
root: "a/b/c",
expected: "a/b/c",
},
}
for _, tc := range cases {
t.Run(tc.note, func(t *testing.T) {
l := NewDirectoryLoader(tc.root)
actual := l.(*dirLoader).root
if actual != tc.expected {
t.Fatalf("Expected root %s got %s", tc.expected, actual)
}
})
}
}