|
@ -2,9 +2,10 @@ |
|
|
var isWindows = process.platform === 'win32'; |
|
|
var isWindows = process.platform === 'win32'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// resolves . and .. elements in a path array with directory names
|
|
|
// resolves . and .. elements in a path array with directory names there
|
|
|
// there must be no slashes, empty elements, or device names (c:\) in the array
|
|
|
// must be no slashes, empty elements, or device names (c:\) in the array
|
|
|
// (so also no leading and trailing slashes - it does not distinguish relative and absolute paths)
|
|
|
// (so also no leading and trailing slashes - it does not distinguish
|
|
|
|
|
|
// relative and absolute paths)
|
|
|
function normalizeArray(parts, allowAboveRoot) { |
|
|
function normalizeArray(parts, allowAboveRoot) { |
|
|
// if the path tries to go above the root, `up` ends up > 0
|
|
|
// if the path tries to go above the root, `up` ends up > 0
|
|
|
var up = 0; |
|
|
var up = 0; |
|
@ -38,18 +39,20 @@ if (isWindows) { |
|
|
// windows version
|
|
|
// windows version
|
|
|
var splitPathRe = /^(.+(?:[\\\/](?!$)|:)|[\\\/])?((?:.+?)?(\.[^.]*)?)$/; |
|
|
var splitPathRe = /^(.+(?:[\\\/](?!$)|:)|[\\\/])?((?:.+?)?(\.[^.]*)?)$/; |
|
|
|
|
|
|
|
|
// Regex to split a windows path into three parts: [*, device, slash, tail]
|
|
|
// Regex to split a windows path into three parts: [*, device, slash,
|
|
|
// windows-only
|
|
|
// tail] windows-only
|
|
|
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?(.*?)$/; |
|
|
var splitDeviceRe = |
|
|
|
|
|
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?(.*?)$/; |
|
|
|
|
|
|
|
|
// path.resolve([from ...], to)
|
|
|
// path.resolve([from ...], to)
|
|
|
// windows version
|
|
|
// windows version
|
|
|
exports.resolve = function() { |
|
|
exports.resolve = function() { |
|
|
// Prepend cwd to provided paths
|
|
|
// Prepend cwd to provided paths
|
|
|
var paths = [process.cwd()].concat(Array.prototype.slice.call(arguments, 0)); |
|
|
var paths = [process.cwd()].concat( |
|
|
|
|
|
Array.prototype.slice.call(arguments, 0)); |
|
|
|
|
|
|
|
|
var resolvedDevice = "", |
|
|
var resolvedDevice = '', |
|
|
resolvedTail = "", |
|
|
resolvedTail = '', |
|
|
resolvedAbsolute = false; |
|
|
resolvedAbsolute = false; |
|
|
|
|
|
|
|
|
for (var i = paths.length; i >= 0; i--) { |
|
|
for (var i = paths.length; i >= 0; i--) { |
|
@ -66,7 +69,9 @@ if (isWindows) { |
|
|
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
|
|
|
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
|
|
|
tail = result[3]; |
|
|
tail = result[3]; |
|
|
|
|
|
|
|
|
if (device && resolvedDevice && device.toLowerCase() !== resolvedDevice.toLowerCase()) { |
|
|
if (device && |
|
|
|
|
|
resolvedDevice && |
|
|
|
|
|
device.toLowerCase() !== resolvedDevice.toLowerCase()) { |
|
|
// This path points to another device so it is not applicable
|
|
|
// This path points to another device so it is not applicable
|
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
@ -92,7 +97,7 @@ if (isWindows) { |
|
|
// Windows stores the current directories for 'other' drives
|
|
|
// Windows stores the current directories for 'other' drives
|
|
|
// as hidden environment variables like =C:=c:\windows (literally)
|
|
|
// as hidden environment variables like =C:=c:\windows (literally)
|
|
|
// var deviceCwd = os.getCwdForDrive(resolvedDevice);
|
|
|
// var deviceCwd = os.getCwdForDrive(resolvedDevice);
|
|
|
var deviceCwd = ""; |
|
|
var deviceCwd = ''; |
|
|
|
|
|
|
|
|
// If there is no cwd set for the drive, it is at root
|
|
|
// If there is no cwd set for the drive, it is at root
|
|
|
resolvedTail = deviceCwd + '\\' + resolvedTail; |
|
|
resolvedTail = deviceCwd + '\\' + resolvedTail; |
|
@ -102,17 +107,23 @@ if (isWindows) { |
|
|
// Replace slashes (in UNC share name) by backslashes
|
|
|
// Replace slashes (in UNC share name) by backslashes
|
|
|
resolvedDevice = resolvedDevice.replace(/\//g, '\\'); |
|
|
resolvedDevice = resolvedDevice.replace(/\//g, '\\'); |
|
|
|
|
|
|
|
|
// At this point the path should be resolved to a full absolute path, but
|
|
|
// At this point the path should be resolved to a full absolute path,
|
|
|
// handle relative paths to be safe (might happen when process.cwd() fails)
|
|
|
// but handle relative paths to be safe (might happen when process.cwd()
|
|
|
|
|
|
// fails)
|
|
|
|
|
|
|
|
|
// Normalize the tail path
|
|
|
// Normalize the tail path
|
|
|
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(function(p) { |
|
|
|
|
|
return !!p; |
|
|
|
|
|
}), !resolvedAbsolute).join('\\'); |
|
|
|
|
|
|
|
|
|
|
|
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || '.'; |
|
|
function f(p) { |
|
|
|
|
|
return !!p; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f), |
|
|
|
|
|
!resolvedAbsolute).join('\\'); |
|
|
|
|
|
|
|
|
|
|
|
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || |
|
|
|
|
|
'.'; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// windows version
|
|
|
// windows version
|
|
|
exports.normalize = function(path) { |
|
|
exports.normalize = function(path) { |
|
|
var result = splitDeviceRe.exec(path), |
|
|
var result = splitDeviceRe.exec(path), |
|
@ -128,21 +139,23 @@ if (isWindows) { |
|
|
}), !isAbsolute).join('\\'); |
|
|
}), !isAbsolute).join('\\'); |
|
|
|
|
|
|
|
|
if (!tail && !isAbsolute) { |
|
|
if (!tail && !isAbsolute) { |
|
|
tail = '.' |
|
|
tail = '.'; |
|
|
} |
|
|
} |
|
|
if (tail && trailingSlash) { |
|
|
if (tail && trailingSlash) { |
|
|
tail += '\\' |
|
|
tail += '\\'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return device + (isAbsolute ? '\\' : '') + tail; |
|
|
return device + (isAbsolute ? '\\' : '') + tail; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
// windows version
|
|
|
// windows version
|
|
|
exports.join = function() { |
|
|
exports.join = function() { |
|
|
var paths = Array.prototype.slice.call(arguments, 0).filter(function(p) { |
|
|
function f(p) { |
|
|
return p && typeof p === 'string'; |
|
|
return p && typeof p === 'string'; |
|
|
}), |
|
|
} |
|
|
joined = paths.join('\\'); |
|
|
|
|
|
|
|
|
var paths = Array.prototype.slice.call(arguments, 0).filter(f); |
|
|
|
|
|
var joined = paths.join('\\'); |
|
|
|
|
|
|
|
|
// Make sure that the joined path doesn't start with two slashes
|
|
|
// Make sure that the joined path doesn't start with two slashes
|
|
|
// - it will be mistaken for an unc path by normalize() -
|
|
|
// - it will be mistaken for an unc path by normalize() -
|
|
@ -152,7 +165,7 @@ if (isWindows) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return exports.normalize(joined); |
|
|
return exports.normalize(joined); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else /* posix */ { |
|
|
} else /* posix */ { |
|
@ -165,9 +178,10 @@ if (isWindows) { |
|
|
// posix version
|
|
|
// posix version
|
|
|
exports.resolve = function() { |
|
|
exports.resolve = function() { |
|
|
// Prepend cwd to provided paths
|
|
|
// Prepend cwd to provided paths
|
|
|
var paths = [process.cwd()].concat(Array.prototype.slice.call(arguments, 0)); |
|
|
var paths = [process.cwd()].concat( |
|
|
|
|
|
Array.prototype.slice.call(arguments, 0)); |
|
|
|
|
|
|
|
|
var resolvedPath = "", |
|
|
var resolvedPath = '', |
|
|
resolvedAbsolute = false; |
|
|
resolvedAbsolute = false; |
|
|
|
|
|
|
|
|
for (var i = paths.length; i >= 0 && !resolvedAbsolute; i--) { |
|
|
for (var i = paths.length; i >= 0 && !resolvedAbsolute; i--) { |
|
@ -189,7 +203,7 @@ if (isWindows) { |
|
|
}), !resolvedAbsolute).join('/'); |
|
|
}), !resolvedAbsolute).join('/'); |
|
|
|
|
|
|
|
|
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; |
|
|
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
// path.normalize(path)
|
|
|
// path.normalize(path)
|
|
|
// posix version
|
|
|
// posix version
|
|
@ -203,23 +217,23 @@ if (isWindows) { |
|
|
}), !isAbsolute).join('/'); |
|
|
}), !isAbsolute).join('/'); |
|
|
|
|
|
|
|
|
if (!path && !isAbsolute) { |
|
|
if (!path && !isAbsolute) { |
|
|
path = '.' |
|
|
path = '.'; |
|
|
} |
|
|
} |
|
|
if (path && trailingSlash) { |
|
|
if (path && trailingSlash) { |
|
|
path += '/'; |
|
|
path += '/'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return (isAbsolute ? '/' : '') + path; |
|
|
return (isAbsolute ? '/' : '') + path; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// posix version
|
|
|
// posix version
|
|
|
exports.join = function() { |
|
|
exports.join = function() { |
|
|
var paths = Array.prototype.slice.call(arguments, 0); |
|
|
var paths = Array.prototype.slice.call(arguments, 0); |
|
|
return exports.normalize(paths.filter(function(p, index) { |
|
|
return exports.normalize(paths.filter(function(p, index) { |
|
|
return p && typeof p === 'string' |
|
|
return p && typeof p === 'string'; |
|
|
}).join('/')); |
|
|
}).join('/')); |
|
|
} |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -227,7 +241,7 @@ exports.dirname = function(path) { |
|
|
var dir = splitPathRe.exec(path)[1] || ''; |
|
|
var dir = splitPathRe.exec(path)[1] || ''; |
|
|
if (!dir) { |
|
|
if (!dir) { |
|
|
// No dirname
|
|
|
// No dirname
|
|
|
return '.' |
|
|
return '.'; |
|
|
} else if (dir.length === 1 || |
|
|
} else if (dir.length === 1 || |
|
|
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')) { |
|
|
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')) { |
|
|
// It is just a slash or a drive letter with a slash
|
|
|
// It is just a slash or a drive letter with a slash
|
|
|