You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2017/05/25 20:38:32 UTC
[12/25] cordova-browser git commit: update shelljs version,
prepare is working
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/chmod.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/chmod.js b/node_modules/shelljs/src/chmod.js
index 6c6de10..ce5659e 100644
--- a/node_modules/shelljs/src/chmod.js
+++ b/node_modules/shelljs/src/chmod.js
@@ -4,35 +4,37 @@ var path = require('path');
var PERMS = (function (base) {
return {
- OTHER_EXEC : base.EXEC,
- OTHER_WRITE : base.WRITE,
- OTHER_READ : base.READ,
+ OTHER_EXEC: base.EXEC,
+ OTHER_WRITE: base.WRITE,
+ OTHER_READ: base.READ,
- GROUP_EXEC : base.EXEC << 3,
- GROUP_WRITE : base.WRITE << 3,
- GROUP_READ : base.READ << 3,
+ GROUP_EXEC: base.EXEC << 3,
+ GROUP_WRITE: base.WRITE << 3,
+ GROUP_READ: base.READ << 3,
- OWNER_EXEC : base.EXEC << 6,
- OWNER_WRITE : base.WRITE << 6,
- OWNER_READ : base.READ << 6,
+ OWNER_EXEC: base.EXEC << 6,
+ OWNER_WRITE: base.WRITE << 6,
+ OWNER_READ: base.READ << 6,
- // Literal octal numbers are apparently not allowed in "strict" javascript. Using parseInt is
- // the preferred way, else a jshint warning is thrown.
- STICKY : parseInt('01000', 8),
- SETGID : parseInt('02000', 8),
- SETUID : parseInt('04000', 8),
+ // Literal octal numbers are apparently not allowed in "strict" javascript.
+ STICKY: parseInt('01000', 8),
+ SETGID: parseInt('02000', 8),
+ SETUID: parseInt('04000', 8),
- TYPE_MASK : parseInt('0770000', 8)
+ TYPE_MASK: parseInt('0770000', 8),
};
-})({
- EXEC : 1,
- WRITE : 2,
- READ : 4
+}({
+ EXEC: 1,
+ WRITE: 2,
+ READ: 4,
+}));
+
+common.register('chmod', _chmod, {
});
//@
-//@ ### chmod(octal_mode || octal_string, file)
-//@ ### chmod(symbolic_mode, file)
+//@ ### chmod([options,] octal_mode || octal_string, file)
+//@ ### chmod([options,] symbolic_mode, file)
//@
//@ Available options:
//@
@@ -46,6 +48,7 @@ var PERMS = (function (base) {
//@ chmod(755, '/Users/brandon');
//@ chmod('755', '/Users/brandon'); // same as above
//@ chmod('u+x', '/Users/brandon');
+//@ chmod('-R', 'a-w', '/Users/brandon');
//@ ```
//@
//@ Alters the permissions of a file or directory by either specifying the
@@ -62,11 +65,8 @@ function _chmod(options, mode, filePattern) {
// Special case where the specified file permissions started with - to subtract perms, which
// get picked up by the option parser as command flags.
// If we are down by one argument and options starts with -, shift everything over.
- filePattern = mode;
- mode = options;
- options = '';
- }
- else {
+ [].unshift.call(arguments, '');
+ } else {
common.error('You must specify a file.');
}
}
@@ -74,18 +74,17 @@ function _chmod(options, mode, filePattern) {
options = common.parseOptions(options, {
'R': 'recursive',
'c': 'changes',
- 'v': 'verbose'
+ 'v': 'verbose',
});
- if (typeof filePattern === 'string') {
- filePattern = [ filePattern ];
- }
+ filePattern = [].slice.call(arguments, 2);
var files;
+ // TODO: replace this with a call to common.expand()
if (options.recursive) {
files = [];
- common.expand(filePattern).forEach(function addFile(expandedFile) {
+ filePattern.forEach(function addFile(expandedFile) {
var stat = fs.lstatSync(expandedFile);
if (!stat.isSymbolicLink()) {
@@ -98,9 +97,8 @@ function _chmod(options, mode, filePattern) {
}
}
});
- }
- else {
- files = common.expand(filePattern);
+ } else {
+ files = filePattern;
}
files.forEach(function innerChmod(file) {
@@ -124,7 +122,6 @@ function _chmod(options, mode, filePattern) {
if (isNaN(parseInt(mode, 8))) {
// parse options
mode.split(',').forEach(function (symbolicMode) {
- /*jshint regexdash:true */
var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i;
var matches = pattern.exec(symbolicMode);
@@ -133,19 +130,20 @@ function _chmod(options, mode, filePattern) {
var operator = matches[2];
var change = matches[3];
- var changeOwner = applyTo.indexOf('u') != -1 || applyTo === 'a' || applyTo === '';
- var changeGroup = applyTo.indexOf('g') != -1 || applyTo === 'a' || applyTo === '';
- var changeOther = applyTo.indexOf('o') != -1 || applyTo === 'a' || applyTo === '';
+ var changeOwner = applyTo.indexOf('u') !== -1 || applyTo === 'a' || applyTo === '';
+ var changeGroup = applyTo.indexOf('g') !== -1 || applyTo === 'a' || applyTo === '';
+ var changeOther = applyTo.indexOf('o') !== -1 || applyTo === 'a' || applyTo === '';
- var changeRead = change.indexOf('r') != -1;
- var changeWrite = change.indexOf('w') != -1;
- var changeExec = change.indexOf('x') != -1;
- var changeExecDir = change.indexOf('X') != -1;
- var changeSticky = change.indexOf('t') != -1;
- var changeSetuid = change.indexOf('s') != -1;
+ var changeRead = change.indexOf('r') !== -1;
+ var changeWrite = change.indexOf('w') !== -1;
+ var changeExec = change.indexOf('x') !== -1;
+ var changeExecDir = change.indexOf('X') !== -1;
+ var changeSticky = change.indexOf('t') !== -1;
+ var changeSetuid = change.indexOf('s') !== -1;
- if (changeExecDir && isDir)
+ if (changeExecDir && isDir) {
changeExec = true;
+ }
var mask = 0;
if (changeOwner) {
@@ -175,35 +173,37 @@ function _chmod(options, mode, filePattern) {
case '=':
newPerms = type + mask;
- // According to POSIX, when using = to explicitly set the permissions, setuid and setgid can never be cleared.
+ // According to POSIX, when using = to explicitly set the
+ // permissions, setuid and setgid can never be cleared.
if (fs.statSync(file).isDirectory()) {
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
}
break;
+ default:
+ common.error('Could not recognize operator: `' + operator + '`');
}
if (options.verbose) {
console.log(file + ' -> ' + newPerms.toString(8));
}
- if (perms != newPerms) {
+ if (perms !== newPerms) {
if (!options.verbose && options.changes) {
console.log(file + ' -> ' + newPerms.toString(8));
}
fs.chmodSync(file, newPerms);
perms = newPerms; // for the next round of changes!
}
- }
- else {
+ } else {
common.error('Invalid symbolic mode change: ' + symbolicMode);
}
});
- }
- else {
+ } else {
// they gave us a full number
newPerms = type + parseInt(mode, 8);
- // POSIX rules are that setuid and setgid can only be added using numeric form, but not cleared.
+ // POSIX rules are that setuid and setgid can only be added using numeric
+ // form, but not cleared.
if (fs.statSync(file).isDirectory()) {
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
}
@@ -211,5 +211,6 @@ function _chmod(options, mode, filePattern) {
fs.chmodSync(file, newPerms);
}
});
+ return '';
}
module.exports = _chmod;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/common.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/common.js b/node_modules/shelljs/src/common.js
index 33198bd..f5197d8 100644
--- a/node_modules/shelljs/src/common.js
+++ b/node_modules/shelljs/src/common.js
@@ -1,68 +1,186 @@
+// Ignore warning about 'new String()'
+/* eslint no-new-wrappers: 0 */
+'use strict';
+
var os = require('os');
var fs = require('fs');
-var _ls = require('./ls');
+var glob = require('glob');
+var shell = require('..');
-// Module globals
-var config = {
- silent: false,
+var shellMethods = Object.create(shell);
+
+// objectAssign(target_obj, source_obj1 [, source_obj2 ...])
+// "Ponyfill" for Object.assign
+// objectAssign({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
+var objectAssign = typeof Object.assign === 'function' ?
+ Object.assign :
+ function objectAssign(target) {
+ var sources = [].slice.call(arguments, 1);
+ sources.forEach(function (source) {
+ Object.keys(source).forEach(function (key) {
+ target[key] = source[key];
+ });
+ });
+
+ return target;
+ };
+exports.extend = objectAssign;
+
+// Check if we're running under electron
+var isElectron = Boolean(process.versions.electron);
+
+// Module globals (assume no execPath by default)
+var DEFAULT_CONFIG = {
fatal: false,
+ globOptions: {},
+ maxdepth: 255,
+ noglob: false,
+ silent: false,
verbose: false,
+ execPath: null,
};
+
+var config = {
+ reset: function () {
+ objectAssign(this, DEFAULT_CONFIG);
+ if (!isElectron) {
+ this.execPath = process.execPath;
+ }
+ },
+ resetForTesting: function () {
+ this.reset();
+ this.silent = true;
+ },
+};
+
+config.reset();
exports.config = config;
var state = {
error: null,
+ errorCode: 0,
currentCmd: 'shell.js',
- previousDir: null,
- tempDir: null
+ tempDir: null,
};
exports.state = state;
+delete process.env.OLDPWD; // initially, there's no previous directory
+
var platform = os.type().match(/^Win/) ? 'win' : 'unix';
exports.platform = platform;
+// This is populated by calls to commonl.wrap()
+var pipeMethods = [];
+
+// Reliably test if something is any sort of javascript object
+function isObject(a) {
+ return typeof a === 'object' && a !== null;
+}
+exports.isObject = isObject;
+
function log() {
- if (!config.silent)
+ /* istanbul ignore next */
+ if (!config.silent) {
console.error.apply(console, arguments);
+ }
}
exports.log = log;
-// Shows error message. Throws unless _continue or config.fatal are true
-function error(msg, _continue) {
- if (state.error === null)
- state.error = '';
- var log_entry = state.currentCmd + ': ' + msg;
- if (state.error === '')
- state.error = log_entry;
- else
- state.error += '\n' + log_entry;
+// Converts strings to be equivalent across all platforms. Primarily responsible
+// for making sure we use '/' instead of '\' as path separators, but this may be
+// expanded in the future if necessary
+function convertErrorOutput(msg) {
+ if (typeof msg !== 'string') {
+ throw new TypeError('input must be a string');
+ }
+ return msg.replace(/\\/g, '/');
+}
+exports.convertErrorOutput = convertErrorOutput;
+
+// Shows error message. Throws if config.fatal is true
+function error(msg, _code, options) {
+ // Validate input
+ if (typeof msg !== 'string') throw new Error('msg must be a string');
+
+ var DEFAULT_OPTIONS = {
+ continue: false,
+ code: 1,
+ prefix: state.currentCmd + ': ',
+ silent: false,
+ };
- if (msg.length > 0)
- log(log_entry);
+ if (typeof _code === 'number' && isObject(options)) {
+ options.code = _code;
+ } else if (isObject(_code)) { // no 'code'
+ options = _code;
+ } else if (typeof _code === 'number') { // no 'options'
+ options = { code: _code };
+ } else if (typeof _code !== 'number') { // only 'msg'
+ options = {};
+ }
+ options = objectAssign({}, DEFAULT_OPTIONS, options);
+
+ if (!state.errorCode) state.errorCode = options.code;
+
+ var logEntry = convertErrorOutput(options.prefix + msg);
+ state.error = state.error ? state.error + '\n' : '';
+ state.error += logEntry;
- if (config.fatal)
- process.exit(1);
+ // Throw an error, or log the entry
+ if (config.fatal) throw new Error(logEntry);
+ if (msg.length > 0 && !options.silent) log(logEntry);
- if (!_continue)
- throw '';
+ if (!options.continue) {
+ throw {
+ msg: 'earlyExit',
+ retValue: (new ShellString('', state.error, state.errorCode)),
+ };
+ }
}
exports.error = error;
-// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings.
-// For now, this is a dummy function to bookmark places we need such strings
-function ShellString(str) {
- return str;
+//@
+//@ ### ShellString(str)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var foo = ShellString('hello world');
+//@ ```
+//@
+//@ Turns a regular string into a string-like object similar to what each
+//@ command returns. This has special methods, like `.to()` and `.toEnd()`
+function ShellString(stdout, stderr, code) {
+ var that;
+ if (stdout instanceof Array) {
+ that = stdout;
+ that.stdout = stdout.join('\n');
+ if (stdout.length > 0) that.stdout += '\n';
+ } else {
+ that = new String(stdout);
+ that.stdout = stdout;
+ }
+ that.stderr = stderr;
+ that.code = code;
+ // A list of all commands that can appear on the right-hand side of a pipe
+ // (populated by calls to common.wrap())
+ pipeMethods.forEach(function (cmd) {
+ that[cmd] = shellMethods[cmd].bind(that);
+ });
+ return that;
}
+
exports.ShellString = ShellString;
// Return the home directory in a platform-agnostic way, with consideration for
// older versions of node
function getUserHome() {
var result;
- if (os.homedir)
+ if (os.homedir) {
result = os.homedir(); // node 3+
- else
+ } else {
result = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
+ }
return result;
}
exports.getUserHome = getUserHome;
@@ -71,52 +189,58 @@ exports.getUserHome = getUserHome;
// parseOptions('-a', {'a':'alice', 'b':'bob'});
// Returns {'reference': 'string-value', 'bob': false} when passed two dictionaries of the form:
// parseOptions({'-r': 'string-value'}, {'r':'reference', 'b':'bob'});
-function parseOptions(opt, map) {
- if (!map)
- error('parseOptions() internal error: no map given');
+function parseOptions(opt, map, errorOptions) {
+ // Validate input
+ if (typeof opt !== 'string' && !isObject(opt)) {
+ throw new Error('options must be strings or key-value pairs');
+ } else if (!isObject(map)) {
+ throw new Error('parseOptions() internal error: map must be an object');
+ } else if (errorOptions && !isObject(errorOptions)) {
+ throw new Error('parseOptions() internal error: errorOptions must be object');
+ }
// All options are false by default
var options = {};
- for (var letter in map) {
- if (map[letter][0] !== '!')
- options[map[letter]] = false;
- }
+ Object.keys(map).forEach(function (letter) {
+ var optName = map[letter];
+ if (optName[0] !== '!') {
+ options[optName] = false;
+ }
+ });
- if (!opt)
- return options; // defaults
+ if (opt === '') return options; // defaults
- var optionName;
if (typeof opt === 'string') {
- if (opt[0] !== '-')
- return options;
+ if (opt[0] !== '-') {
+ error("Options string must start with a '-'", errorOptions || {});
+ }
// e.g. chars = ['R', 'f']
var chars = opt.slice(1).split('');
- chars.forEach(function(c) {
+ chars.forEach(function (c) {
if (c in map) {
- optionName = map[c];
- if (optionName[0] === '!')
- options[optionName.slice(1, optionName.length-1)] = false;
- else
+ var optionName = map[c];
+ if (optionName[0] === '!') {
+ options[optionName.slice(1)] = false;
+ } else {
options[optionName] = true;
+ }
} else {
- error('option not recognized: '+c);
+ error('option not recognized: ' + c, errorOptions || {});
}
});
- } else if (typeof opt === 'object') {
- for (var key in opt) {
+ } else { // opt is an Object
+ Object.keys(opt).forEach(function (key) {
// key is a string of the form '-r', '-d', etc.
var c = key[1];
if (c in map) {
- optionName = map[c];
+ var optionName = map[c];
options[optionName] = opt[key]; // assign the given value
} else {
- error('option not recognized: '+c);
+ error('option not recognized: ' + c, errorOptions || {});
}
- }
- } else {
- error('options must be strings or key-value pairs');
+ });
}
return options;
}
@@ -127,29 +251,18 @@ exports.parseOptions = parseOptions;
// expand(['file*.js']) = ['file1.js', 'file2.js', ...]
// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
function expand(list) {
+ if (!Array.isArray(list)) {
+ throw new TypeError('must be an array');
+ }
var expanded = [];
- list.forEach(function(listEl) {
- // Wildcard present on directory names ?
- if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) {
- var match = listEl.match(/^([^*]+\/|)(.*)/);
- var root = match[1];
- var rest = match[2];
- var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*");
- restRegex = new RegExp(restRegex);
-
- _ls('-R', root).filter(function (e) {
- return restRegex.test(e);
- }).forEach(function(file) {
- expanded.push(file);
- });
- }
- // Wildcard present on file names ?
- else if (listEl.search(/\*/) > -1) {
- _ls('', listEl).forEach(function(file) {
- expanded.push(file);
- });
- } else {
+ list.forEach(function (listEl) {
+ // Don't expand non-strings
+ if (typeof listEl !== 'string') {
expanded.push(listEl);
+ } else {
+ var ret = glob.sync(listEl, config.globOptions);
+ // if glob fails, interpret the string literally
+ expanded = expanded.concat(ret.length > 0 ? ret : [listEl]);
}
});
return expanded;
@@ -161,8 +274,9 @@ exports.expand = expand;
function unlinkSync(file) {
try {
fs.unlinkSync(file);
- } catch(e) {
+ } catch (e) {
// Try to override file permission
+ /* istanbul ignore next */
if (e.code === 'EPERM') {
fs.chmodSync(file, '0666');
fs.unlinkSync(file);
@@ -176,78 +290,120 @@ exports.unlinkSync = unlinkSync;
// e.g. 'shelljs_a5f185d0443ca...'
function randomFileName() {
function randomHash(count) {
- if (count === 1)
- return parseInt(16*Math.random(), 10).toString(16);
- else {
- var hash = '';
- for (var i=0; i<count; i++)
- hash += randomHash(1);
- return hash;
+ if (count === 1) {
+ return parseInt(16 * Math.random(), 10).toString(16);
+ }
+ var hash = '';
+ for (var i = 0; i < count; i++) {
+ hash += randomHash(1);
}
+ return hash;
}
- return 'shelljs_'+randomHash(20);
+ return 'shelljs_' + randomHash(20);
}
exports.randomFileName = randomFileName;
-// extend(target_obj, source_obj1 [, source_obj2 ...])
-// Shallow extend, e.g.:
-// extend({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
-function extend(target) {
- var sources = [].slice.call(arguments, 1);
- sources.forEach(function(source) {
- for (var key in source)
- target[key] = source[key];
- });
-
- return target;
-}
-exports.extend = extend;
-
-// Common wrapper for all Unix-like commands
+// Common wrapper for all Unix-like commands that performs glob expansion,
+// command-logging, and other nice things
function wrap(cmd, fn, options) {
- return function() {
+ options = options || {};
+ if (options.canReceivePipe) {
+ pipeMethods.push(cmd);
+ }
+ return function () {
var retValue = null;
state.currentCmd = cmd;
state.error = null;
+ state.errorCode = 0;
try {
var args = [].slice.call(arguments, 0);
+ // Log the command to stderr, if appropriate
if (config.verbose) {
- args.unshift(cmd);
- console.log.apply(console, args);
- args.shift();
+ console.error.apply(console, [cmd].concat(args));
}
- if (options && options.notUnix) {
+ // If this is coming from a pipe, let's set the pipedValue (otherwise, set
+ // it to the empty string)
+ state.pipedValue = (this && typeof this.stdout === 'string') ? this.stdout : '';
+
+ if (options.unix === false) { // this branch is for exec()
retValue = fn.apply(this, args);
- } else {
- if (typeof args[0] === 'object' && args[0].constructor.name === 'Object') {
- args = args; // object count as options
+ } else { // and this branch is for everything else
+ if (isObject(args[0]) && args[0].constructor.name === 'Object') {
+ // a no-op, allowing the syntax `touch({'-r': file}, ...)`
} else if (args.length === 0 || typeof args[0] !== 'string' || args[0].length <= 1 || args[0][0] !== '-') {
args.unshift(''); // only add dummy option if '-option' not already present
}
+
+ // flatten out arrays that are arguments, to make the syntax:
+ // `cp([file1, file2, file3], dest);`
+ // equivalent to:
+ // `cp(file1, file2, file3, dest);`
+ args = args.reduce(function (accum, cur) {
+ if (Array.isArray(cur)) {
+ return accum.concat(cur);
+ }
+ accum.push(cur);
+ return accum;
+ }, []);
+
+ // Convert ShellStrings (basically just String objects) to regular strings
+ args = args.map(function (arg) {
+ if (isObject(arg) && arg.constructor.name === 'String') {
+ return arg.toString();
+ }
+ return arg;
+ });
+
// Expand the '~' if appropriate
var homeDir = getUserHome();
- args = args.map(function(arg) {
- if (typeof arg === 'string' && arg.slice(0, 2) === '~/' || arg === '~')
+ args = args.map(function (arg) {
+ if (typeof arg === 'string' && arg.slice(0, 2) === '~/' || arg === '~') {
return arg.replace(/^~/, homeDir);
- else
- return arg;
+ }
+ return arg;
});
- retValue = fn.apply(this, args);
+
+ // Perform glob-expansion on all arguments after globStart, but preserve
+ // the arguments before it (like regexes for sed and grep)
+ if (!config.noglob && options.allowGlobbing === true) {
+ args = args.slice(0, options.globStart).concat(expand(args.slice(options.globStart)));
+ }
+
+ try {
+ // parse options if options are provided
+ if (isObject(options.cmdOptions)) {
+ args[0] = parseOptions(args[0], options.cmdOptions);
+ }
+
+ retValue = fn.apply(this, args);
+ } catch (e) {
+ /* istanbul ignore else */
+ if (e.msg === 'earlyExit') {
+ retValue = e.retValue;
+ } else {
+ throw e; // this is probably a bug that should be thrown up the call stack
+ }
+ }
}
} catch (e) {
+ /* istanbul ignore next */
if (!state.error) {
// If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
- console.log('shell.js: internal error');
- console.log(e.stack || e);
+ console.error('ShellJS: internal error');
+ console.error(e.stack || e);
process.exit(1);
}
- if (config.fatal)
- throw e;
+ if (config.fatal) throw e;
+ }
+
+ if (options.wrapOutput &&
+ (typeof retValue === 'string' || Array.isArray(retValue))) {
+ retValue = new ShellString(retValue, state.error, state.errorCode);
}
state.currentCmd = 'shell.js';
@@ -255,3 +411,40 @@ function wrap(cmd, fn, options) {
};
} // wrap
exports.wrap = wrap;
+
+// This returns all the input that is piped into the current command (or the
+// empty string, if this isn't on the right-hand side of a pipe
+function _readFromPipe() {
+ return state.pipedValue;
+}
+exports.readFromPipe = _readFromPipe;
+
+var DEFAULT_WRAP_OPTIONS = {
+ allowGlobbing: true,
+ canReceivePipe: false,
+ cmdOptions: false,
+ globStart: 1,
+ pipeOnly: false,
+ unix: true,
+ wrapOutput: true,
+ overWrite: false,
+};
+
+// Register a new ShellJS command
+function _register(name, implementation, wrapOptions) {
+ wrapOptions = wrapOptions || {};
+ // If an option isn't specified, use the default
+ wrapOptions = objectAssign({}, DEFAULT_WRAP_OPTIONS, wrapOptions);
+
+ if (shell[name] && !wrapOptions.overWrite) {
+ throw new Error('unable to overwrite `' + name + '` command');
+ }
+
+ if (wrapOptions.pipeOnly) {
+ wrapOptions.canReceivePipe = true;
+ shellMethods[name] = wrap(name, implementation, wrapOptions);
+ } else {
+ shell[name] = wrap(name, implementation, wrapOptions);
+ }
+}
+exports.register = _register;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/cp.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/cp.js b/node_modules/shelljs/src/cp.js
index 54404ef..04c4e57 100644
--- a/node_modules/shelljs/src/cp.js
+++ b/node_modules/shelljs/src/cp.js
@@ -3,42 +3,79 @@ var path = require('path');
var common = require('./common');
var os = require('os');
+common.register('cp', _cp, {
+ cmdOptions: {
+ 'f': '!no_force',
+ 'n': 'no_force',
+ 'u': 'update',
+ 'R': 'recursive',
+ 'r': 'recursive',
+ 'L': 'followsymlink',
+ 'P': 'noFollowsymlink',
+ },
+ wrapOutput: false,
+});
+
// Buffered file copy, synchronous
// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
// with large files)
-function copyFileSync(srcFile, destFile) {
- if (!fs.existsSync(srcFile))
+function copyFileSync(srcFile, destFile, options) {
+ if (!fs.existsSync(srcFile)) {
common.error('copyFileSync: no such file or directory: ' + srcFile);
-
- var BUF_LENGTH = 64*1024,
- buf = new Buffer(BUF_LENGTH),
- bytesRead = BUF_LENGTH,
- pos = 0,
- fdr = null,
- fdw = null;
-
- try {
- fdr = fs.openSync(srcFile, 'r');
- } catch(e) {
- common.error('copyFileSync: could not read src file ('+srcFile+')');
}
+ // Check the mtimes of the files if the '-u' flag is provided
try {
- fdw = fs.openSync(destFile, 'w');
- } catch(e) {
- common.error('copyFileSync: could not write to dest file (code='+e.code+'):'+destFile);
+ if (options.update && fs.statSync(srcFile).mtime < fs.statSync(destFile).mtime) {
+ return;
+ }
+ } catch (e) {
+ // If we're here, destFile probably doesn't exist, so just do a normal copy
}
- while (bytesRead === BUF_LENGTH) {
- bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
- fs.writeSync(fdw, buf, 0, bytesRead);
- pos += bytesRead;
- }
+ if (fs.lstatSync(srcFile).isSymbolicLink() && !options.followsymlink) {
+ try {
+ fs.lstatSync(destFile);
+ common.unlinkSync(destFile); // re-link it
+ } catch (e) {
+ // it doesn't exist, so no work needs to be done
+ }
- fs.closeSync(fdr);
- fs.closeSync(fdw);
+ var symlinkFull = fs.readlinkSync(srcFile);
+ fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null);
+ } else {
+ var BUF_LENGTH = 64 * 1024;
+ var buf = new Buffer(BUF_LENGTH);
+ var bytesRead = BUF_LENGTH;
+ var pos = 0;
+ var fdr = null;
+ var fdw = null;
- fs.chmodSync(destFile, fs.statSync(srcFile).mode);
+ try {
+ fdr = fs.openSync(srcFile, 'r');
+ } catch (e) {
+ /* istanbul ignore next */
+ common.error('copyFileSync: could not read src file (' + srcFile + ')');
+ }
+
+ try {
+ fdw = fs.openSync(destFile, 'w');
+ } catch (e) {
+ /* istanbul ignore next */
+ common.error('copyFileSync: could not write to dest file (code=' + e.code + '):' + destFile);
+ }
+
+ while (bytesRead === BUF_LENGTH) {
+ bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
+ fs.writeSync(fdw, buf, 0, bytesRead);
+ pos += bytesRead;
+ }
+
+ fs.closeSync(fdr);
+ fs.closeSync(fdw);
+
+ fs.chmodSync(destFile, fs.statSync(srcFile).mode);
+ }
}
// Recursively copies 'sourceDir' into 'destDir'
@@ -49,43 +86,91 @@ function copyFileSync(srcFile, destFile) {
//
// Licensed under the MIT License
// http://www.opensource.org/licenses/mit-license.php
-function cpdirSyncRecursive(sourceDir, destDir, opts) {
+function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) {
if (!opts) opts = {};
- /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
- var checkDir = fs.statSync(sourceDir);
+ // Ensure there is not a run away recursive copy
+ if (currentDepth >= common.config.maxdepth) return;
+ currentDepth++;
+
+ // Create the directory where all our junk is moving to; read the mode of the
+ // source directory and mirror it
try {
+ var checkDir = fs.statSync(sourceDir);
fs.mkdirSync(destDir, checkDir.mode);
} catch (e) {
- //if the directory already exists, that's okay
+ // if the directory already exists, that's okay
if (e.code !== 'EEXIST') throw e;
}
var files = fs.readdirSync(sourceDir);
for (var i = 0; i < files.length; i++) {
- var srcFile = sourceDir + "/" + files[i];
- var destFile = destDir + "/" + files[i];
+ var srcFile = sourceDir + '/' + files[i];
+ var destFile = destDir + '/' + files[i];
var srcFileStat = fs.lstatSync(srcFile);
+ var symlinkFull;
+ if (opts.followsymlink) {
+ if (cpcheckcycle(sourceDir, srcFile)) {
+ // Cycle link found.
+ console.error('Cycle link found.');
+ symlinkFull = fs.readlinkSync(srcFile);
+ fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null);
+ continue;
+ }
+ }
if (srcFileStat.isDirectory()) {
/* recursion this thing right on back. */
- cpdirSyncRecursive(srcFile, destFile, opts);
- } else if (srcFileStat.isSymbolicLink()) {
- var symlinkFull = fs.readlinkSync(srcFile);
- fs.symlinkSync(symlinkFull, destFile, os.platform() === "win32" ? "junction" : null);
+ cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
+ } else if (srcFileStat.isSymbolicLink() && !opts.followsymlink) {
+ symlinkFull = fs.readlinkSync(srcFile);
+ try {
+ fs.lstatSync(destFile);
+ common.unlinkSync(destFile); // re-link it
+ } catch (e) {
+ // it doesn't exist, so no work needs to be done
+ }
+ fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null);
+ } else if (srcFileStat.isSymbolicLink() && opts.followsymlink) {
+ srcFileStat = fs.statSync(srcFile);
+ if (srcFileStat.isDirectory()) {
+ cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
+ } else {
+ copyFileSync(srcFile, destFile, opts);
+ }
} else {
/* At this point, we've hit a file actually worth copying... so copy it on over. */
if (fs.existsSync(destFile) && opts.no_force) {
common.log('skipping existing file: ' + files[i]);
} else {
- copyFileSync(srcFile, destFile);
+ copyFileSync(srcFile, destFile, opts);
}
}
-
} // for files
} // cpdirSyncRecursive
+function cpcheckcycle(sourceDir, srcFile) {
+ var srcFileStat = fs.lstatSync(srcFile);
+ if (srcFileStat.isSymbolicLink()) {
+ // Do cycle check. For example:
+ // $ mkdir -p 1/2/3/4
+ // $ cd 1/2/3/4
+ // $ ln -s ../../3 link
+ // $ cd ../../../..
+ // $ cp -RL 1 copy
+ var cyclecheck = fs.statSync(srcFile);
+ if (cyclecheck.isDirectory()) {
+ var sourcerealpath = fs.realpathSync(sourceDir);
+ var symlinkrealpath = fs.realpathSync(srcFile);
+ var re = new RegExp(symlinkrealpath);
+ if (re.test(sourcerealpath)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
//@
//@ ### cp([options,] source [, source ...], dest)
@@ -94,117 +179,100 @@ function cpdirSyncRecursive(sourceDir, destDir, opts) {
//@
//@ + `-f`: force (default behavior)
//@ + `-n`: no-clobber
-//@ + `-r, -R`: recursive
+//@ + `-u`: only copy if source is newer than dest
+//@ + `-r`, `-R`: recursive
+//@ + `-L`: follow symlinks
+//@ + `-P`: don't follow symlinks
//@
//@ Examples:
//@
//@ ```javascript
//@ cp('file1', 'dir1');
+//@ cp('-R', 'path/to/dir/', '~/newCopy/');
//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
//@ ```
//@
-//@ Copies files. The wildcard `*` is accepted.
+//@ Copies files.
function _cp(options, sources, dest) {
- options = common.parseOptions(options, {
- 'f': '!no_force',
- 'n': 'no_force',
- 'R': 'recursive',
- 'r': 'recursive'
- });
+ // If we're missing -R, it actually implies -L (unless -P is explicit)
+ if (options.followsymlink) {
+ options.noFollowsymlink = false;
+ }
+ if (!options.recursive && !options.noFollowsymlink) {
+ options.followsymlink = true;
+ }
// Get sources, dest
if (arguments.length < 3) {
common.error('missing <source> and/or <dest>');
- } else if (arguments.length > 3) {
+ } else {
sources = [].slice.call(arguments, 1, arguments.length - 1);
dest = arguments[arguments.length - 1];
- } else if (typeof sources === 'string') {
- sources = [sources];
- } else if ('length' in sources) {
- sources = sources; // no-op for array
- } else {
- common.error('invalid arguments');
}
- var exists = fs.existsSync(dest),
- stats = exists && fs.statSync(dest);
+ var destExists = fs.existsSync(dest);
+ var destStat = destExists && fs.statSync(dest);
// Dest is not existing dir, but multiple sources given
- if ((!exists || !stats.isDirectory()) && sources.length > 1)
+ if ((!destExists || !destStat.isDirectory()) && sources.length > 1) {
common.error('dest is not a directory (too many sources)');
-
- // Dest is an existing file, but no -f given
- if (exists && stats.isFile() && options.no_force)
- common.error('dest file already exists: ' + dest);
-
- if (options.recursive) {
- // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
- // (see Github issue #15)
- sources.forEach(function(src, i) {
- if (src[src.length - 1] === '/') {
- sources[i] += '*';
- // If src is a directory and dest doesn't exist, 'cp -r src dest' should copy src/* into dest
- } else if (fs.statSync(src).isDirectory() && !exists) {
- sources[i] += '/*';
- }
- });
-
- // Create dest
- try {
- fs.mkdirSync(dest, parseInt('0777', 8));
- } catch (e) {
- // like Unix's cp, keep going even if we can't create dest dir
- }
}
- sources = common.expand(sources);
+ // Dest is an existing file, but -n is given
+ if (destExists && destStat.isFile() && options.no_force) {
+ return new common.ShellString('', '', 0);
+ }
- sources.forEach(function(src) {
+ sources.forEach(function (src) {
if (!fs.existsSync(src)) {
- common.error('no such file or directory: '+src, true);
+ common.error('no such file or directory: ' + src, { continue: true });
return; // skip file
}
-
- // If here, src exists
- if (fs.statSync(src).isDirectory()) {
+ var srcStat = fs.statSync(src);
+ if (!options.noFollowsymlink && srcStat.isDirectory()) {
if (!options.recursive) {
// Non-Recursive
- common.log(src + ' is a directory (not copied)');
+ common.error("omitting directory '" + src + "'", { continue: true });
} else {
// Recursive
// 'cp /a/source dest' should create 'source' in 'dest'
- var newDest = path.join(dest, path.basename(src)),
- checkDir = fs.statSync(src);
+ var newDest = (destStat && destStat.isDirectory()) ?
+ path.join(dest, path.basename(src)) :
+ dest;
+
try {
- fs.mkdirSync(newDest, checkDir.mode);
+ fs.statSync(path.dirname(dest));
+ cpdirSyncRecursive(src, newDest, 0, { no_force: options.no_force, followsymlink: options.followsymlink });
} catch (e) {
- //if the directory already exists, that's okay
- if (e.code !== 'EEXIST') {
- common.error('dest file no such file or directory: ' + newDest, true);
- throw e;
- }
+ /* istanbul ignore next */
+ common.error("cannot create directory '" + dest + "': No such file or directory");
}
+ }
+ } else {
+ // If here, src is a file
- cpdirSyncRecursive(src, newDest, {no_force: options.no_force});
+ // When copying to '/path/dir':
+ // thisDest = '/path/dir/file1'
+ var thisDest = dest;
+ if (destStat && destStat.isDirectory()) {
+ thisDest = path.normalize(dest + '/' + path.basename(src));
}
- return; // done with dir
- }
- // If here, src is a file
+ if (fs.existsSync(thisDest) && options.no_force) {
+ return; // skip file
+ }
- // When copying to '/path/dir':
- // thisDest = '/path/dir/file1'
- var thisDest = dest;
- if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
- thisDest = path.normalize(dest + '/' + path.basename(src));
+ if (path.relative(src, thisDest) === '') {
+ // a file cannot be copied to itself, but we want to continue copying other files
+ common.error("'" + thisDest + "' and '" + src + "' are the same file", { continue: true });
+ return;
+ }
- if (fs.existsSync(thisDest) && options.no_force) {
- common.error('dest file already exists: ' + thisDest, true);
- return; // skip file
+ copyFileSync(src, thisDest, options);
}
-
- copyFileSync(src, thisDest);
}); // forEach(src)
+
+ return new common.ShellString('', common.state.error, common.state.errorCode);
}
module.exports = _cp;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/dirs.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/dirs.js b/node_modules/shelljs/src/dirs.js
index 58fae8b..3806c14 100644
--- a/node_modules/shelljs/src/dirs.js
+++ b/node_modules/shelljs/src/dirs.js
@@ -2,6 +2,16 @@ var common = require('./common');
var _cd = require('./cd');
var path = require('path');
+common.register('dirs', _dirs, {
+ wrapOutput: false,
+});
+common.register('pushd', _pushd, {
+ wrapOutput: false,
+});
+common.register('popd', _popd, {
+ wrapOutput: false,
+});
+
// Pushd/popd/dirs internals
var _dirStack = [];
@@ -13,9 +23,8 @@ function _parseStackIndex(index) {
if (_isStackIndex(index)) {
if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd
return (/^-/).test(index) ? Number(index) - 1 : Number(index);
- } else {
- common.error(index + ': directory stack index out of range');
}
+ common.error(index + ': directory stack index out of range');
} else {
common.error(index + ': invalid number');
}
@@ -54,7 +63,7 @@ function _pushd(options, dir) {
}
options = common.parseOptions(options, {
- 'n' : 'no-cd'
+ 'n': 'no-cd',
});
var dirs = _actualDirStack();
@@ -120,7 +129,7 @@ function _popd(options, index) {
}
options = common.parseOptions(options, {
- 'n' : 'no-cd'
+ 'n': 'no-cd',
});
if (!_dirStack.length) {
@@ -163,10 +172,10 @@ function _dirs(options, index) {
}
options = common.parseOptions(options, {
- 'c' : 'clear'
+ 'c': 'clear',
});
- if (options['clear']) {
+ if (options.clear) {
_dirStack = [];
return _dirStack;
}
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/echo.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/echo.js b/node_modules/shelljs/src/echo.js
index b574adc..2b0e7d9 100644
--- a/node_modules/shelljs/src/echo.js
+++ b/node_modules/shelljs/src/echo.js
@@ -1,7 +1,14 @@
var common = require('./common');
+common.register('echo', _echo, {
+ allowGlobbing: false,
+});
+
+//@
+//@ ### echo([options,] string [, string ...])
+//@ Available options:
//@
-//@ ### echo(string [, string ...])
+//@ + `-e`: interpret backslash escapes (default)
//@
//@ Examples:
//@
@@ -12,9 +19,16 @@ var common = require('./common');
//@
//@ Prints string to stdout, and returns string with additional utility methods
//@ like `.to()`.
-function _echo() {
- var messages = [].slice.call(arguments, 0);
+function _echo(opts, messages) {
+ // allow strings starting with '-', see issue #20
+ messages = [].slice.call(arguments, opts ? 0 : 1);
+
+ if (messages[0] === '-e') {
+ // ignore -e
+ messages.shift();
+ }
+
console.log.apply(console, messages);
- return common.ShellString(messages.join(' '));
+ return messages.join(' ');
}
module.exports = _echo;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/error.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/error.js b/node_modules/shelljs/src/error.js
index 112563d..507c86d 100644
--- a/node_modules/shelljs/src/error.js
+++ b/node_modules/shelljs/src/error.js
@@ -2,8 +2,12 @@ var common = require('./common');
//@
//@ ### error()
-//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
-//@ otherwise returns string explaining the error
+//@ Tests if error occurred in the last command. Returns a truthy value if an
+//@ error returned and a falsy value otherwise.
+//@
+//@ **Note**: do not rely on the
+//@ return value to be an error message. If you need the last error message, use
+//@ the `.stderr` attribute from the last command's return value instead.
function error() {
return common.state.error;
}
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/exec.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/exec.js b/node_modules/shelljs/src/exec.js
index 4174adb..5d360e8 100644
--- a/node_modules/shelljs/src/exec.js
+++ b/node_modules/shelljs/src/exec.js
@@ -5,85 +5,106 @@ var path = require('path');
var fs = require('fs');
var child = require('child_process');
-var DEFAULT_MAXBUFFER_SIZE = 20*1024*1024;
+var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024;
+
+common.register('exec', _exec, {
+ unix: false,
+ canReceivePipe: true,
+ wrapOutput: false,
+});
// Hack to run child_process.exec() synchronously (sync avoids callback hell)
// Uses a custom wait loop that checks for a flag file, created when the child process is done.
// (Can't do a wait loop that checks for internal Node variables/messages as
// Node is single-threaded; callbacks and other internal state changes are done in the
// event loop).
-function execSync(cmd, opts) {
+function execSync(cmd, opts, pipe) {
+ if (!common.config.execPath) {
+ common.error('Unable to find a path to the node binary. Please manually set config.execPath');
+ }
+
var tempDir = _tempDir();
- var stdoutFile = path.resolve(tempDir+'/'+common.randomFileName()),
- stderrFile = path.resolve(tempDir+'/'+common.randomFileName()),
- codeFile = path.resolve(tempDir+'/'+common.randomFileName()),
- scriptFile = path.resolve(tempDir+'/'+common.randomFileName()),
- sleepFile = path.resolve(tempDir+'/'+common.randomFileName());
+ var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName());
+ var stderrFile = path.resolve(tempDir + '/' + common.randomFileName());
+ var codeFile = path.resolve(tempDir + '/' + common.randomFileName());
+ var scriptFile = path.resolve(tempDir + '/' + common.randomFileName());
+ var sleepFile = path.resolve(tempDir + '/' + common.randomFileName());
opts = common.extend({
silent: common.config.silent,
- cwd: _pwd(),
+ cwd: _pwd().toString(),
env: process.env,
- maxBuffer: DEFAULT_MAXBUFFER_SIZE
+ maxBuffer: DEFAULT_MAXBUFFER_SIZE,
}, opts);
- var previousStdoutContent = '',
- previousStderrContent = '';
+ var previousStdoutContent = '';
+ var previousStderrContent = '';
// Echoes stdout and stderr changes from running process, if not silent
function updateStream(streamFile) {
- if (opts.silent || !fs.existsSync(streamFile))
+ if (opts.silent || !fs.existsSync(streamFile)) {
return;
+ }
- var previousStreamContent,
- proc_stream;
+ var previousStreamContent;
+ var procStream;
if (streamFile === stdoutFile) {
previousStreamContent = previousStdoutContent;
- proc_stream = process.stdout;
+ procStream = process.stdout;
} else { // assume stderr
previousStreamContent = previousStderrContent;
- proc_stream = process.stderr;
+ procStream = process.stderr;
}
var streamContent = fs.readFileSync(streamFile, 'utf8');
// No changes since last time?
- if (streamContent.length <= previousStreamContent.length)
+ if (streamContent.length <= previousStreamContent.length) {
return;
+ }
- proc_stream.write(streamContent.substr(previousStreamContent.length));
+ procStream.write(streamContent.substr(previousStreamContent.length));
previousStreamContent = streamContent;
}
- function escape(str) {
- return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
- }
-
if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile);
if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
if (fs.existsSync(stderrFile)) common.unlinkSync(stderrFile);
if (fs.existsSync(codeFile)) common.unlinkSync(codeFile);
- var execCommand = '"'+process.execPath+'" '+scriptFile;
+ var execCommand = JSON.stringify(common.config.execPath) + ' ' + JSON.stringify(scriptFile);
var script;
+ opts.cwd = path.resolve(opts.cwd);
+ var optString = JSON.stringify(opts);
+
if (typeof child.execSync === 'function') {
script = [
"var child = require('child_process')",
" , fs = require('fs');",
- "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: "+opts.maxBuffer+"}, function(err) {",
- " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');",
- "});",
- "var stdoutStream = fs.createWriteStream('"+escape(stdoutFile)+"');",
- "var stderrStream = fs.createWriteStream('"+escape(stderrFile)+"');",
- "childProcess.stdout.pipe(stdoutStream, {end: false});",
- "childProcess.stderr.pipe(stderrStream, {end: false});",
- "childProcess.stdout.pipe(process.stdout);",
- "childProcess.stderr.pipe(process.stderr);",
- "var stdoutEnded = false, stderrEnded = false;",
- "function tryClosingStdout(){ if(stdoutEnded){ stdoutStream.end(); } }",
- "function tryClosingStderr(){ if(stderrEnded){ stderrStream.end(); } }",
- "childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosingStdout(); });",
- "childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });"
- ].join('\n');
+ 'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {',
+ ' var fname = ' + JSON.stringify(codeFile) + ';',
+ ' if (!err) {',
+ ' fs.writeFileSync(fname, "0");',
+ ' } else if (err.code === undefined) {',
+ ' fs.writeFileSync(fname, "1");',
+ ' } else {',
+ ' fs.writeFileSync(fname, err.code.toString());',
+ ' }',
+ '});',
+ 'var stdoutStream = fs.createWriteStream(' + JSON.stringify(stdoutFile) + ');',
+ 'var stderrStream = fs.createWriteStream(' + JSON.stringify(stderrFile) + ');',
+ 'childProcess.stdout.pipe(stdoutStream, {end: false});',
+ 'childProcess.stderr.pipe(stderrStream, {end: false});',
+ 'childProcess.stdout.pipe(process.stdout);',
+ 'childProcess.stderr.pipe(process.stderr);',
+ ].join('\n') +
+ (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n') +
+ [
+ 'var stdoutEnded = false, stderrEnded = false;',
+ 'function tryClosingStdout(){ if(stdoutEnded){ stdoutStream.end(); } }',
+ 'function tryClosingStderr(){ if(stderrEnded){ stderrStream.end(); } }',
+ "childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosingStdout(); });",
+ "childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });",
+ ].join('\n');
fs.writeFileSync(scriptFile, script);
@@ -94,17 +115,34 @@ function execSync(cmd, opts) {
}
// Welcome to the future
- child.execSync(execCommand, opts);
+ try {
+ child.execSync(execCommand, opts);
+ } catch (e) {
+ // Clean up immediately if we have an exception
+ try { common.unlinkSync(scriptFile); } catch (e2) {}
+ try { common.unlinkSync(stdoutFile); } catch (e2) {}
+ try { common.unlinkSync(stderrFile); } catch (e2) {}
+ try { common.unlinkSync(codeFile); } catch (e2) {}
+ throw e;
+ }
} else {
- cmd += ' > '+stdoutFile+' 2> '+stderrFile; // works on both win/unix
+ cmd += ' > ' + stdoutFile + ' 2> ' + stderrFile; // works on both win/unix
script = [
"var child = require('child_process')",
" , fs = require('fs');",
- "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: "+opts.maxBuffer+"}, function(err) {",
- " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');",
- "});"
- ].join('\n');
+ 'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {',
+ ' var fname = ' + JSON.stringify(codeFile) + ';',
+ ' if (!err) {',
+ ' fs.writeFileSync(fname, "0");',
+ ' } else if (err.code === undefined) {',
+ ' fs.writeFileSync(fname, "1");',
+ ' } else {',
+ ' fs.writeFileSync(fname, err.code.toString());',
+ ' }',
+ '});',
+ ].join('\n') +
+ (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n');
fs.writeFileSync(scriptFile, script);
@@ -117,6 +155,7 @@ function execSync(cmd, opts) {
while (!fs.existsSync(codeFile)) { updateStream(stdoutFile); fs.writeFileSync(sleepFile, 'a'); }
while (!fs.existsSync(stdoutFile)) { updateStream(stdoutFile); fs.writeFileSync(sleepFile, 'a'); }
while (!fs.existsSync(stderrFile)) { updateStream(stderrFile); fs.writeFileSync(sleepFile, 'a'); }
+ try { common.unlinkSync(sleepFile); } catch (e) {}
}
// At this point codeFile exists, but it's not necessarily flushed yet.
@@ -130,53 +169,53 @@ function execSync(cmd, opts) {
var stderr = fs.readFileSync(stderrFile, 'utf8');
// No biggie if we can't erase the files now -- they're in a temp dir anyway
- try { common.unlinkSync(scriptFile); } catch(e) {}
- try { common.unlinkSync(stdoutFile); } catch(e) {}
- try { common.unlinkSync(stderrFile); } catch(e) {}
- try { common.unlinkSync(codeFile); } catch(e) {}
- try { common.unlinkSync(sleepFile); } catch(e) {}
-
- // some shell return codes are defined as errors, per http://tldp.org/LDP/abs/html/exitcodes.html
- if (code === 1 || code === 2 || code >= 126) {
- common.error('', true); // unix/shell doesn't really give an error message after non-zero exit codes
+ try { common.unlinkSync(scriptFile); } catch (e) {}
+ try { common.unlinkSync(stdoutFile); } catch (e) {}
+ try { common.unlinkSync(stderrFile); } catch (e) {}
+ try { common.unlinkSync(codeFile); } catch (e) {}
+
+ if (code !== 0) {
+ common.error('', code, { continue: true });
}
- // True if successful, false if not
- var obj = {
- code: code,
- output: stdout, // deprecated
- stdout: stdout,
- stderr: stderr
- };
+ var obj = common.ShellString(stdout, stderr, code);
return obj;
} // execSync()
// Wrapper around exec() to enable echoing output to console in real time
-function execAsync(cmd, opts, callback) {
+function execAsync(cmd, opts, pipe, callback) {
var stdout = '';
var stderr = '';
opts = common.extend({
silent: common.config.silent,
- cwd: _pwd(),
+ cwd: _pwd().toString(),
env: process.env,
- maxBuffer: DEFAULT_MAXBUFFER_SIZE
+ maxBuffer: DEFAULT_MAXBUFFER_SIZE,
}, opts);
- var c = child.exec(cmd, opts, function(err) {
- if (callback)
- callback(err ? err.code : 0, stdout, stderr);
+ var c = child.exec(cmd, opts, function (err) {
+ if (callback) {
+ if (!err) {
+ callback(0, stdout, stderr);
+ } else if (err.code === undefined) {
+ // See issue #536
+ callback(1, stdout, stderr);
+ } else {
+ callback(err.code, stdout, stderr);
+ }
+ }
});
- c.stdout.on('data', function(data) {
+ if (pipe) c.stdin.end(pipe);
+
+ c.stdout.on('data', function (data) {
stdout += data;
- if (!opts.silent)
- process.stdout.write(data);
+ if (!opts.silent) process.stdout.write(data);
});
- c.stderr.on('data', function(data) {
+ c.stderr.on('data', function (data) {
stderr += data;
- if (!opts.silent)
- process.stderr.write(data);
+ if (!opts.silent) process.stderr.write(data);
});
return c;
@@ -189,7 +228,7 @@ function execAsync(cmd, opts, callback) {
//@ + `async`: Asynchronous execution. If a callback is provided, it will be set to
//@ `true`, regardless of the passed value.
//@ + `silent`: Do not echo program output to console.
-//@ + and any option available to NodeJS's
+//@ + and any option available to Node.js's
//@ [child_process.exec()](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)
//@
//@ Examples:
@@ -210,16 +249,22 @@ function execAsync(cmd, opts, callback) {
//@ ```
//@
//@ Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous
-//@ mode returns the object `{ code:..., stdout:... , stderr:... }`, containing the program's
-//@ `stdout`, `stderr`, and its exit `code`. Otherwise returns the child process object,
-//@ and the `callback` gets the arguments `(code, stdout, stderr)`.
+//@ mode, this returns a ShellString (compatible with ShellJS v0.6.x, which returns an object
+//@ of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process
+//@ object, and the `callback` gets the arguments `(code, stdout, stderr)`.
+//@
+//@ Not seeing the behavior you want? `exec()` runs everything through `sh`
+//@ by default (or `cmd.exe` on Windows), which differs from `bash`. If you
+//@ need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option.
//@
//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as
//@ the current synchronous implementation uses a lot of CPU. This should be getting
//@ fixed soon.
function _exec(command, options, callback) {
- if (!command)
- common.error('must specify command');
+ options = options || {};
+ if (!command) common.error('must specify command');
+
+ var pipe = common.readFromPipe();
// Callback is defined instead of options.
if (typeof options === 'function') {
@@ -234,14 +279,15 @@ function _exec(command, options, callback) {
options = common.extend({
silent: common.config.silent,
- async: false
+ async: false,
}, options);
try {
- if (options.async)
- return execAsync(command, options, callback);
- else
- return execSync(command, options);
+ if (options.async) {
+ return execAsync(command, options, pipe, callback);
+ } else {
+ return execSync(command, options, pipe);
+ }
} catch (e) {
common.error('internal error');
}
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/find.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/find.js b/node_modules/shelljs/src/find.js
index c96fb2f..625aa29 100644
--- a/node_modules/shelljs/src/find.js
+++ b/node_modules/shelljs/src/find.js
@@ -1,7 +1,10 @@
var fs = require('fs');
+var path = require('path');
var common = require('./common');
var _ls = require('./ls');
+common.register('find', _find, {});
+
//@
//@ ### find(path [, path ...])
//@ ### find(path_array)
@@ -18,30 +21,37 @@ var _ls = require('./ls');
//@ The main difference from `ls('-R', path)` is that the resulting file names
//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
function _find(options, paths) {
- if (!paths)
+ if (!paths) {
common.error('no path specified');
- else if (typeof paths === 'object')
- paths = paths; // assume array
- else if (typeof paths === 'string')
+ } else if (typeof paths === 'string') {
paths = [].slice.call(arguments, 1);
+ }
var list = [];
function pushFile(file) {
- if (common.platform === 'win')
+ if (common.platform === 'win') {
file = file.replace(/\\/g, '/');
+ }
list.push(file);
}
// why not simply do ls('-R', paths)? because the output wouldn't give the base dirs
// to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory
- paths.forEach(function(file) {
+ paths.forEach(function (file) {
+ var stat;
+ try {
+ stat = fs.statSync(file);
+ } catch (e) {
+ common.error('no such file or directory: ' + file);
+ }
+
pushFile(file);
- if (fs.statSync(file).isDirectory()) {
- _ls('-RA', file+'/*').forEach(function(subfile) {
- pushFile(subfile);
+ if (stat.isDirectory()) {
+ _ls({ recursive: true, all: true }, file).forEach(function (subfile) {
+ pushFile(path.join(file, subfile));
});
}
});
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/grep.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/grep.js b/node_modules/shelljs/src/grep.js
index 78008ce..30842bc 100644
--- a/node_modules/shelljs/src/grep.js
+++ b/node_modules/shelljs/src/grep.js
@@ -1,12 +1,22 @@
var common = require('./common');
var fs = require('fs');
+common.register('grep', _grep, {
+ globStart: 2, // don't glob-expand the regex
+ canReceivePipe: true,
+ cmdOptions: {
+ 'v': 'inverse',
+ 'l': 'nameOnly',
+ },
+});
+
//@
//@ ### grep([options,] regex_filter, file [, file ...])
//@ ### grep([options,] regex_filter, file_array)
//@ Available options:
//@
//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
+//@ + `-l`: Print only filenames of matching files
//@
//@ Examples:
//@
@@ -16,37 +26,42 @@ var fs = require('fs');
//@ ```
//@
//@ Reads input string from given files and returns a string containing all lines of the
-//@ file that match the given `regex_filter`. Wildcard `*` accepted.
+//@ file that match the given `regex_filter`.
function _grep(options, regex, files) {
- options = common.parseOptions(options, {
- 'v': 'inverse'
- });
+ // Check if this is coming from a pipe
+ var pipe = common.readFromPipe();
- if (!files)
- common.error('no paths given');
+ if (!files && !pipe) common.error('no paths given', 2);
- if (typeof files === 'string')
- files = [].slice.call(arguments, 2);
- // if it's array leave it as it is
+ files = [].slice.call(arguments, 2);
- files = common.expand(files);
+ if (pipe) {
+ files.unshift('-');
+ }
- var grep = '';
- files.forEach(function(file) {
- if (!fs.existsSync(file)) {
- common.error('no such file or directory: ' + file, true);
+ var grep = [];
+ files.forEach(function (file) {
+ if (!fs.existsSync(file) && file !== '-') {
+ common.error('no such file or directory: ' + file, 2, { continue: true });
return;
}
- var contents = fs.readFileSync(file, 'utf8'),
- lines = contents.split(/\r*\n/);
- lines.forEach(function(line) {
- var matched = line.match(regex);
- if ((options.inverse && !matched) || (!options.inverse && matched))
- grep += line + '\n';
- });
+ var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
+ var lines = contents.split(/\r*\n/);
+ if (options.nameOnly) {
+ if (contents.match(regex)) {
+ grep.push(file);
+ }
+ } else {
+ lines.forEach(function (line) {
+ var matched = line.match(regex);
+ if ((options.inverse && !matched) || (!options.inverse && matched)) {
+ grep.push(line);
+ }
+ });
+ }
});
- return common.ShellString(grep);
+ return grep.join('\n') + '\n';
}
module.exports = _grep;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/ln.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/ln.js b/node_modules/shelljs/src/ln.js
index 878fda1..7393d9f 100644
--- a/node_modules/shelljs/src/ln.js
+++ b/node_modules/shelljs/src/ln.js
@@ -2,6 +2,13 @@ var fs = require('fs');
var path = require('path');
var common = require('./common');
+common.register('ln', _ln, {
+ cmdOptions: {
+ 's': 'symlink',
+ 'f': 'force',
+ },
+});
+
//@
//@ ### ln([options,] source, dest)
//@ Available options:
@@ -18,11 +25,6 @@ var common = require('./common');
//@
//@ Links source to dest. Use -f to force the link, should dest already exist.
function _ln(options, source, dest) {
- options = common.parseOptions(options, {
- 's': 'symlink',
- 'f': 'force'
- });
-
if (!source || !dest) {
common.error('Missing <source> and/or <dest>');
}
@@ -34,7 +36,7 @@ function _ln(options, source, dest) {
if (fs.existsSync(dest)) {
if (!options.force) {
- common.error('Destination file exists', true);
+ common.error('Destination file exists', { continue: true });
}
fs.unlinkSync(dest);
@@ -45,19 +47,19 @@ function _ln(options, source, dest) {
var linkType = isWindows ? 'file' : null;
var resolvedSourcePath = isAbsolute ? sourcePath : path.resolve(process.cwd(), path.dirname(dest), source);
if (!fs.existsSync(resolvedSourcePath)) {
- common.error('Source file does not exist', true);
+ common.error('Source file does not exist', { continue: true });
} else if (isWindows && fs.statSync(resolvedSourcePath).isDirectory()) {
- linkType = 'junction';
+ linkType = 'junction';
}
try {
- fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath: source, dest, linkType);
+ fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath : source, dest, linkType);
} catch (err) {
common.error(err.message);
}
} else {
if (!fs.existsSync(source)) {
- common.error('Source file does not exist', true);
+ common.error('Source file does not exist', { continue: true });
}
try {
fs.linkSync(source, dest);
@@ -65,5 +67,6 @@ function _ln(options, source, dest) {
common.error(err.message);
}
}
+ return '';
}
module.exports = _ln;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/ls.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/ls.js b/node_modules/shelljs/src/ls.js
index 6a54b3a..bb1b6a7 100644
--- a/node_modules/shelljs/src/ls.js
+++ b/node_modules/shelljs/src/ls.js
@@ -1,8 +1,20 @@
var path = require('path');
var fs = require('fs');
var common = require('./common');
-var _cd = require('./cd');
-var _pwd = require('./pwd');
+var glob = require('glob');
+
+var globPatternRecursive = path.sep + '**';
+
+common.register('ls', _ls, {
+ cmdOptions: {
+ 'R': 'recursive',
+ 'A': 'all',
+ 'L': 'link',
+ 'a': 'all_deprecated',
+ 'd': 'directory',
+ 'l': 'long',
+ },
+});
//@
//@ ### ls([options,] [path, ...])
@@ -11,6 +23,7 @@ var _pwd = require('./pwd');
//@
//@ + `-R`: recursive
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
+//@ + `-L`: follow symlinks
//@ + `-d`: list directories themselves, not their contents
//@ + `-l`: list objects representing each file, each with fields containing `ls
//@ -l` output fields. See
@@ -28,14 +41,6 @@ var _pwd = require('./pwd');
//@
//@ Returns array of files in the given path, or in current directory if no path provided.
function _ls(options, paths) {
- options = common.parseOptions(options, {
- 'R': 'recursive',
- 'A': 'all',
- 'a': 'all_deprecated',
- 'd': 'directory',
- 'l': 'long'
- });
-
if (options.all_deprecated) {
// We won't support the -a option as it's hard to image why it's useful
// (it includes '.' and '..' in addition to '.*' files)
@@ -44,125 +49,78 @@ function _ls(options, paths) {
options.all = true;
}
- if (!paths)
+ if (!paths) {
paths = ['.'];
- else if (typeof paths === 'object')
- paths = paths; // assume array
- else if (typeof paths === 'string')
+ } else {
paths = [].slice.call(arguments, 1);
+ }
var list = [];
- // Conditionally pushes file to list - returns true if pushed, false otherwise
- // (e.g. prevents hidden files to be included unless explicitly told so)
- function pushFile(file, query) {
- var name = file.name || file;
- // hidden file?
- if (path.basename(name)[0] === '.') {
- // not explicitly asking for hidden files?
- if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
- return false;
+ function pushFile(abs, relName, stat) {
+ if (process.platform === 'win32') {
+ relName = relName.replace(/\\/g, '/');
}
-
- if (common.platform === 'win')
- name = name.replace(/\\/g, '/');
-
- if (file.name) {
- file.name = name;
+ if (options.long) {
+ stat = stat || (options.link ? fs.statSync(abs) : fs.lstatSync(abs));
+ list.push(addLsAttributes(relName, stat));
} else {
- file = name;
+ // list.push(path.relative(rel || '.', file));
+ list.push(relName);
}
- list.push(file);
- return true;
}
- paths.forEach(function(p) {
- if (fs.existsSync(p)) {
- var stats = ls_stat(p);
- // Simple file?
- if (stats.isFile()) {
- if (options.long) {
- pushFile(stats, p);
- } else {
- pushFile(p, p);
- }
- return; // continue
- }
+ paths.forEach(function (p) {
+ var stat;
- // Simple dir?
- if (options.directory) {
- pushFile(p, p);
- return;
- } else if (stats.isDirectory()) {
- // Iterate over p contents
- fs.readdirSync(p).forEach(function(file) {
- var orig_file = file;
- if (options.long)
- file = ls_stat(path.join(p, file));
- if (!pushFile(file, p))
- return;
+ try {
+ stat = options.link ? fs.statSync(p) : fs.lstatSync(p);
+ } catch (e) {
+ common.error('no such file or directory: ' + p, 2, { continue: true });
+ return;
+ }
- // Recursive?
- if (options.recursive) {
- var oldDir = _pwd();
- _cd('', p);
- if (fs.statSync(orig_file).isDirectory())
- list = list.concat(_ls('-R'+(options.all?'A':''), orig_file+'/*'));
- _cd('', oldDir);
+ // If the stat succeeded
+ if (stat.isDirectory() && !options.directory) {
+ if (options.recursive) {
+ // use glob, because it's simple
+ glob.sync(p + globPatternRecursive, { dot: options.all, follow: options.link })
+ .forEach(function (item) {
+ // Glob pattern returns the directory itself and needs to be filtered out.
+ if (path.relative(p, item)) {
+ pushFile(item, path.relative(p, item));
+ }
+ });
+ } else if (options.all) {
+ // use fs.readdirSync, because it's fast
+ fs.readdirSync(p).forEach(function (item) {
+ pushFile(path.join(p, item), item);
+ });
+ } else {
+ // use fs.readdirSync and then filter out secret files
+ fs.readdirSync(p).forEach(function (item) {
+ if (item[0] !== '.') {
+ pushFile(path.join(p, item), item);
}
});
- return; // continue
}
+ } else {
+ pushFile(p, p, stat);
}
-
- // p does not exist - possible wildcard present
-
- var basename = path.basename(p);
- var dirname = path.dirname(p);
- // Wildcard present on an existing dir? (e.g. '/tmp/*.js')
- if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) {
- // Escape special regular expression chars
- var regexp = basename.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
- // Translates wildcard into regex
- regexp = '^' + regexp.replace(/\*/g, '.*') + '$';
- // Iterate over directory contents
- fs.readdirSync(dirname).forEach(function(file) {
- if (file.match(new RegExp(regexp))) {
- var file_path = path.join(dirname, file);
- file_path = options.long ? ls_stat(file_path) : file_path;
- if (file_path.name)
- file_path.name = path.normalize(file_path.name);
- else
- file_path = path.normalize(file_path);
- if (!pushFile(file_path, basename))
- return;
-
- // Recursive?
- if (options.recursive) {
- var pp = dirname + '/' + file;
- if (fs.lstatSync(pp).isDirectory())
- list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*'));
- } // recursive
- } // if file matches
- }); // forEach
- return;
- }
-
- common.error('no such file or directory: ' + p, true);
});
+ // Add methods, to make this more compatible with ShellStrings
return list;
}
-module.exports = _ls;
-
-function ls_stat(path) {
- var stats = fs.statSync(path);
+function addLsAttributes(pathName, stats) {
// Note: this object will contain more information than .toString() returns
- stats.name = path;
- stats.toString = function() {
+ stats.name = pathName;
+ stats.toString = function () {
// Return a string resembling unix's `ls -l` format
return [this.mode, this.nlink, this.uid, this.gid, this.size, this.mtime, this.name].join(' ');
};
return stats;
}
+
+module.exports = _ls;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/mkdir.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/mkdir.js b/node_modules/shelljs/src/mkdir.js
index 8b4fd99..115f75c 100644
--- a/node_modules/shelljs/src/mkdir.js
+++ b/node_modules/shelljs/src/mkdir.js
@@ -2,10 +2,23 @@ var common = require('./common');
var fs = require('fs');
var path = require('path');
+common.register('mkdir', _mkdir, {
+ cmdOptions: {
+ 'p': 'fullpath',
+ },
+});
+
// Recursively creates 'dir'
function mkdirSyncRecursive(dir) {
var baseDir = path.dirname(dir);
+ // Prevents some potential problems arising from malformed UNCs or
+ // insufficient permissions.
+ /* istanbul ignore next */
+ if (baseDir === dir) {
+ common.error('dirname() failed: [' + dir + ']');
+ }
+
// Base dir exists, no recursion necessary
if (fs.existsSync(baseDir)) {
fs.mkdirSync(dir, parseInt('0777', 8));
@@ -35,34 +48,46 @@ function mkdirSyncRecursive(dir) {
//@
//@ Creates directories.
function _mkdir(options, dirs) {
- options = common.parseOptions(options, {
- 'p': 'fullpath'
- });
- if (!dirs)
- common.error('no paths given');
+ if (!dirs) common.error('no paths given');
- if (typeof dirs === 'string')
+ if (typeof dirs === 'string') {
dirs = [].slice.call(arguments, 1);
+ }
// if it's array leave it as it is
- dirs.forEach(function(dir) {
- if (fs.existsSync(dir)) {
- if (!options.fullpath)
- common.error('path already exists: ' + dir, true);
+ dirs.forEach(function (dir) {
+ try {
+ fs.lstatSync(dir);
+ if (!options.fullpath) {
+ common.error('path already exists: ' + dir, { continue: true });
+ }
return; // skip dir
+ } catch (e) {
+ // do nothing
}
// Base dir does not exist, and no -p option given
var baseDir = path.dirname(dir);
if (!fs.existsSync(baseDir) && !options.fullpath) {
- common.error('no such file or directory: ' + baseDir, true);
+ common.error('no such file or directory: ' + baseDir, { continue: true });
return; // skip dir
}
- if (options.fullpath)
- mkdirSyncRecursive(dir);
- else
- fs.mkdirSync(dir, parseInt('0777', 8));
+ try {
+ if (options.fullpath) {
+ mkdirSyncRecursive(path.resolve(dir));
+ } else {
+ fs.mkdirSync(dir, parseInt('0777', 8));
+ }
+ } catch (e) {
+ if (e.code === 'EACCES') {
+ common.error('cannot create directory ' + dir + ': Permission denied');
+ } else {
+ /* istanbul ignore next */
+ throw e;
+ }
+ }
});
+ return '';
} // mkdir
module.exports = _mkdir;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/mv.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/mv.js b/node_modules/shelljs/src/mv.js
index 69cc03f..7fc7cf0 100644
--- a/node_modules/shelljs/src/mv.js
+++ b/node_modules/shelljs/src/mv.js
@@ -1,6 +1,15 @@
var fs = require('fs');
var path = require('path');
var common = require('./common');
+var cp = require('./cp');
+var rm = require('./rm');
+
+common.register('mv', _mv, {
+ cmdOptions: {
+ 'f': '!no_force',
+ 'n': 'no_force',
+ },
+});
//@
//@ ### mv([options ,] source [, source ...], dest')
@@ -18,13 +27,8 @@ var common = require('./common');
//@ mv(['file1', 'file2'], 'dir/'); // same as above
//@ ```
//@
-//@ Moves files. The wildcard `*` is accepted.
+//@ Moves files.
function _mv(options, sources, dest) {
- options = common.parseOptions(options, {
- 'f': '!no_force',
- 'n': 'no_force'
- });
-
// Get sources, dest
if (arguments.length < 3) {
common.error('missing <source> and/or <dest>');
@@ -33,28 +37,27 @@ function _mv(options, sources, dest) {
dest = arguments[arguments.length - 1];
} else if (typeof sources === 'string') {
sources = [sources];
- } else if ('length' in sources) {
- sources = sources; // no-op for array
} else {
+ // TODO(nate): figure out if we actually need this line
common.error('invalid arguments');
}
- sources = common.expand(sources);
-
- var exists = fs.existsSync(dest),
- stats = exists && fs.statSync(dest);
+ var exists = fs.existsSync(dest);
+ var stats = exists && fs.statSync(dest);
// Dest is not existing dir, but multiple sources given
- if ((!exists || !stats.isDirectory()) && sources.length > 1)
+ if ((!exists || !stats.isDirectory()) && sources.length > 1) {
common.error('dest is not a directory (too many sources)');
+ }
// Dest is an existing file, but no -f given
- if (exists && stats.isFile() && options.no_force)
+ if (exists && stats.isFile() && options.no_force) {
common.error('dest file already exists: ' + dest);
+ }
- sources.forEach(function(src) {
+ sources.forEach(function (src) {
if (!fs.existsSync(src)) {
- common.error('no such file or directory: '+src, true);
+ common.error('no such file or directory: ' + src, { continue: true });
return; // skip file
}
@@ -63,20 +66,34 @@ function _mv(options, sources, dest) {
// When copying to '/path/dir':
// thisDest = '/path/dir/file1'
var thisDest = dest;
- if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
+ if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) {
thisDest = path.normalize(dest + '/' + path.basename(src));
+ }
if (fs.existsSync(thisDest) && options.no_force) {
- common.error('dest file already exists: ' + thisDest, true);
+ common.error('dest file already exists: ' + thisDest, { continue: true });
return; // skip file
}
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
- common.error('cannot move to self: '+src, true);
+ common.error('cannot move to self: ' + src, { continue: true });
return; // skip file
}
- fs.renameSync(src, thisDest);
+ try {
+ fs.renameSync(src, thisDest);
+ } catch (e) {
+ /* istanbul ignore next */
+ if (e.code === 'EXDEV') {
+ // If we're trying to `mv` to an external partition, we'll actually need
+ // to perform a copy and then clean up the original file. If either the
+ // copy or the rm fails with an exception, we should allow this
+ // exception to pass up to the top level.
+ cp('-r', src, thisDest);
+ rm('-rf', src);
+ }
+ }
}); // forEach(src)
+ return '';
} // mv
module.exports = _mv;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/popd.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/popd.js b/node_modules/shelljs/src/popd.js
index 11ea24f..d9eac3f 100644
--- a/node_modules/shelljs/src/popd.js
+++ b/node_modules/shelljs/src/popd.js
@@ -1 +1 @@
-// see dirs.js
\ No newline at end of file
+// see dirs.js
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/pushd.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/pushd.js b/node_modules/shelljs/src/pushd.js
index 11ea24f..d9eac3f 100644
--- a/node_modules/shelljs/src/pushd.js
+++ b/node_modules/shelljs/src/pushd.js
@@ -1 +1 @@
-// see dirs.js
\ No newline at end of file
+// see dirs.js
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/pwd.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/pwd.js b/node_modules/shelljs/src/pwd.js
index 26cefe0..3861851 100644
--- a/node_modules/shelljs/src/pwd.js
+++ b/node_modules/shelljs/src/pwd.js
@@ -1,11 +1,15 @@
var path = require('path');
var common = require('./common');
+common.register('pwd', _pwd, {
+ allowGlobbing: false,
+});
+
//@
//@ ### pwd()
//@ Returns the current directory.
function _pwd() {
var pwd = path.resolve(process.cwd());
- return common.ShellString(pwd);
+ return pwd;
}
module.exports = _pwd;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/rm.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/rm.js b/node_modules/shelljs/src/rm.js
index cf2e95b..5953681 100644
--- a/node_modules/shelljs/src/rm.js
+++ b/node_modules/shelljs/src/rm.js
@@ -1,6 +1,14 @@
var common = require('./common');
var fs = require('fs');
+common.register('rm', _rm, {
+ cmdOptions: {
+ 'f': 'force',
+ 'r': 'recursive',
+ 'R': 'recursive',
+ },
+});
+
// Recursively removes 'dir'
// Adapted from https://github.com/ryanmcgrath/wrench-js
//
@@ -15,32 +23,24 @@ function rmdirSyncRecursive(dir, force) {
files = fs.readdirSync(dir);
// Loop through and delete everything in the sub-tree after checking it
- for(var i = 0; i < files.length; i++) {
- var file = dir + "/" + files[i],
- currFile = fs.lstatSync(file);
+ for (var i = 0; i < files.length; i++) {
+ var file = dir + '/' + files[i];
+ var currFile = fs.lstatSync(file);
- if(currFile.isDirectory()) { // Recursive function back to the beginning
+ if (currFile.isDirectory()) { // Recursive function back to the beginning
rmdirSyncRecursive(file, force);
- }
-
- else if(currFile.isSymbolicLink()) { // Unlink symlinks
+ } else { // Assume it's a file - perhaps a try/catch belongs here?
if (force || isWriteable(file)) {
try {
common.unlinkSync(file);
} catch (e) {
- common.error('could not remove file (code '+e.code+'): ' + file, true);
+ /* istanbul ignore next */
+ common.error('could not remove file (code ' + e.code + '): ' + file, {
+ continue: true,
+ });
}
}
}
-
- else // Assume it's a file - perhaps a try/catch belongs here?
- if (force || isWriteable(file)) {
- try {
- common.unlinkSync(file);
- } catch (e) {
- common.error('could not remove file (code '+e.code+'): ' + file, true);
- }
- }
}
// Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
@@ -50,16 +50,19 @@ function rmdirSyncRecursive(dir, force) {
try {
// Retry on windows, sometimes it takes a little time before all the files in the directory are gone
var start = Date.now();
- while (true) {
+
+ // TODO: replace this with a finite loop
+ for (;;) {
try {
result = fs.rmdirSync(dir);
- if (fs.existsSync(dir)) throw { code: "EAGAIN" };
+ if (fs.existsSync(dir)) throw { code: 'EAGAIN' };
break;
- } catch(er) {
+ } catch (er) {
+ /* istanbul ignore next */
// In addition to error codes, also check if the directory still exists and loop again if true
- if (process.platform === "win32" && (er.code === "ENOTEMPTY" || er.code === "EBUSY" || er.code === "EPERM" || er.code === "EAGAIN")) {
+ if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM' || er.code === 'EAGAIN')) {
if (Date.now() - start > 1000) throw er;
- } else if (er.code === "ENOENT") {
+ } else if (er.code === 'ENOENT') {
// Directory did not exist, deletion was successful
break;
} else {
@@ -67,8 +70,8 @@ function rmdirSyncRecursive(dir, force) {
}
}
}
- } catch(e) {
- common.error('could not remove directory (code '+e.code+'): ' + dir, true);
+ } catch (e) {
+ common.error('could not remove directory (code ' + e.code + '): ' + dir, { continue: true });
}
return result;
@@ -81,7 +84,7 @@ function isWriteable(file) {
try {
var __fd = fs.openSync(file, 'a');
fs.closeSync(__fd);
- } catch(e) {
+ } catch (e) {
writePermission = false;
}
@@ -104,60 +107,44 @@ function isWriteable(file) {
//@ rm(['some_file.txt', 'another_file.txt']); // same as above
//@ ```
//@
-//@ Removes files. The wildcard `*` is accepted.
+//@ Removes files.
function _rm(options, files) {
- options = common.parseOptions(options, {
- 'f': 'force',
- 'r': 'recursive',
- 'R': 'recursive'
- });
- if (!files)
- common.error('no paths given');
-
- if (typeof files === 'string')
- files = [].slice.call(arguments, 1);
- // if it's array leave it as it is
+ if (!files) common.error('no paths given');
- files = common.expand(files);
+ // Convert to array
+ files = [].slice.call(arguments, 1);
- files.forEach(function(file) {
- if (!fs.existsSync(file)) {
+ files.forEach(function (file) {
+ var stats;
+ try {
+ stats = fs.lstatSync(file); // test for existence
+ } catch (e) {
// Path does not exist, no force flag given
- if (!options.force)
- common.error('no such file or directory: '+file, true);
-
+ if (!options.force) {
+ common.error('no such file or directory: ' + file, { continue: true });
+ }
return; // skip file
}
// If here, path exists
-
- var stats = fs.lstatSync(file);
- if (stats.isFile() || stats.isSymbolicLink()) {
-
- // Do not check for file writing permissions
- if (options.force) {
+ if (stats.isFile()) {
+ if (options.force || isWriteable(file)) {
+ // -f was passed, or file is writable, so it can be removed
common.unlinkSync(file);
- return;
+ } else {
+ common.error('permission denied: ' + file, { continue: true });
}
-
- if (isWriteable(file))
- common.unlinkSync(file);
- else
- common.error('permission denied: '+file, true);
-
- return;
- } // simple file
-
- // Path is an existing directory, but no -r flag given
- if (stats.isDirectory() && !options.recursive) {
- common.error('path is a directory', true);
- return; // skip path
- }
-
- // Recursively remove existing directory
- if (stats.isDirectory() && options.recursive) {
- rmdirSyncRecursive(file, options.force);
+ } else if (stats.isDirectory()) {
+ if (options.recursive) {
+ // -r was passed, so directory can be removed
+ rmdirSyncRecursive(file, options.force);
+ } else {
+ common.error('path is a directory', { continue: true });
+ }
+ } else if (stats.isSymbolicLink() || stats.isFIFO()) {
+ common.unlinkSync(file);
}
}); // forEach(file)
+ return '';
} // rm
module.exports = _rm;
http://git-wip-us.apache.org/repos/asf/cordova-browser/blob/c846b473/node_modules/shelljs/src/sed.js
----------------------------------------------------------------------
diff --git a/node_modules/shelljs/src/sed.js b/node_modules/shelljs/src/sed.js
index baa385b..dfdc0a7 100644
--- a/node_modules/shelljs/src/sed.js
+++ b/node_modules/shelljs/src/sed.js
@@ -1,6 +1,14 @@
var common = require('./common');
var fs = require('fs');
+common.register('sed', _sed, {
+ globStart: 3, // don't glob-expand regexes
+ canReceivePipe: true,
+ cmdOptions: {
+ 'i': 'inplace',
+ },
+});
+
//@
//@ ### sed([options,] search_regex, replacement, file [, file ...])
//@ ### sed([options,] search_regex, replacement, file_array)
@@ -17,48 +25,62 @@ var fs = require('fs');
//@
//@ Reads an input string from `files` and performs a JavaScript `replace()` on the input
//@ using the given search regex and replacement string or function. Returns the new string after replacement.
+//@
+//@ Note:
+//@
+//@ Like unix `sed`, ShellJS `sed` supports capture groups. Capture groups are specified
+//@ using the `$n` syntax:
+//@
+//@ ```javascript
+//@ sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt');
+//@ ```
function _sed(options, regex, replacement, files) {
- options = common.parseOptions(options, {
- 'i': 'inplace'
- });
+ // Check if this is coming from a pipe
+ var pipe = common.readFromPipe();
- if (typeof replacement === 'string' || typeof replacement === 'function')
- replacement = replacement; // no-op
- else if (typeof replacement === 'number')
- replacement = replacement.toString(); // fallback
- else
- common.error('invalid replacement string');
+ if (typeof replacement !== 'string' && typeof replacement !== 'function') {
+ if (typeof replacement === 'number') {
+ replacement = replacement.toString(); // fallback
+ } else {
+ common.error('invalid replacement string');
+ }
+ }
// Convert all search strings to RegExp
- if (typeof regex === 'string')
+ if (typeof regex === 'string') {
regex = RegExp(regex);
+ }
- if (!files)
+ if (!files && !pipe) {
common.error('no files given');
+ }
- if (typeof files === 'string')
- files = [].slice.call(arguments, 3);
- // if it's array leave it as it is
+ files = [].slice.call(arguments, 3);
- files = common.expand(files);
+ if (pipe) {
+ files.unshift('-');
+ }
var sed = [];
- files.forEach(function(file) {
- if (!fs.existsSync(file)) {
- common.error('no such file or directory: ' + file, true);
+ files.forEach(function (file) {
+ if (!fs.existsSync(file) && file !== '-') {
+ common.error('no such file or directory: ' + file, 2, { continue: true });
return;
}
- var result = fs.readFileSync(file, 'utf8').split('\n').map(function (line) {
+ var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
+ var lines = contents.split(/\r*\n/);
+ var result = lines.map(function (line) {
return line.replace(regex, replacement);
}).join('\n');
sed.push(result);
- if (options.inplace)
+ if (options.inplace) {
fs.writeFileSync(file, result, 'utf8');
+ }
});
- return common.ShellString(sed.join('\n'));
+ return sed.join('\n');
}
module.exports = _sed;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org