Skip to content

Commit

Permalink
path: added parse() and format() functions
Browse files Browse the repository at this point in the history
The parse() function splits a path and returns an object
with the different elements. The format() function is the
reverse of this and adds an objects corresponding path
elements to make up a string. Fixes nodejs#6976.
  • Loading branch information
roryrjb authored and chrisdickinson committed Nov 20, 2014
1 parent e41c071 commit ac56b61
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
42 changes: 42 additions & 0 deletions doc/api/path.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,48 @@ An example on Windows:
// returns
['C:\Windows\system32', 'C:\Windows', 'C:\Program Files\nodejs\']

## path.parse

Returns an object from a path string.

An example on *nix:

path.parse('/home/user/dir/file.txt')
// returns
{
root : "/",
dir : "/home/user/dir",
base : "file.txt",
ext : ".txt",
name : "file"
}

An example on Windows:

path.parse('C:\\path\\dir\\index.html')
// returns
{
root : "C:\",
dir : "C:\path\dir",
base : "index.html",
ext : ".html",
name : "index"
}

## path.format

Returns a path string from an object, the opposite of `path.parse` above.

path.format({
root : "/",
dir : "/home/user/dir",
base : "file.txt",
ext : ".txt",
name : "file"
})
// returns
'/home/user/dir/file.txt'

## path.posix

Provide access to aforementioned `path` methods but always interact in a posix
Expand Down
49 changes: 49 additions & 0 deletions lib/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function normalizeArray(parts, allowAboveRoot) {
return parts;
}

var splitPath;

// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
Expand Down Expand Up @@ -364,6 +365,30 @@ win32.extname = function(path) {
};


win32.format = function(object) {
root = object.root || '';
dir = object.dir;
base = object.base || '';
if (dir.slice(dir.length - 1, dir.length) === win32.sep) {
return dir + base;
} else {
return dir + this.sep + base;
}
};


win32.parse = function(string) {
var allParts = win32.splitPath(string);
return {
root: allParts[0],
dir: allParts[0] + allParts[1].slice(0, allParts[1].length - 1),
base: allParts[2],
ext: allParts[3],
name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
};
};


win32.sep = '\\';
win32.delimiter = ';';

Expand Down Expand Up @@ -545,6 +570,30 @@ posix.extname = function(path) {
};


posix.format = function(object) {
root = object.root || '';
var sep = posix.sep;
if (root.indexOf(':') > -1) {
sep = '\\';
}
dir = object.dir + sep;
base = object.base || '';
return dir + base;
};


posix.parse = function(string) {
var allParts = posix.splitPath(string);
return {
root: allParts[0],
dir: allParts[0] + allParts[1].slice(0, allParts[1].length - 1),
base: allParts[2],
ext: allParts[3],
name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
};
};


posix.sep = '/';
posix.delimiter = ':';

Expand Down
64 changes: 64 additions & 0 deletions test/simple/test-path-parse-format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var assert = require('assert');
var path = require('path');

var winPaths = [
'C:\\path\\dir\\index.html',
'C:\\another_path\\DIR\\1\\2\\33\\index',
'another_path\\DIR with spaces\\1\\2\\33\\index',

// unc
'\\\\server\\share\\file_path',
'\\\\server two\\shared folder\\file path.zip',
'\\\\teela\\admin$\\system32'

];

var unixPaths = [
'/home/user/dir/file.txt',
'/home/user/a dir/another File.zip',
'/home/user/a dir//another&File.',
'/home/user/a$$$dir//another File.zip',
'user/dir/another File.zip'
];

check(path.win32, winPaths);
check(path.posix, unixPaths);

function check(path, paths) {
paths.forEach(function(element, index, array) {
var count = index + 1;
console.log(count + ': `' + element + '`');
var output = path.parse(element);
var keys = Object.keys(output);
var values = [];
for (var i = 0; i < Object.keys(output).length; i++) {
values.push(output[keys[i]]);
}

assert.strictEqual(path.format(path.parse(element)), element);
assert.strictEqual(path.parse(element).dir, path.dirname(element));
assert.strictEqual(path.parse(element).base, path.basename(element));
assert.strictEqual(path.parse(element).ext, path.extname(element));
})
}

0 comments on commit ac56b61

Please sign in to comment.