summaryrefslogtreecommitdiff
path: root/deps/npm/lib/utils/relativize.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib/utils/relativize.js')
-rw-r--r--deps/npm/lib/utils/relativize.js70
1 files changed, 70 insertions, 0 deletions
diff --git a/deps/npm/lib/utils/relativize.js b/deps/npm/lib/utils/relativize.js
new file mode 100644
index 0000000000..74c45c5d3e
--- /dev/null
+++ b/deps/npm/lib/utils/relativize.js
@@ -0,0 +1,70 @@
+
+module.exports = relativize
+
+// return the shortest path between two folders.
+// if the original path is shorter, then use that,
+// unless forceRelative is set to true.
+var path = require("path")
+function relativize (dest, src, forceRelative) {
+ var orig = dest
+ if (!isAbsolute(src)) forceRelative = true
+ else if (!isAbsolute(dest)) return false
+ src = path.resolve(src)
+ dest = path.resolve(dest)
+ if (src === dest) return "."
+ src = src.split(split)
+ dest = dest.split(split)
+ var i = 0
+ while (src[i] === dest[i]) i++
+ if (!forceRelative && i === 1) return orig // nothing in common
+ src.splice(0, i + 1)
+ var dots = [0, i, "."]
+ for (var i = 0, l = src.length; i < l; i ++) dots.push("..")
+ dest.splice.apply(dest, dots)
+ if (dest[0] === "." && dest[1] === "..") dest.shift()
+ dest = dest.join("/")
+ return !forceRelative && orig.length < dest.length ? orig : dest
+}
+
+var split = process.platform === "win32" ? /[\/\\]/ : "/"
+
+function isAbsolute (p) {
+ if (process.platform !== "win32") return p.charAt(0) === "/"
+ return path.resolve(p) === p
+}
+
+if (module === require.main) {
+ // from, to, result, relativeForced
+ var assert = require("assert")
+
+ ; [ ["/bar" ,"/foo" ,"/bar" ,"./bar" ]
+ , ["/foo/baz" ,"/foo/bar/baz" ,"../baz" ,"../baz" ]
+ , ["/a/d" ,"/a/b/c/d/e/f" ,"/a/d" ,"../../../../d" ]
+ // trailing slashes are ignored.
+ , ["/a/d" ,"/a/b/c/d/e/" ,"/a/d" ,"../../../d" ]
+ , ["./foo/bar" ,"./foo/baz" ,"./bar" ,"./bar" ]
+ // force relative when the src is relative.
+ , ["./d" ,"./a/b/c/d/e" ,"../../../../d" ,"../../../../d" ]
+ // if src is abs and dest is relative, then fail
+ , ["./d" ,"/a/b" ,false ,false ]
+ ].forEach(function (test) {
+ var d = test[0]
+ , s = test[1]
+ , r = test[2]
+ , rr = test[3]
+ , ra = relativize(d, s)
+ , rra = relativize(d, s, true)
+ console.log([d, s, r, rr], [ra, rra], [r === ra, rr === rra])
+ assert.equal(r, ra)
+ assert.equal(rr, rra)
+ if (!r) return
+ // contract: this is the relative path from absolute A to absolute B
+ var ad = path.resolve(d)
+ , as = path.resolve(s)
+ , dir = path.dirname(as)
+ assert.equal(path.resolve(dir, rr), ad)
+ assert.equal(path.resolve(dir, r), ad)
+ })
+
+ console.log("ok")
+}