cord-776 create build / runtime containers for autmation uservices
Change-Id: I246973192adef56a250ffe93a5f65fff488840c1
diff --git a/automation/vendor/github.com/juju/utils/relativeurl.go b/automation/vendor/github.com/juju/utils/relativeurl.go
new file mode 100644
index 0000000..b70f1d5
--- /dev/null
+++ b/automation/vendor/github.com/juju/utils/relativeurl.go
@@ -0,0 +1,62 @@
+// Copyright 2016 Canonical Ltd.
+// Licensed under the LGPLv3, see LICENCE file for details.
+
+package utils
+
+import (
+ "strings"
+
+ "github.com/juju/errors"
+)
+
+// RelativeURLPath returns a relative URL path that is lexically
+// equivalent to targpath when interpreted by url.URL.ResolveReference.
+// On success, the returned path will always be non-empty and relative
+// to basePath, even if basePath and targPath share no elements.
+//
+// It is assumed that both basePath and targPath are normalized
+// (have no . or .. elements).
+//
+// An error is returned if basePath or targPath are not absolute paths.
+func RelativeURLPath(basePath, targPath string) (string, error) {
+ if !strings.HasPrefix(basePath, "/") {
+ return "", errors.New("non-absolute base URL")
+ }
+ if !strings.HasPrefix(targPath, "/") {
+ return "", errors.New("non-absolute target URL")
+ }
+ baseParts := strings.Split(basePath, "/")
+ targParts := strings.Split(targPath, "/")
+
+ // For the purposes of dotdot, the last element of
+ // the paths are irrelevant. We save the last part
+ // of the target path for later.
+ lastElem := targParts[len(targParts)-1]
+ baseParts = baseParts[0 : len(baseParts)-1]
+ targParts = targParts[0 : len(targParts)-1]
+
+ // Find the common prefix between the two paths:
+ var i int
+ for ; i < len(baseParts); i++ {
+ if i >= len(targParts) || baseParts[i] != targParts[i] {
+ break
+ }
+ }
+ dotdotCount := len(baseParts) - i
+ targOnly := targParts[i:]
+ result := make([]string, 0, dotdotCount+len(targOnly)+1)
+ for i := 0; i < dotdotCount; i++ {
+ result = append(result, "..")
+ }
+ result = append(result, targOnly...)
+ result = append(result, lastElem)
+ final := strings.Join(result, "/")
+ if final == "" {
+ // If the final result is empty, the last element must
+ // have been empty, so the target was slash terminated
+ // and there were no previous elements, so "."
+ // is appropriate.
+ final = "."
+ }
+ return final, nil
+}