Skip to content

Commit

Permalink
Merge pull request #15 from ChALkeR/v0.x-update
Browse files Browse the repository at this point in the history
backport (dir|base|ext)name from 1.0.0
  • Loading branch information
goto-bus-stop authored Jun 20, 2018
2 parents 9d4dca5 + 338a800 commit 14ea364
Show file tree
Hide file tree
Showing 3 changed files with 529 additions and 27 deletions.
130 changes: 104 additions & 26 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
// backported and transplited with Babel, with backwards-compat fixes

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
Expand Down Expand Up @@ -49,14 +52,6 @@ function normalizeArray(parts, allowAboveRoot) {
return parts;
}

// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};

// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
Expand Down Expand Up @@ -172,37 +167,120 @@ exports.relative = function(from, to) {
exports.sep = '/';
exports.delimiter = ':';

exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];

if (!root && !dir) {
// No dirname whatsoever
return '.';
exports.dirname = function (path) {
if (typeof path !== 'string') path = path + '';
if (path.length === 0) return '.';
var code = path.charCodeAt(0);
var hasRoot = code === 47 /*/*/;
var end = -1;
var matchedSlash = true;
for (var i = path.length - 1; i >= 1; --i) {
code = path.charCodeAt(i);
if (code === 47 /*/*/) {
if (!matchedSlash) {
end = i;
break;
}
} else {
// We saw the first non-path separator
matchedSlash = false;
}
}

if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
if (end === -1) return hasRoot ? '/' : '.';
if (hasRoot && end === 1) {
// return '//';
// Backwards-compat fix:
return '/';
}

return root + dir;
return path.slice(0, end);
};

function basename(path) {
if (typeof path !== 'string') path = path + '';

var start = 0;
var end = -1;
var matchedSlash = true;
var i;

for (i = path.length - 1; i >= 0; --i) {
if (path.charCodeAt(i) === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
start = i + 1;
break;
}
} else if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// path component
matchedSlash = false;
end = i + 1;
}
}

if (end === -1) return '';
return path.slice(start, end);
}

exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
// Uses a mixed approach for backwards-compatibility, as ext behavior changed
// in new Node.js versions, so only basename() above is backported here
exports.basename = function (path, ext) {
var f = basename(path);
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};

exports.extname = function (path) {
if (typeof path !== 'string') path = path + '';
var startDot = -1;
var startPart = 0;
var end = -1;
var matchedSlash = true;
// Track the state of characters (if any) we see before our first dot and
// after any path separator we find
var preDotState = 0;
for (var i = path.length - 1; i >= 0; --i) {
var code = path.charCodeAt(i);
if (code === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
startPart = i + 1;
break;
}
continue;
}
if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// extension
matchedSlash = false;
end = i + 1;
}
if (code === 46 /*.*/) {
// If this is our first dot, mark it as the start of our extension
if (startDot === -1)
startDot = i;
else if (preDotState !== 1)
preDotState = 1;
} else if (startDot !== -1) {
// We saw a non-dot and non-path separator before our dot, so we should
// have a good chance at having a non-empty extension
preDotState = -1;
}
}

exports.extname = function(path) {
return splitPath(path)[3];
if (startDot === -1 || end === -1 ||
// We saw a non-dot character immediately before the dot
preDotState === 0 ||
// The (right-most) trimmed path component is exactly '..'
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
return '';
}
return path.slice(startDot, end);
};

function filter (xs, f) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"tape": "~1.0.4"
},
"scripts": {
"test": "tape test/*.js"
"test": "node test/test-path.js"
},
"repository": {
"type": "git",
Expand Down
Loading

0 comments on commit 14ea364

Please sign in to comment.