Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Force relativize args to be absolute

  • Loading branch information...
commit 5f141645ad2f4304f3f2bf046a0c95d5162da801 1 parent 4e74172
@isaacs isaacs authored
Showing with 26 additions and 10 deletions.
  1. +26 −10 lib/utils/relativize.js
View
36 lib/utils/relativize.js
@@ -2,34 +2,43 @@
module.exports = relativize
// return the shortest path between two folders.
-// if the absolute path is shorter, then use that,
+// 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 (src.charAt(0) !== "/") forceRelative = true
+ else if (dest.charAt(0) !== "/") return false
+ src = path.resolve(src)
+ dest = path.resolve(dest)
src = src.split("/")
- var abs = dest
dest = dest.split("/")
var i = 0
while (src[i] === dest[i]) i++
- if (!forceRelative && i === 1) return abs // nothing in common
+ 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 && abs.length < dest.length ? abs : dest
+ return !forceRelative && orig.length < dest.length ? orig : dest
}
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" ]
- , ["/a/d" ,"/a/b/c/d/e/" ,"/a/d" ,"../../../../d" ]
- , ["./foo/bar" ,"./foo/baz" ,"./bar" ,"./bar" ]
- , ["./d" ,"./a/b/c/d/e" ,"./d" ,"../../../../d" ]
+ ; [ ["/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]
@@ -40,6 +49,13 @@ if (module === require.main) {
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")
Please sign in to comment.
Something went wrong with that request. Please try again.