add path.relative
This commit is contained in:
parent
cf78ce59b3
commit
502900c0bc
103
lib/path.js
103
lib/path.js
@ -165,6 +165,64 @@ if (isWindows) {
|
|||||||
return exports.normalize(joined);
|
return exports.normalize(joined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// path.relative(from, to)
|
||||||
|
// it will solve the relative path from 'from' to 'to', for instance:
|
||||||
|
// from = 'C:\\orandea\\test\\aaa'
|
||||||
|
// to = 'C:\\orandea\\impl\\bbb'
|
||||||
|
// The output of the function should be: '..\\..\\impl\\bbb'
|
||||||
|
// windows version
|
||||||
|
exports.relative = function(from, to) {
|
||||||
|
from = exports.resolve(from);
|
||||||
|
to = exports.resolve(to);
|
||||||
|
|
||||||
|
// windows is not case sensitive
|
||||||
|
var lowerFrom = from.toLowerCase();
|
||||||
|
var lowerTo = to.toLowerCase();
|
||||||
|
|
||||||
|
function trim(arr) {
|
||||||
|
var start = 0;
|
||||||
|
for(;start < arr.length; start++) {
|
||||||
|
if (arr[start] !== '') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var end = arr.length - 1;
|
||||||
|
for(;end >= 0; end--) {
|
||||||
|
if (arr[end] !== '') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > end) return [];
|
||||||
|
return arr.slice(start, end - start + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fromParts = trim(from.split('\\'));
|
||||||
|
var toParts = trim(to.split('\\'));
|
||||||
|
|
||||||
|
var lowerFromParts = trim(lowerFrom.split('\\'));
|
||||||
|
var lowerToParts = trim(lowerTo.split('\\'));
|
||||||
|
|
||||||
|
var length = Math.min(lowerFromParts.length, lowerToParts.length);
|
||||||
|
var samePartsLength = length;
|
||||||
|
for(var i = 0; i < length; i++) {
|
||||||
|
if (lowerFromParts[i] !== lowerToParts[i]) {
|
||||||
|
samePartsLength = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samePartsLength == 0) {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputParts = [];
|
||||||
|
for(var i = samePartsLength; i < lowerFromParts.length; i++) {
|
||||||
|
outputParts.push('..');
|
||||||
|
}
|
||||||
|
|
||||||
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
||||||
|
|
||||||
|
return outputParts.join('\\');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} else /* posix */ {
|
} else /* posix */ {
|
||||||
|
|
||||||
@ -232,6 +290,51 @@ if (isWindows) {
|
|||||||
return p && typeof p === 'string';
|
return p && typeof p === 'string';
|
||||||
}).join('/'));
|
}).join('/'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// path.relative(from, to)
|
||||||
|
// posix version
|
||||||
|
exports.relative = function(from, to) {
|
||||||
|
from = exports.resolve(from).substr(1);
|
||||||
|
to = exports.resolve(to).substr(1);
|
||||||
|
|
||||||
|
function trim(arr) {
|
||||||
|
var start = 0;
|
||||||
|
for(;start < arr.length; start++) {
|
||||||
|
if (arr[start] !== '') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var end = arr.length - 1;
|
||||||
|
for(;end >= 0; end--) {
|
||||||
|
if (arr[end] !== '') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > end) return [];
|
||||||
|
return arr.slice(start, end - start + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fromParts = trim(from.split('/'));
|
||||||
|
var toParts = trim(to.split('/'));
|
||||||
|
|
||||||
|
var length = Math.min(fromParts.length, toParts.length);
|
||||||
|
var samePartsLength = length;
|
||||||
|
for(var i = 0; i < length; i++) {
|
||||||
|
if (fromParts[i] !== toParts[i]) {
|
||||||
|
samePartsLength = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputParts = [];
|
||||||
|
for(var i = samePartsLength; i < fromParts.length; i++) {
|
||||||
|
outputParts.push('..');
|
||||||
|
}
|
||||||
|
|
||||||
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
||||||
|
|
||||||
|
return outputParts.join('/');
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,3 +147,39 @@ resolveTests.forEach(function(test) {
|
|||||||
// assert.equal(actual, expected, message);
|
// assert.equal(actual, expected, message);
|
||||||
});
|
});
|
||||||
assert.equal(failures.length, 0, failures.join(''));
|
assert.equal(failures.length, 0, failures.join(''));
|
||||||
|
|
||||||
|
// path.relative tests
|
||||||
|
if (isWindows) {
|
||||||
|
// windows
|
||||||
|
var relativeTests =
|
||||||
|
// arguments result
|
||||||
|
[['c:/blah\\blah', 'd:/games', 'd:\\games'],
|
||||||
|
['c:/aaaa/bbbb', 'c:/aaaa', '..'],
|
||||||
|
['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'],
|
||||||
|
['c:/aaaa/bbbb', 'c:/aaaa/bbbb',''],
|
||||||
|
['c:/aaaa/bbbb', 'c:/aaaa/cccc','..\\cccc'],
|
||||||
|
['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'],
|
||||||
|
['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'],
|
||||||
|
['c:/aaaa/bbbb', 'd:\\', 'd:\\']];
|
||||||
|
} else {
|
||||||
|
// posix
|
||||||
|
var relativeTests =
|
||||||
|
// arguments result
|
||||||
|
[['/var/lib', '/var', '..'],
|
||||||
|
['/var/lib', '/bin', '../../bin'],
|
||||||
|
['/var/lib', '/var/lib', ''],
|
||||||
|
['/var/lib', '/var/apache', '../apache'],
|
||||||
|
['/var/', '/var/lib', 'lib'],
|
||||||
|
['/', '/var/lib', 'var/lib']];
|
||||||
|
}
|
||||||
|
var failures = [];
|
||||||
|
relativeTests.forEach(function(test) {
|
||||||
|
var actual = path.relative(test[0], test[1]);
|
||||||
|
var expected = test[2];
|
||||||
|
var message = 'path.relative(' + test.slice(0, 2).map(JSON.stringify).join(',') + ')' +
|
||||||
|
'\n expect=' + JSON.stringify(expected) +
|
||||||
|
'\n actual=' + JSON.stringify(actual);
|
||||||
|
if (actual !== expected) failures.push('\n' + message);
|
||||||
|
});
|
||||||
|
assert.equal(failures.length, 0, failures.join(''));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user