diff --git a/lib/bucket/bucket.go b/lib/bucket/bucket.go index 13217f0da..44aac0bb3 100644 --- a/lib/bucket/bucket.go +++ b/lib/bucket/bucket.go @@ -29,6 +29,19 @@ func Split(absPath string) (bucket, bucketPath string) { return absPath[:slash], absPath[slash+1:] } +// Join path1 and path2 +// +// Like path.Join but does not clean the path - useful to preserve trailing / +func Join(path1, path2 string) string { + if path1 == "" { + return path2 + } + if path2 == "" { + return path1 + } + return strings.TrimSuffix(path1, "/") + "/" + strings.TrimPrefix(path2, "/") +} + // Cache stores whether buckets are available and their IDs type Cache struct { mu sync.Mutex // mutex to protect created and deleted diff --git a/lib/bucket/bucket_test.go b/lib/bucket/bucket_test.go index c178a37f9..1a36ea300 100644 --- a/lib/bucket/bucket_test.go +++ b/lib/bucket/bucket_test.go @@ -2,6 +2,7 @@ package bucket import ( "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -24,6 +25,26 @@ func TestSplit(t *testing.T) { } } +func TestJoin(t *testing.T) { + for _, test := range []struct { + in1, in2 string + want string + }{ + {in1: "", in2: "", want: ""}, + {in1: "in1", in2: "", want: "in1"}, + {in1: "", in2: "in2", want: "in2"}, + {in1: "in1", in2: "in2", want: "in1/in2"}, + {in1: "in1/", in2: "in2", want: "in1/in2"}, + {in1: "in1", in2: "/in2", want: "in1/in2"}, + {in1: "in1", in2: "in2/", want: "in1/in2/"}, + {in1: "/in1", in2: "/in2", want: "/in1/in2"}, + {in1: "/in1", in2: "../in2", want: "/in1/../in2"}, + } { + got := Join(test.in1, test.in2) + assert.Equal(t, test.want, got, fmt.Sprintf("in1=%q, in2=%q", test.in1, test.in2)) + } +} + func TestCache(t *testing.T) { c := NewCache() errBoom := errors.New("boom")