Closed gillesruppert closed 12 years ago
Indeed there was an issue when working outside of package scope. Usually we work with projects that are packages and have root path other than system root /
. It's also hard to write test that would check that case, that's why it wasn't picked so far.
I've fixed that and published it (v0.3.10). Let me know if it works fine for you.
According to error that occurred when installing with dev
. It crashed on installing dev dependencies of packages that Webmake depend on.
To test Webmake, you just need to do npm install
directly in Webmake directory and then npm test
:
dhcp1031224-176:webmake medikoo$ rm -rf node_modules
dhcp1031224-176:webmake medikoo$ npm install
npm http GET https://registry.npmjs.org/find-requires
npm http GET https://registry.npmjs.org/next
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/tad
npm http GET https://registry.npmjs.org/es5-ext
npm http GET https://registry.npmjs.org/deferred
npm http 304 https://registry.npmjs.org/find-requires
npm http 304 https://registry.npmjs.org/optimist
npm http 304 https://registry.npmjs.org/tad
npm http 304 https://registry.npmjs.org/next
npm http 304 https://registry.npmjs.org/es5-ext
npm http 304 https://registry.npmjs.org/deferred
npm http GET https://registry.npmjs.org/esprima/0.9.9
npm http GET https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/duration
npm http GET https://registry.npmjs.org/event-emitter
npm http GET https://registry.npmjs.org/test
npm http GET https://registry.npmjs.org/cli-color
npm http GET https://registry.npmjs.org/clock
npm http GET https://registry.npmjs.org/minimatch
npm http 304 https://registry.npmjs.org/esprima/0.9.9
npm http 304 https://registry.npmjs.org/wordwrap
npm http 304 https://registry.npmjs.org/cli-color
npm http 304 https://registry.npmjs.org/clock
npm http 304 https://registry.npmjs.org/event-emitter
npm http 304 https://registry.npmjs.org/duration
npm http 304 https://registry.npmjs.org/test
npm http 304 https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/lru-cache
npm http 304 https://registry.npmjs.org/lru-cache
deferred@0.5.6 ./node_modules/deferred
es5-ext@0.8.2 ./node_modules/es5-ext
optimist@0.3.4 ./node_modules/optimist
└── wordwrap@0.0.2
tad@0.1.9 ./node_modules/tad
├── event-emitter@0.1.4
├── duration@0.1.0
├── clock@0.1.4
├── cli-color@0.1.7
└── test@0.4.4
find-requires@0.1.2 ./node_modules/find-requires
└── esprima@0.9.9
next@0.2.14 ./node_modules/next
├── event-emitter@0.1.4
└── minimatch@0.2.5 (lru-cache@1.1.0)
dhcp1031224-176:webmake medikoo$ npm test
> webmake@0.3.9 test /Users/medikoo/Projects/_packages/webmake
> node ./node_modules/tad/bin/tad lib
15:37:21.369 ✓ parser.js ..
15:37:21.424 ✓ webmake.js .............................
.333 31 Ok [100.00%]
dhcp1031224-176:webmake medikoo$ node --version
v0.6.18
dhcp1031224-176:webmake medikoo$ npm --version
1.1.21
I was finally able to try the latest version (0.3.11):
The issue I described above is indeed fixed and the path is now correct. However, the tests are still not running, which is not really a problem for me right now, but I thought I would let you know:
These are the dependencies that are installed (npm install
in the webmake directory):
deferred@0.5.6 ./node_modules/deferred
es5-ext@0.8.2 ./node_modules/es5-ext
optimist@0.3.4 ./node_modules/optimist
└── wordwrap@0.0.2
tad@0.1.9 ./node_modules/tad
├── event-emitter@0.1.4
├── duration@0.1.0
├── clock@0.1.4
├── cli-color@0.1.7
└── test@0.4.4
find-requires@0.1.2 ./node_modules/find-requires
└── esprima@0.9.9
next@0.2.14 ./node_modules/next
├── event-emitter@0.1.4
└── minimatch@0.2.5 (lru-cache@1.1.0)
Running npm test
creates this output:
± npm test
> webmake@0.3.11 test /usr/local/lib/node_modules/webmake
> node ./node_modules/tad/bin/tad lib
09:54:32.952 ✗ parser.js
Error: Cannot require "path". Native node.js modules are not ported to client-side. You can however provide alternative version of this module in your node_modules path, it will be picked up by Webmake
at Object.<anonymous> (/usr/local/lib/node_modules/webmake/lib/parser.js:200:13)
at native
at /usr/local/lib/node_modules/webmake/node_modules/es5-ext/lib/Function/prototype/silent.js:10:17
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/promisify-sync.js:13:43
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/_promisify.js:36:17
at Object.resolveExternal (/usr/local/lib/node_modules/webmake/lib/parser.js:220:15)
at Object.resolve (/usr/local/lib/node_modules/webmake/lib/parser.js:115:16)
at native
at Object.self [as processValue] (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:59:18)
at Object.iterate (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:42:16)
09:54:32.978 ✗ webmake.js
Error: Cannot require "path". Native node.js modules are not ported to client-side. You can however provide alternative version of this module in your node_modules path, it will be picked up by Webmake
at Object.<anonymous> (/usr/local/lib/node_modules/webmake/lib/parser.js:200:13)
at native
at /usr/local/lib/node_modules/webmake/node_modules/es5-ext/lib/Function/prototype/silent.js:10:17
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/promisify-sync.js:13:43
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/_promisify.js:36:17
at Object.resolveExternal (/usr/local/lib/node_modules/webmake/lib/parser.js:220:15)
at Object.resolve (/usr/local/lib/node_modules/webmake/lib/parser.js:115:16)
at native
at Object.self [as processValue] (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:59:18)
at Object.iterate (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:42:16)
09:54:32.994 ✓ webmake.js .....
.098 5 Ok [71.43%] 2 Failed
npm ERR! webmake@0.3.11 test: `node ./node_modules/tad/bin/tad lib`
npm ERR! `sh "-c" "node ./node_modules/tad/bin/tad lib"` failed with 1
npm ERR!
npm ERR! Failed at the webmake@0.3.11 test script.
npm ERR! This is most likely a problem with the webmake package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node ./node_modules/tad/bin/tad lib
npm ERR! You can get their info via:
npm ERR! npm owner ls webmake
npm ERR! There is likely additional logging output above.
npm ERR!
npm ERR! System Darwin 11.4.0
npm ERR! command "node" "/usr/local/bin/npm" "test"
npm ERR! cwd /usr/local/lib/node_modules/webmake
npm ERR! node -v v0.6.18
npm ERR! npm -v 1.1.21
npm ERR! code ELIFECYCLE
npm ERR! message webmake@0.3.11 test: `node ./node_modules/tad/bin/tad lib`
npm ERR! message `sh "-c" "node ./node_modules/tad/bin/tad lib"` failed with 1
npm ERR! errno {}
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /usr/local/lib/node_modules/webmake/npm-debug.log
npm not ok
I compared the package versions and it seems to be all the same, so I'm a bit lost as to why it would be broken.
It's very weird. I'm testing exactly same setup as yours (OSX System Darwin 11.4.0, node -v v0.6.18, npm -v 1.1.21) and I have 100% pass. I've tried reinstalling clean Node.js and clean Webmake, and same 100% pass.
On your side it looks as if tests from version pre v0.3.11 test version v0.3.11
Can you add two logs to your Webmake installation, and test with that?
Into this section https://github.com/medikoo/modules-webmake/blob/master/lib/parser.js#L193-198 this two logs: https://gist.github.com/240a621a2bd2ccabafb1 Then let me know what they return when you run the tests. You will see two white logs among green/red test results. If you won't see any white logs it will mean that you didn't edit webmake installation that you were testing.
Please let me know what you see. Thanks!
ok, finally got around to doing this.
The log output is quite large (over 2.4k lines). The whole output is below. Unfortunately github doesn't seem to allow to attach files to issues.
BTW: the 2nd log (Success) is never printed. There is also still this error:
Cannot require "path". Native node.js modules are not ported to client-side. You can however provide alternative version of this module in your node_modules path, it will be picked up by Webmake [...]
I hope this helps. If I can do something else to help, please let me know. (no more comments below the log output)
> webmake@0.3.11 test /usr/local/lib/node_modules/webmake
> node ./node_modules/tad/bin/tad lib
Deleted native | undefined | // 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 isWindows = process.platform === 'win32';
// resolves . and .. elements in a path array with directory names there
// 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)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
if (isWindows) {
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
// Regex to split the tail part of the above into [*, dir, basename, ext]
var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
// Function to split a filename into [root, dir, basename, ext]
// windows version
var splitPath = function(filename) {
// Separate device+slash from tail
var result = splitDeviceRe.exec(filename),
device = (result[1] || '') + (result[2] || ''),
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = splitTailRe.exec(tail),
dir = result2[1] || '',
basename = result2[2] || '',
ext = result2[3] || '';
return [device, dir, basename, ext];
};
// path.resolve([from ...], to)
// windows version
exports.resolve = function() {
var resolvedDevice = '',
resolvedTail = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1; i--) {
var path;
if (i >= 0) {
path = arguments[i];
} else if (!resolvedDevice) {
path = process.cwd();
} else {
// Windows has the concept of drive-specific current working
// directories. If we've resolved a drive letter but not yet an
// absolute path, get cwd for that drive. We're sure the device is not
// an unc path at this points, because unc paths are always absolute.
path = process.env['=' + resolvedDevice];
// Verify that a drive-local cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
if (!path || path.slice(0, 3).toLowerCase() !==
resolvedDevice.toLowerCase() + '\\') {
path = resolvedDevice + '\\';
}
}
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
var result = splitDeviceRe.exec(path),
device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3];
if (device &&
resolvedDevice &&
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
// This path points to another device so it is not applicable
continue;
}
if (!resolvedDevice) {
resolvedDevice = device;
}
if (!resolvedAbsolute) {
resolvedTail = tail + '\\' + resolvedTail;
resolvedAbsolute = isAbsolute;
}
if (resolvedDevice && resolvedAbsolute) {
break;
}
}
// Replace slashes (in UNC share name) by backslashes
resolvedDevice = resolvedDevice.replace(/\//g, '\\');
// At this point the path should be resolved to a full absolute path,
// but handle relative paths to be safe (might happen when process.cwd()
// fails)
// Normalize the tail path
function f(p) {
return !!p;
}
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
!resolvedAbsolute).join('\\');
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
'.';
};
// windows version
exports.normalize = function(path) {
var result = splitDeviceRe.exec(path),
device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3],
trailingSlash = /[\\\/]$/.test(tail);
// Normalize the tail path
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
return !!p;
}), !isAbsolute).join('\\');
if (!tail && !isAbsolute) {
tail = '.';
}
if (tail && trailingSlash) {
tail += '\\';
}
// Convert slashes to backslashes when `device` points to an UNC root.
device = device.replace(/\//g, '\\');
return device + (isAbsolute ? '\\' : '') + tail;
};
// windows version
exports.join = function() {
function f(p) {
return p && typeof p === 'string';
}
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
// - it will be mistaken for an unc path by normalize() -
// unless the paths[0] also starts with two slashes
if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(paths[0])) {
joined = joined.slice(1);
}
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 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 */ {
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
var splitPath = function(filename) {
var result = splitPathRe.exec(filename);
return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
// Normalize the path
path = normalizeArray(path.split('/').filter(function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(paths.filter(function(p, index) {
return p && typeof p === 'string';
}).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('/');
};
}
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substring(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
exports.exists = function(path, callback) {
process.binding('fs').stat(_makeLong(path), function(err, stats) {
if (callback) callback(err ? false : true);
});
};
exports.existsSync = function(path) {
try {
process.binding('fs').stat(_makeLong(path));
return true;
} catch (e) {
return false;
}
};
var _makeLong = exports._makeLong = isWindows ?
function(path) {
path = "" + path;
if (!path) {
return "";
}
var resolvedPath = exports.resolve(path);
if (resolvedPath.match(/^[a-zA-Z]\:\\/)) {
// path is local filesystem path, which needs to be converted
// to long UNC path.
return '\\\\?\\' + resolvedPath;
} else if (resolvedPath.match(/^\\\\[^?.]/)) {
// path is network UNC path, which needs to be converted
// to long UNC path.
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
}
return path;
} :
function(path) {
return path;
};
[31m23:26:59.021 ✗ parser.js
Error: Cannot require "path". Native node.js modules are not ported to client-side. You can however provide alternative version of this module in your node_modules path, it will be picked up by Webmake
at Object.<anonymous> (/usr/local/lib/node_modules/webmake/lib/parser.js:208:13)
at native
at /usr/local/lib/node_modules/webmake/node_modules/es5-ext/lib/Function/prototype/silent.js:10:17
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/promisify-sync.js:13:43
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/_promisify.js:36:17
at Object.resolveExternal (/usr/local/lib/node_modules/webmake/lib/parser.js:228:15)
at Object.resolve (/usr/local/lib/node_modules/webmake/lib/parser.js:115:16)
at native
at Object.self [as processValue] (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:59:18)
at Object.iterate (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:42:16)
[39mDeleted native | undefined | // 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 isWindows = process.platform === 'win32';
// resolves . and .. elements in a path array with directory names there
// 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)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
if (isWindows) {
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
// Regex to split the tail part of the above into [*, dir, basename, ext]
var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
// Function to split a filename into [root, dir, basename, ext]
// windows version
var splitPath = function(filename) {
// Separate device+slash from tail
var result = splitDeviceRe.exec(filename),
device = (result[1] || '') + (result[2] || ''),
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = splitTailRe.exec(tail),
dir = result2[1] || '',
basename = result2[2] || '',
ext = result2[3] || '';
return [device, dir, basename, ext];
};
// path.resolve([from ...], to)
// windows version
exports.resolve = function() {
var resolvedDevice = '',
resolvedTail = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1; i--) {
var path;
if (i >= 0) {
path = arguments[i];
} else if (!resolvedDevice) {
path = process.cwd();
} else {
// Windows has the concept of drive-specific current working
// directories. If we've resolved a drive letter but not yet an
// absolute path, get cwd for that drive. We're sure the device is not
// an unc path at this points, because unc paths are always absolute.
path = process.env['=' + resolvedDevice];
// Verify that a drive-local cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
if (!path || path.slice(0, 3).toLowerCase() !==
resolvedDevice.toLowerCase() + '\\') {
path = resolvedDevice + '\\';
}
}
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
var result = splitDeviceRe.exec(path),
device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3];
if (device &&
resolvedDevice &&
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
// This path points to another device so it is not applicable
continue;
}
if (!resolvedDevice) {
resolvedDevice = device;
}
if (!resolvedAbsolute) {
resolvedTail = tail + '\\' + resolvedTail;
resolvedAbsolute = isAbsolute;
}
if (resolvedDevice && resolvedAbsolute) {
break;
}
}
// Replace slashes (in UNC share name) by backslashes
resolvedDevice = resolvedDevice.replace(/\//g, '\\');
// At this point the path should be resolved to a full absolute path,
// but handle relative paths to be safe (might happen when process.cwd()
// fails)
// Normalize the tail path
function f(p) {
return !!p;
}
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
!resolvedAbsolute).join('\\');
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
'.';
};
// windows version
exports.normalize = function(path) {
var result = splitDeviceRe.exec(path),
device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3],
trailingSlash = /[\\\/]$/.test(tail);
// Normalize the tail path
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
return !!p;
}), !isAbsolute).join('\\');
if (!tail && !isAbsolute) {
tail = '.';
}
if (tail && trailingSlash) {
tail += '\\';
}
// Convert slashes to backslashes when `device` points to an UNC root.
device = device.replace(/\//g, '\\');
return device + (isAbsolute ? '\\' : '') + tail;
};
// windows version
exports.join = function() {
function f(p) {
return p && typeof p === 'string';
}
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
// - it will be mistaken for an unc path by normalize() -
// unless the paths[0] also starts with two slashes
if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(paths[0])) {
joined = joined.slice(1);
}
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 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 */ {
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
var splitPath = function(filename) {
var result = splitPathRe.exec(filename);
return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
// Normalize the path
path = normalizeArray(path.split('/').filter(function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(paths.filter(function(p, index) {
return p && typeof p === 'string';
}).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('/');
};
}
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substring(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
exports.exists = function(path, callback) {
process.binding('fs').stat(_makeLong(path), function(err, stats) {
if (callback) callback(err ? false : true);
});
};
exports.existsSync = function(path) {
try {
process.binding('fs').stat(_makeLong(path));
return true;
} catch (e) {
return false;
}
};
var _makeLong = exports._makeLong = isWindows ?
function(path) {
path = "" + path;
if (!path) {
return "";
}
var resolvedPath = exports.resolve(path);
if (resolvedPath.match(/^[a-zA-Z]\:\\/)) {
// path is local filesystem path, which needs to be converted
// to long UNC path.
return '\\\\?\\' + resolvedPath;
} else if (resolvedPath.match(/^\\\\[^?.]/)) {
// path is network UNC path, which needs to be converted
// to long UNC path.
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
}
return path;
} :
function(path) {
return path;
};
[31m23:26:59.055 ✗ webmake.js
Error: Cannot require "path". Native node.js modules are not ported to client-side. You can however provide alternative version of this module in your node_modules path, it will be picked up by Webmake
at Object.<anonymous> (/usr/local/lib/node_modules/webmake/lib/parser.js:208:13)
at native
at /usr/local/lib/node_modules/webmake/node_modules/es5-ext/lib/Function/prototype/silent.js:10:17
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/promisify-sync.js:13:43
at /usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/function/_promisify.js:36:17
at Object.resolveExternal (/usr/local/lib/node_modules/webmake/lib/parser.js:228:15)
at Object.resolve (/usr/local/lib/node_modules/webmake/lib/parser.js:115:16)
at native
at Object.self [as processValue] (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:59:18)
at Object.iterate (/usr/local/lib/node_modules/webmake/node_modules/deferred/lib/ext/array/map.js:42:16)
[39m[32m23:26:59.072 ✓ webmake.js .[39m[32m.[39m[32m.[39m[32m.[39mDeleted native | undefined | // 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.
// Maintainers, keep in mind that octal literals are not allowed
// in strict mode. Use the decimal value and add a comment with
// the octal value. Example:
//
// var mode = 438; /* mode=0666 */
var util = require('util');
var pathModule = require('path');
var binding = process.binding('fs');
var constants = process.binding('constants');
var fs = exports;
var Stream = require('stream').Stream;
var EventEmitter = require('events').EventEmitter;
var kMinPoolSpace = 128;
var kPoolSize = 40 * 1024;
fs.Stats = binding.Stats;
fs.Stats.prototype._checkModeProperty = function(property) {
return ((this.mode & constants.S_IFMT) === property);
};
fs.Stats.prototype.isDirectory = function() {
return this._checkModeProperty(constants.S_IFDIR);
};
fs.Stats.prototype.isFile = function() {
return this._checkModeProperty(constants.S_IFREG);
};
fs.Stats.prototype.isBlockDevice = function() {
return this._checkModeProperty(constants.S_IFBLK);
};
fs.Stats.prototype.isCharacterDevice = function() {
return this._checkModeProperty(constants.S_IFCHR);
};
fs.Stats.prototype.isSymbolicLink = function() {
return this._checkModeProperty(constants.S_IFLNK);
};
fs.Stats.prototype.isFIFO = function() {
return this._checkModeProperty(constants.S_IFIFO);
};
fs.Stats.prototype.isSocket = function() {
return this._checkModeProperty(constants.S_IFSOCK);
};
fs.readFile = function(path, encoding_) {
var encoding = typeof(encoding_) === 'string' ? encoding_ : null;
var callback = arguments[arguments.length - 1];
if (typeof(callback) !== 'function') callback = noop;
var readStream = fs.createReadStream(path);
var buffers = [];
var nread = 0;
var error;
readStream.on('data', function(chunk) {
buffers.push(chunk);
nread += chunk.length;
});
readStream.on('error', function(er) {
error = er;
readStream.destroy();
if (!readStream.fd) {
readStream.emit('close');
}
});
readStream.on('close', function() {
if (error) {
return callback(error);
}
// copy all the buffers into one
var buffer;
switch (buffers.length) {
case 0: buffer = new Buffer(0); break;
case 1: buffer = buffers[0]; break;
default: // concat together
buffer = new Buffer(nread);
var n = 0;
buffers.forEach(function(b) {
var l = b.length;
b.copy(buffer, n, 0, l);
n += l;
});
break;
}
if (encoding) {
try {
buffer = buffer.toString(encoding);
} catch (er) {
return callback(er);
}
}
callback(null, buffer);
});
};
fs.readFileSync = function(path, encoding) {
var fd = fs.openSync(path, constants.O_RDONLY, 438 /*=0666*/);
var buffer = new Buffer(4048);
var buffers = [];
var nread = 0;
var lastRead = 0;
try {
do {
if (lastRead) {
buffer._bytesRead = lastRead;
nread += lastRead;
buffers.push(buffer);
}
var buffer = new Buffer(4048);
lastRead = fs.readSync(fd, buffer, 0, buffer.length, null);
} while (lastRead > 0);
} finally {
fs.closeSync(fd);
}
if (buffers.length > 1) {
var offset = 0;
var i;
buffer = new Buffer(nread);
buffers.forEach(function(i) {
if (!i._bytesRead) return;
i.copy(buffer, offset, 0, i._bytesRead);
offset += i._bytesRead;
});
} else if (buffers.length) {
// buffers has exactly 1 (possibly zero length) buffer, so this should
// be a shortcut
buffer = buffers[0].slice(0, buffers[0]._bytesRead);
} else {
buffer = new Buffer(0);
}
if (encoding) buffer = buffer.toString(encoding);
return buffer;
};
// Used by binding.open and friends
function stringToFlags(flag) {
// Only mess with strings
if (typeof flag !== 'string') {
return flag;
}
switch (flag) {
case 'r':
return constants.O_RDONLY;
case 'r+':
return constants.O_RDWR;
case 'w':
return constants.O_CREAT | constants.O_TRUNC | constants.O_WRONLY;
case 'w+':
return constants.O_CREAT | constants.O_TRUNC | constants.O_RDWR;
case 'a':
return constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY;
case 'a+':
return constants.O_APPEND | constants.O_CREAT | constants.O_RDWR;
default:
throw new Error('Unknown file open flag: ' + flag);
}
}
function noop() {}
// Yes, the follow could be easily DRYed up but I provide the explicit
// list to make the arguments clear.
fs.close = function(fd, callback) {
binding.close(fd, callback || noop);
};
fs.closeSync = function(fd) {
return binding.close(fd);
};
function modeNum(m, def) {
switch (typeof m) {
case 'number': return m;
case 'string': return parseInt(m, 8);
default:
if (def) {
return modeNum(def);
} else {
return undefined;
}
}
}
fs.open = function(path, flags, mode, callback) {
callback = arguments[arguments.length - 1];
if (typeof(callback) !== 'function') {
callback = noop;
}
mode = modeNum(mode, 438 /*=0666*/);
binding.open(pathModule._makeLong(path), stringToFlags(flags), mode,
callback);
};
fs.openSync = function(path, flags, mode) {
mode = modeNum(mode, 438 /*=0666*/);
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
};
fs.read = function(fd, buffer, offset, length, position, callback) {
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, length, position, encoding, callback)
var cb = arguments[4],
encoding = arguments[3];
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);
offset = 0;
callback = function(err, bytesRead) {
if (!cb) return;
var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : '';
(cb)(err, str, bytesRead);
};
}
function wrapper(err, bytesRead) {
// Retain a reference to buffer so that it can't be GC'ed too soon.
callback && callback(err, bytesRead || 0, buffer);
}
binding.read(fd, buffer, offset, length, position, wrapper);
};
fs.readSync = function(fd, buffer, offset, length, position) {
var legacy = false;
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, length, position, encoding, callback)
legacy = true;
var encoding = arguments[3];
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);
offset = 0;
}
var r = binding.read(fd, buffer, offset, length, position);
if (!legacy) {
return r;
}
var str = (r > 0) ? buffer.toString(encoding, 0, r) : '';
return [str, r];
};
fs.write = function(fd, buffer, offset, length, position, callback) {
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, data, position, encoding, callback)
callback = arguments[4];
position = arguments[2];
buffer = new Buffer('' + arguments[1], arguments[3]);
offset = 0;
length = buffer.length;
}
if (!length) {
if (typeof callback == 'function') {
process.nextTick(function() {
callback(undefined, 0);
});
}
return;
}
function wrapper(err, written) {
// Retain a reference to buffer so that it can't be GC'ed too soon.
callback && callback(err, written || 0, buffer);
}
binding.write(fd, buffer, offset, length, position, wrapper);
};
fs.writeSync = function(fd, buffer, offset, length, position) {
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, data, position, encoding)
position = arguments[2];
buffer = new Buffer('' + arguments[1], arguments[3]);
offset = 0;
length = buffer.length;
}
if (!length) return 0;
return binding.write(fd, buffer, offset, length, position);
};
fs.rename = function(oldPath, newPath, callback) {
binding.rename(pathModule._makeLong(oldPath), pathModule._makeLong(newPath),
callback || noop);
};
fs.renameSync = function(oldPath, newPath) {
return binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath));
};
fs.truncate = function(fd, len, callback) {
binding.truncate(fd, len, callback || noop);
};
fs.truncateSync = function(fd, len) {
return binding.truncate(fd, len);
};
fs.rmdir = function(path, callback) {
binding.rmdir(pathModule._makeLong(path), callback || noop);
};
fs.rmdirSync = function(path) {
return binding.rmdir(pathModule._makeLong(path));
};
fs.fdatasync = function(fd, callback) {
binding.fdatasync(fd, callback || noop);
};
fs.fdatasyncSync = function(fd) {
return binding.fdatasync(fd);
};
fs.fsync = function(fd, callback) {
binding.fsync(fd, callback || noop);
};
fs.fsyncSync = function(fd) {
return binding.fsync(fd);
};
fs.mkdir = function(path, mode, callback) {
if (typeof mode === 'function') callback = mode;
binding.mkdir(pathModule._makeLong(path), modeNum(mode, 511 /*=0777*/),
callback || noop);
};
fs.mkdirSync = function(path, mode) {
return binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/));
};
fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
binding.sendfile(outFd, inFd, inOffset, length, callback || noop);
};
fs.sendfileSync = function(outFd, inFd, inOffset, length) {
return binding.sendfile(outFd, inFd, inOffset, length);
};
fs.readdir = function(path, callback) {
binding.readdir(pathModule._makeLong(path), callback || noop);
};
fs.readdirSync = function(path) {
return binding.readdir(pathModule._makeLong(path));
};
fs.fstat = function(fd, callback) {
binding.fstat(fd, callback || noop);
};
fs.lstat = function(path, callback) {
binding.lstat(pathModule._makeLong(path), callback || noop);
};
fs.stat = function(path, callback) {
binding.stat(pathModule._makeLong(path), callback || noop);
};
fs.fstatSync = function(fd) {
return binding.fstat(fd);
};
fs.lstatSync = function(path) {
return binding.lstat(pathModule._makeLong(path));
};
fs.statSync = function(path) {
return binding.stat(pathModule._makeLong(path));
};
fs.readlink = function(path, callback) {
binding.readlink(pathModule._makeLong(path), callback || noop);
};
fs.readlinkSync = function(path) {
return binding.readlink(pathModule._makeLong(path));
};
fs.symlink = function(destination, path, type_, callback) {
var type = (typeof(type_) == 'string' ? type_ : null);
var callback_ = arguments[arguments.length - 1];
callback = (typeof(callback_) == 'function' ? callback_ : null);
binding.symlink(pathModule._makeLong(destination),
pathModule._makeLong(path), type, callback);
};
fs.symlinkSync = function(destination, path, type) {
return binding.symlink(pathModule._makeLong(destination),
pathModule._makeLong(path), type);
};
fs.link = function(srcpath, dstpath, callback) {
binding.link(pathModule._makeLong(srcpath), pathModule._makeLong(dstpath),
callback || noop);
};
fs.linkSync = function(srcpath, dstpath) {
return binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath));
};
fs.unlink = function(path, callback) {
binding.unlink(pathModule._makeLong(path), callback || noop);
};
fs.unlinkSync = function(path) {
return binding.unlink(pathModule._makeLong(path));
};
fs.fchmod = function(fd, mode, callback) {
binding.fchmod(fd, modeNum(mode), callback || noop);
};
fs.fchmodSync = function(fd, mode) {
return binding.fchmod(fd, modeNum(mode));
};
if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchmod = function(path, mode, callback) {
callback = callback || noop;
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
return;
}
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
fs.fchmod(fd, mode, function(err) {
fs.close(fd, function(err2) {
callback(err || err2);
});
});
});
};
fs.lchmodSync = function(path, mode) {
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
var err, err2;
try {
var ret = fs.fchmodSync(fd, mode);
} catch (er) {
err = er;
}
try {
fs.closeSync(fd);
} catch (er) {
err2 = er;
}
if (err || err2) throw (err || err2);
return ret;
};
}
fs.chmod = function(path, mode, callback) {
binding.chmod(pathModule._makeLong(path), modeNum(mode), callback || noop);
};
fs.chmodSync = function(path, mode) {
return binding.chmod(pathModule._makeLong(path), modeNum(mode));
};
if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchown = function(path, uid, gid, callback) {
callback = callback || noop;
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
return;
}
fs.fchown(fd, uid, gid, callback);
});
};
fs.lchownSync = function(path, uid, gid) {
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
return fs.fchownSync(fd, uid, gid);
};
}
fs.fchown = function(fd, uid, gid, callback) {
binding.fchown(fd, uid, gid, callback || noop);
};
fs.fchownSync = function(fd, uid, gid) {
return binding.fchown(fd, uid, gid);
};
fs.chown = function(path, uid, gid, callback) {
binding.chown(pathModule._makeLong(path), uid, gid, callback || noop);
};
fs.chownSync = function(path, uid, gid) {
return binding.chown(pathModule._makeLong(path), uid, gid);
};
// converts Date or number to a fractional UNIX timestamp
function toUnixTimestamp(time) {
if (typeof time == 'number') {
return time;
}
if (time instanceof Date) {
// convert to 123.456 UNIX timestamp
return time.getTime() / 1000;
}
throw new Error('Cannot parse time: ' + time);
}
// exported for unit tests, not for public consumption
fs._toUnixTimestamp = toUnixTimestamp;
fs.utimes = function(path, atime, mtime, callback) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(pathModule._makeLong(path), atime, mtime, callback || noop);
};
fs.utimesSync = function(path, atime, mtime) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(pathModule._makeLong(path), atime, mtime);
};
fs.futimes = function(fd, atime, mtime, callback) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.futimes(fd, atime, mtime, callback || noop);
};
fs.futimesSync = function(fd, atime, mtime) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.futimes(fd, atime, mtime);
};
function writeAll(fd, buffer, offset, length, callback) {
// write(fd, buffer, offset, length, position, callback)
fs.write(fd, buffer, offset, length, offset, function(writeErr, written) {
if (writeErr) {
fs.close(fd, function() {
if (callback) callback(writeErr);
});
} else {
if (written === length) {
fs.close(fd, callback);
} else {
writeAll(fd, buffer, offset + written, length - written, callback);
}
}
});
}
fs.writeFile = function(path, data, encoding_, callback) {
var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
var callback_ = arguments[arguments.length - 1];
callback = (typeof(callback_) == 'function' ? callback_ : null);
fs.open(path, 'w', 438 /*=0666*/, function(openErr, fd) {
if (openErr) {
if (callback) callback(openErr);
} else {
var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data,
encoding);
writeAll(fd, buffer, 0, buffer.length, callback);
}
});
};
fs.writeFileSync = function(path, data, encoding) {
var fd = fs.openSync(path, 'w');
if (!Buffer.isBuffer(data)) {
data = new Buffer('' + data, encoding || 'utf8');
}
var written = 0;
var length = data.length;
try {
while (written < length) {
written += fs.writeSync(fd, data, written, length - written, written);
}
} finally {
fs.closeSync(fd);
}
};
function errnoException(errorno, syscall) {
// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
var e = new Error(syscall + ' ' + errorno);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}
function FSWatcher() {
var self = this;
var FSEvent = process.binding('fs_event_wrap').FSEvent;
this._handle = new FSEvent();
this._handle.onchange = function(status, event, filename) {
if (status) {
self._handle.close();
self.emit('error', errnoException(errno, 'watch'));
} else {
self.emit('change', event, filename);
}
};
}
util.inherits(FSWatcher, EventEmitter);
FSWatcher.prototype.start = function(filename, persistent) {
var r = this._handle.start(pathModule._makeLong(filename), persistent);
if (r) {
this._handle.close();
throw errnoException(errno, 'watch');
}
};
FSWatcher.prototype.close = function() {
this._handle.close();
};
fs.watch = function(filename) {
var watcher;
var options;
var listener;
if ('object' == typeof arguments[1]) {
options = arguments[1];
listener = arguments[2];
} else {
options = {};
listener = arguments[1];
}
if (!listener) {
throw new Error('watch requires a listener function');
}
if (options.persistent === undefined) options.persistent = true;
watcher = new FSWatcher();
watcher.start(filename, options.persistent);
watcher.addListener('change', listener);
return watcher;
};
// Stat Change Watchers
function StatWatcher() {
var self = this;
this._handle = new binding.StatWatcher();
this._handle.onchange = function(current, previous) {
self.emit('change', current, previous);
};
this._handle.onstop = function() {
self.emit('stop');
};
}
util.inherits(StatWatcher, EventEmitter);
StatWatcher.prototype.start = function(filename, persistent, interval) {
this._handle.start(pathModule._makeLong(filename), persistent, interval);
};
StatWatcher.prototype.stop = function() {
this._handle.stop();
};
var statWatchers = {};
function inStatWatchers(filename) {
return Object.prototype.hasOwnProperty.call(statWatchers, filename) &&
statWatchers[filename];
}
fs.watchFile = function(filename) {
if (isWindows) {
throw new Error('use fs.watch api instead');
}
var stat;
var options;
var listener;
if ('object' == typeof arguments[1]) {
options = arguments[1];
listener = arguments[2];
} else {
options = {};
listener = arguments[1];
}
if (!listener) {
throw new Error('watchFile requires a listener function');
}
if (options.persistent === undefined) options.persistent = true;
if (options.interval === undefined) options.interval = 0;
if (inStatWatchers(filename)) {
stat = statWatchers[filename];
} else {
stat = statWatchers[filename] = new StatWatcher();
stat.start(filename, options.persistent, options.interval);
}
stat.addListener('change', listener);
return stat;
};
fs.unwatchFile = function(filename) {
var stat;
if (inStatWatchers(filename)) {
stat = statWatchers[filename];
stat.stop();
statWatchers[filename] = undefined;
}
};
// Realpath
// Not using realpath(2) because it's bad.
// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
var normalize = pathModule.normalize,
isWindows = process.platform === 'win32';
if (isWindows) {
// Node doesn't support symlinks / lstat on windows. Hence realpath is just
// the same as path.resolve that fails if the path doesn't exists.
// windows version
fs.realpathSync = function realpathSync(p, cache) {
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return cache[p];
}
fs.statSync(p);
if (cache) cache[p] = p;
return p;
};
// windows version
fs.realpath = function(p, cache, cb) {
if (typeof cb !== 'function') {
cb = cache;
cache = null;
}
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return cb(null, cache[p]);
}
fs.stat(p, function(err) {
if (err) return cb(err);
if (cache) cache[p] = p;
cb(null, p);
});
};
} else /* posix */ {
// Regexp that finds the next partion of a (partial) path
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
var nextPartRe = /(.*?)(?:[\/]+|$)/g;
// posix version
fs.realpathSync = function realpathSync(p, cache) {
// make p is absolute
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return cache[p];
}
var original = p,
seenLinks = {},
knownHard = {};
// current character position in p
var pos = 0;
// the partial path so far, including a trailing slash if any
var current = '';
// the partial path without a trailing slash
var base = '';
// the partial path scanned in the previous round, with slash
var previous = '';
// walk down the path, swapping out linked pathparts for their real
// values
// NB: p.length changes.
while (pos < p.length) {
// find the next part
nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;
// continue if not a symlink, or if root
if (!base || knownHard[base] || (cache && cache[base] === base)) {
continue;
}
var resolvedLink;
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// some known symbolic link. no need to stat again.
resolvedLink = cache[base];
} else {
var stat = fs.lstatSync(base);
if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
continue;
}
// read the link if it wasn't read before
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (!seenLinks[id]) {
fs.statSync(base);
seenLinks[id] = fs.readlinkSync(base);
resolvedLink = pathModule.resolve(previous, seenLinks[id]);
// track this, if given a cache.
if (cache) cache[base] = resolvedLink;
}
}
// resolve the link, then start over
p = pathModule.resolve(resolvedLink, p.slice(pos));
pos = 0;
previous = base = current = '';
}
if (cache) cache[original] = p;
return p;
};
// posix version
fs.realpath = function realpath(p, cache, cb) {
if (typeof cb !== 'function') {
cb = cache;
cache = null;
}
// make p is absolute
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return cb(null, cache[p]);
}
var original = p,
seenLinks = {},
knownHard = {};
// current character position in p
var pos = 0;
// the partial path so far, including a trailing slash if any
var current = '';
// the partial path without a trailing slash
var base = '';
// the partial path scanned in the previous round, with slash
var previous = '';
// walk down the path, swapping out linked pathparts for their real
// values
LOOP();
function LOOP() {
// stop if scanned past end of path
if (pos >= p.length) {
if (cache) cache[original] = p;
return cb(null, p);
}
// find the next part
nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;
// continue if known to be hard or if root or in cache already.
if (!base || knownHard[base] || (cache && cache[base] === base)) {
return process.nextTick(LOOP);
}
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// known symbolic link. no need to stat again.
return gotResolvedLink(cache[base]);
}
return fs.lstat(base, gotStat);
}
function gotStat(err, stat) {
if (err) return cb(err);
// if not a symlink, skip to the next path part
if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
return process.nextTick(LOOP);
}
// stat & read the link if not read before
// call gotTarget as soon as the link target is known
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (seenLinks[id]) {
return gotTarget(null, seenLinks[id], base);
}
fs.stat(base, function(err) {
if (err) return cb(err);
fs.readlink(base, function(err, target) {
gotTarget(err, seenLinks[id] = target);
});
});
}
function gotTarget(err, target, base) {
if (err) return cb(err);
var resolvedLink = pathModule.resolve(previous, target);
if (cache) cache[base] = resolvedLink;
gotResolvedLink(resolvedLink);
}
function gotResolvedLink(resolvedLink) {
// resolve the link, then start over
p = pathModule.resolve(resolvedLink, p.slice(pos));
pos = 0;
previous = base = current = '';
return process.nextTick(LOOP);
}
};
}
var pool;
function allocNewPool() {
pool = new Buffer(kPoolSize);
pool.used = 0;
}
fs.createReadStream = function(path, options) {
return new ReadStream(path, options);
};
var ReadStream = fs.ReadStream = function(path, options) {
if (!(this instanceof ReadStream)) return new ReadStream(path, options);
Stream.call(this);
var self = this;
this.path = path;
this.fd = null;
this.readable = true;
this.paused = false;
this.flags = 'r';
this.mode = 438; /*=0666*/
this.bufferSize = 64 * 1024;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.encoding) this.setEncoding(this.encoding);
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.end === undefined) {
this.end = Infinity;
} else if ('number' !== typeof this.end) {
throw TypeError('end must be a Number');
}
if (this.start > this.end) {
throw new Error('start must be <= end');
}
this.pos = this.start;
}
if (this.fd !== null) {
this._read();
return;
}
fs.open(this.path, this.flags, this.mode, function(err, fd) {
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
self.fd = fd;
self.emit('open', fd);
self._read();
});
};
util.inherits(ReadStream, Stream);
fs.FileReadStream = fs.ReadStream; // support the legacy name
ReadStream.prototype.setEncoding = function(encoding) {
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder(encoding);
};
ReadStream.prototype._read = function() {
var self = this;
if (!this.readable || this.paused || this.reading) return;
this.reading = true;
if (!pool || pool.length - pool.used < kMinPoolSpace) {
// discard the old pool. Can't add to the free list because
// users might have refernces to slices on it.
pool = null;
allocNewPool();
}
// Grab another reference to the pool in the case that while we're in the
// thread pool another read() finishes up the pool, and allocates a new
// one.
var thisPool = pool;
var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize);
var start = pool.used;
if (this.pos !== undefined) {
toRead = Math.min(this.end - this.pos + 1, toRead);
}
function afterRead(err, bytesRead) {
self.reading = false;
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
if (bytesRead === 0) {
self.emit('end');
self.destroy();
return;
}
var b = thisPool.slice(start, start + bytesRead);
// Possible optimizition here?
// Reclaim some bytes if bytesRead < toRead?
// Would need to ensure that pool === thisPool.
// do not emit events if the stream is paused
if (self.paused) {
self.buffer = b;
return;
}
// do not emit events anymore after we declared the stream unreadable
if (!self.readable) return;
self._emitData(b);
self._read();
}
fs.read(this.fd, pool, pool.used, toRead, this.pos, afterRead);
if (this.pos !== undefined) {
this.pos += toRead;
}
pool.used += toRead;
};
ReadStream.prototype._emitData = function(d) {
if (this._decoder) {
var string = this._decoder.write(d);
if (string.length) this.emit('data', string);
} else {
this.emit('data', d);
}
};
ReadStream.prototype.destroy = function(cb) {
var self = this;
if (!this.readable) return;
this.readable = false;
function close() {
fs.close(self.fd, function(err) {
if (err) {
if (cb) cb(err);
self.emit('error', err);
return;
}
if (cb) cb(null);
self.emit('close');
});
}
if (this.fd === null) {
this.addListener('open', close);
} else {
close();
}
};
ReadStream.prototype.pause = function() {
this.paused = true;
};
ReadStream.prototype.resume = function() {
this.paused = false;
if (this.buffer) {
var buffer = this.buffer;
this.buffer = null;
this._emitData(buffer);
}
// hasn't opened yet.
if (null == this.fd) return;
this._read();
};
fs.createWriteStream = function(path, options) {
return new WriteStream(path, options);
};
var WriteStream = fs.WriteStream = function(path, options) {
if (!(this instanceof WriteStream)) return new WriteStream(path, options);
Stream.call(this);
this.path = path;
this.fd = null;
this.writable = true;
this.flags = 'w';
this.encoding = 'binary';
this.mode = 438; /*=0666*/
this.bytesWritten = 0;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.start < 0) {
throw new Error('start must be >= zero');
}
this.pos = this.start;
}
this.busy = false;
this._queue = [];
if (this.fd === null) {
this._open = fs.open;
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
this.flush();
}
};
util.inherits(WriteStream, Stream);
fs.FileWriteStream = fs.WriteStream; // support the legacy name
WriteStream.prototype.flush = function() {
if (this.busy) return;
var self = this;
var args = this._queue.shift();
if (!args) {
if (this.drainable) { this.emit('drain'); }
return;
}
this.busy = true;
var method = args.shift(),
cb = args.pop();
args.push(function(err) {
self.busy = false;
if (err) {
self.writable = false;
if (cb) {
cb(err);
}
self.emit('error', err);
return;
}
if (method == fs.write) {
self.bytesWritten += arguments[1];
if (cb) {
// write callback
cb(null, arguments[1]);
}
} else if (method === self._open) {
// save reference for file pointer
self.fd = arguments[1];
self.emit('open', self.fd);
} else if (method === fs.close) {
// stop flushing after close
if (cb) {
cb(null);
}
self.emit('close');
return;
}
self.flush();
});
// Inject the file pointer
if (method !== self._open) {
args.unshift(this.fd);
}
method.apply(this, args);
};
WriteStream.prototype.write = function(data) {
if (!this.writable) {
this.emit('error', new Error('stream not writable'));
return false;
}
this.drainable = true;
var cb;
if (typeof(arguments[arguments.length - 1]) == 'function') {
cb = arguments[arguments.length - 1];
}
if (!Buffer.isBuffer(data)) {
var encoding = 'utf8';
if (typeof(arguments[1]) == 'string') encoding = arguments[1];
data = new Buffer('' + data, encoding);
}
this._queue.push([fs.write, data, 0, data.length, this.pos, cb]);
if (this.pos !== undefined) {
this.pos += data.length;
}
this.flush();
return false;
};
WriteStream.prototype.end = function(data, encoding, cb) {
if (typeof(data) === 'function') {
cb = data;
} else if (typeof(encoding) === 'function') {
cb = encoding;
this.write(data);
} else if (arguments.length > 0) {
this.write(data, encoding);
}
this.writable = false;
this._queue.push([fs.close, cb]);
this.flush();
};
WriteStream.prototype.destroy = function(cb) {
var self = this;
if (!this.writable) return;
this.writable = false;
function close() {
fs.close(self.fd, function(err) {
if (err) {
if (cb) { cb(err); }
self.emit('error', err);
return;
}
if (cb) { cb(null); }
self.emit('close');
});
}
if (this.fd === null) {
this.addListener('open', close);
} else {
close();
}
};
// There is no shutdown() for files.
WriteStream.prototype.destroySoon = WriteStream.prototype.end;
// SyncWriteStream is internal. DO NOT USE.
// Temporary hack for process.stdout and process.stderr when piped to files.
function SyncWriteStream(fd) {
this.fd = fd;
this.writable = true;
this.readable = false;
};
util.inherits(SyncWriteStream, Stream);
// Export
fs.SyncWriteStream = SyncWriteStream;
SyncWriteStream.prototype.write = function(data, arg1, arg2) {
var encoding, cb;
// parse arguments
if (arg1) {
if (typeof arg1 === 'string') {
encoding = arg1;
cb = arg2;
} else if (typeof arg1 === 'function') {
cb = arg1;
} else {
throw new Error("bad arg");
}
}
// Change strings to buffers. SLOW
if (typeof data == 'string') {
data = new Buffer(data, encoding);
}
fs.writeSync(this.fd, data, 0, data.length);
if (cb) {
process.nextTick(cb);
}
return true;
};
SyncWriteStream.prototype.end = function(data, arg1, arg2) {
if (data) {
this.write(data, arg1, arg2);
}
this.destroy();
};
SyncWriteStream.prototype.destroy = function() {
fs.closeSync(this.fd);
this.fd = null;
this.emit('close');
return true;
};
SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy;
[32m.[39m
[36m .109 [39m[32m5 Ok [71.43%][39m [31m2 Failed[39m
Great thanks. I get what's the problem. What's funny is that never printed success line gave me a clue, and log above is as I would expect :)
Issue lies within npm version that comes with v0.6.18 and maybe few previous versions. This issue was fixed with npm that comes with v0.6.19. It doesn't affect Webmake itself but its tests, so you can be sure that although tests fails Webmake works properly on v0.6.18
Problem is that npm at some point started ignoring (not copying with install) all nested _nodemodules paths that comes within packages. In Webmake, in test folder there's __playground folder which holds such folder, and this one was not copied and therefore tests didn't work.
It worked on my side as I used Webmake already installed with other version or was testing directly on my repository.
To fix it just upgrade Node to at least v0.6.19 and then do npm cache clean
and npm install webmake
again.
I was about to write again that this is still not working, even after removing the node version that comes with brew.
I reinstalled node and npm from the distributed package as I started using nvm as per your recommendation (1st impression: very neat, thanks). Initially it was still not working until I realised that I didn't do npm cache clean
.
Now that I've cleaned the cache & reinstalled webmake, all is working as expected:
± npm test
> webmake@0.3.11 test /usr/local/lib/node_modules/webmake
> node ./node_modules/tad/bin/tad lib
21:37:26.358 ✓ parser.js ..
21:37:26.431 ✓ webmake.js ..............................
.271 32 Ok [100.00%]
I'm looking forward to be using npm!
BTW: do you have a project on github that uses webmake? I would be interested in checking how you set the workflow/structure up.
Thanks for all your help!
I'm glad it works :)
I have one client-side project on github that uses Webmake, and makes great example: https://github.com/medikoo/soundcloud-playlist-manager
In my work we have application that's build with Webmake from over 200 modules from about 12 packages, unfortunately due to policy of my company I cannot share that. This project is both server and client side, and files are organized so strictly server-side code lands in lib/server
folder and strictly client-side code in lib/client
, code that is shared on both sides lies elsewhere. You can build really large projects with it.
I am using webmake on the cli. This is the command I'm using:
The output of the buildfile is along these lines:
This fails. When I manually edit the path on the last line to
"/path/to/main.js"
, it all works fine.I had a bit of a look around the webmake source:
The issue happens in the
parser.js#readInput()
method where the path is created. Thename
var is set to/
and the separator is set to/
as well, which leads to the wrong path.I installed webmake with the dev dependencies to run the tests. This is the output:
I'm on OSX with node 0.6.18, npm 1.1.21 and webmake 0.3.9.
Is this a known issue? I can currently hack my way around by changing the path, but since I don't know webmake in detail I'm likely missing some edge cases.