mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-26 01:58:06 +02:00
Upgrading ShellJS, introducing 'makeref'
This commit is contained in:
parent
32eb64389e
commit
a0a5c58894
5 changed files with 304 additions and 123 deletions
295
external/shelljs/shell.js
vendored
295
external/shelljs/shell.js
vendored
|
@ -74,9 +74,7 @@ exports.pwd = wrap('pwd', _pwd);
|
|||
//@ ls('-R', ['/users/me', '/tmp']); // same as above
|
||||
//@ ```
|
||||
//@
|
||||
//@ Returns list of files in the given path, or in current directory if no path provided.
|
||||
//@ For convenient iteration via `for (file in ls())`, the format returned is a hash object:
|
||||
//@ `{ 'file1':null, 'dir1/file2':null, ...}`.
|
||||
//@ Returns array of files in the given path, or in current directory if no path provided.
|
||||
function _ls(options, paths) {
|
||||
options = parseOptions(options, {
|
||||
'R': 'recursive',
|
||||
|
@ -90,24 +88,30 @@ function _ls(options, paths) {
|
|||
else if (typeof paths === 'string')
|
||||
paths = [].slice.call(arguments, 1);
|
||||
|
||||
var hash = {};
|
||||
var list = [];
|
||||
|
||||
function pushHash(file, query) {
|
||||
// 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) {
|
||||
// hidden file?
|
||||
if (path.basename(file)[0] === '.') {
|
||||
// not explicitly asking for hidden files?
|
||||
if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
hash[file] = null;
|
||||
if (platform === 'win')
|
||||
file = file.replace(/\\/g, '/');
|
||||
|
||||
list.push(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
paths.forEach(function(p) {
|
||||
if (fs.existsSync(p)) {
|
||||
// Simple file?
|
||||
if (fs.statSync(p).isFile()) {
|
||||
pushHash(p, p);
|
||||
pushFile(p, p);
|
||||
return; // continue
|
||||
}
|
||||
|
||||
|
@ -115,14 +119,17 @@ function _ls(options, paths) {
|
|||
if (fs.statSync(p).isDirectory()) {
|
||||
// Iterate over p contents
|
||||
fs.readdirSync(p).forEach(function(file) {
|
||||
pushHash(file, p);
|
||||
if (!pushFile(file, p))
|
||||
return;
|
||||
|
||||
// Recursive
|
||||
var oldDir = _pwd();
|
||||
_cd('', p);
|
||||
if (fs.statSync(file).isDirectory() && options.recursive)
|
||||
hash = extend(hash, _ls('-R', file+'/*'));
|
||||
_cd('', oldDir);
|
||||
// Recursive?
|
||||
if (options.recursive) {
|
||||
var oldDir = _pwd();
|
||||
_cd('', p);
|
||||
if (fs.statSync(file).isDirectory())
|
||||
list = list.concat(_ls('-R'+(options.all?'a':''), file+'/*'));
|
||||
_cd('', oldDir);
|
||||
}
|
||||
});
|
||||
return; // continue
|
||||
}
|
||||
|
@ -137,17 +144,20 @@ function _ls(options, paths) {
|
|||
// Escape special regular expression chars
|
||||
var regexp = basename.replace(/(\^|\$|\(|\)|\<|\>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
|
||||
// Translates wildcard into regex
|
||||
regexp = '^' + regexp.replace(/\*/g, '.*');
|
||||
regexp = '^' + regexp.replace(/\*/g, '.*') + '$';
|
||||
// Iterate over directory contents
|
||||
fs.readdirSync(dirname).forEach(function(file) {
|
||||
if (file.match(new RegExp(regexp))) {
|
||||
pushHash(path.normalize(dirname+'/'+file), basename);
|
||||
if (!pushFile(path.normalize(dirname+'/'+file), basename))
|
||||
return;
|
||||
|
||||
// Recursive
|
||||
var pp = dirname + '/' + file;
|
||||
if (fs.statSync(pp).isDirectory() && options.recursive)
|
||||
hash = extend(hash, _ls('-R', pp+'/*'));
|
||||
}
|
||||
// Recursive?
|
||||
if (options.recursive) {
|
||||
var pp = dirname + '/' + file;
|
||||
if (fs.statSync(pp).isDirectory())
|
||||
list = list.concat(_ls('-R'+(options.all?'a':''), pp+'/*'));
|
||||
} // recursive
|
||||
} // if file matches
|
||||
}); // forEach
|
||||
return;
|
||||
}
|
||||
|
@ -155,7 +165,7 @@ function _ls(options, paths) {
|
|||
error('no such file or directory: ' + p, true);
|
||||
});
|
||||
|
||||
return hash;
|
||||
return list;
|
||||
};
|
||||
exports.ls = wrap('ls', _ls);
|
||||
|
||||
|
@ -168,16 +178,10 @@ exports.ls = wrap('ls', _ls);
|
|||
//@ ```javascript
|
||||
//@ find('src', 'lib');
|
||||
//@ find(['src', 'lib']); // same as above
|
||||
//@ for (file in find('.')) {
|
||||
//@ if (!file.match(/\.js$/))
|
||||
//@ continue;
|
||||
//@ // all files at this point end in '.js'
|
||||
//@ }
|
||||
//@ find('.').filter(function(file) { return file.match(/\.js$/); });
|
||||
//@ ```
|
||||
//@
|
||||
//@ Returns list of all files (however deep) in the given paths. For convenient iteration
|
||||
//@ via `for (file in find(...))`, the format returned is a hash object:
|
||||
//@ `{ 'file1':null, 'dir1/file2':null, ...}`.
|
||||
//@ Returns array of all files (however deep) in the given paths.
|
||||
//@
|
||||
//@ 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`.
|
||||
|
@ -189,21 +193,28 @@ function _find(options, paths) {
|
|||
else if (typeof paths === 'string')
|
||||
paths = [].slice.call(arguments, 1);
|
||||
|
||||
var hash = {};
|
||||
var list = [];
|
||||
|
||||
function pushFile(file) {
|
||||
if (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){
|
||||
hash[file] = null;
|
||||
paths.forEach(function(file) {
|
||||
pushFile(file);
|
||||
|
||||
if (fs.statSync(file).isDirectory()) {
|
||||
for (subfile in _ls('-Ra', file+'/*'))
|
||||
hash[subfile] = null;
|
||||
_ls('-Ra', file+'/*').forEach(function(subfile) {
|
||||
pushFile(subfile);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return hash;
|
||||
return list;
|
||||
}
|
||||
exports.find = wrap('find', _find);
|
||||
|
||||
|
@ -347,9 +358,20 @@ function _rm(options, files) {
|
|||
|
||||
// Remove simple file
|
||||
if (fs.statSync(file).isFile()) {
|
||||
fs.unlinkSync(file);
|
||||
|
||||
// Do not check for file writing permissions
|
||||
if (options.force) {
|
||||
_unlinkSync(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWriteable(file))
|
||||
_unlinkSync(file);
|
||||
else
|
||||
error('permission denied: '+file, true);
|
||||
|
||||
return;
|
||||
}
|
||||
} // simple file
|
||||
|
||||
// Path is an existing directory, but no -r flag given
|
||||
if (fs.statSync(file).isDirectory() && !options.recursive) {
|
||||
|
@ -359,7 +381,7 @@ function _rm(options, files) {
|
|||
|
||||
// Recursively remove existing directory
|
||||
if (fs.statSync(file).isDirectory() && options.recursive) {
|
||||
rmdirSyncRecursive(file);
|
||||
rmdirSyncRecursive(file, options.force);
|
||||
}
|
||||
}); // forEach(file)
|
||||
}; // rm
|
||||
|
@ -582,7 +604,11 @@ function _to(options, file) {
|
|||
if (!fs.existsSync( path.dirname(file) ))
|
||||
error('no such file or directory: ' + path.dirname(file));
|
||||
|
||||
fs.writeFileSync(file, this.toString(), 'utf8');
|
||||
try {
|
||||
fs.writeFileSync(file, this.toString(), 'utf8');
|
||||
} catch(e) {
|
||||
error('could not write to file (code '+e.code+'): '+file, true);
|
||||
}
|
||||
};
|
||||
// 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
|
||||
|
@ -793,7 +819,7 @@ function _exec(command, options, callback) {
|
|||
}
|
||||
|
||||
options = extend({
|
||||
silent: false,
|
||||
silent: state.silent,
|
||||
async: false
|
||||
}, options);
|
||||
|
||||
|
@ -822,11 +848,52 @@ exports.exec = wrap('exec', _exec, {notUnix:true});
|
|||
//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
|
||||
exports.tempdir = wrap('tempdir', tempDir);
|
||||
|
||||
|
||||
//@
|
||||
//@ #### error()
|
||||
//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
|
||||
//@ otherwise returns string explaining the error
|
||||
exports.error = function() {
|
||||
return state.error;
|
||||
}
|
||||
|
||||
//@
|
||||
//@ #### silent([state])
|
||||
//@ Example:
|
||||
//@
|
||||
//@ ```javascript
|
||||
//@ var silentState = silent();
|
||||
//@ silent(true);
|
||||
//@ /* ... */
|
||||
//@ silent(silentState); // restore old silent state
|
||||
//@ ```
|
||||
//@
|
||||
//@ Suppresses all output if `state = true`. Returns state if no arguments given.
|
||||
exports.silent = function(_state) {
|
||||
if (typeof _state !== 'boolean')
|
||||
return state.silent;
|
||||
|
||||
state.silent = _state;
|
||||
}
|
||||
|
||||
|
||||
//@
|
||||
//@ ## Deprecated
|
||||
//@
|
||||
|
||||
|
||||
|
||||
|
||||
//@
|
||||
//@ #### exists(path [, path ...])
|
||||
//@ #### exists(path_array)
|
||||
//@
|
||||
//@ _This function is being deprecated. Use `test()` instead._
|
||||
//@
|
||||
//@ Returns true if all the given paths exist.
|
||||
function _exists(options, paths) {
|
||||
deprecate('exists', 'Use test() instead.');
|
||||
|
||||
if (!paths)
|
||||
error('no paths given');
|
||||
|
||||
|
@ -844,32 +911,19 @@ function _exists(options, paths) {
|
|||
};
|
||||
exports.exists = wrap('exists', _exists);
|
||||
|
||||
//@
|
||||
//@ #### error()
|
||||
//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
|
||||
//@ otherwise returns string explaining the error
|
||||
exports.error = function() {
|
||||
return state.error;
|
||||
}
|
||||
|
||||
//@
|
||||
//@ #### verbose()
|
||||
//@
|
||||
//@ _This function is being deprecated. Use `silent(false) instead.`_
|
||||
//@
|
||||
//@ Enables all output (default)
|
||||
exports.verbose = function() {
|
||||
deprecate('verbose', 'Use silent(false) instead.');
|
||||
|
||||
state.silent = false;
|
||||
}
|
||||
|
||||
//@
|
||||
//@ #### silent()
|
||||
//@ Suppresses all output, except for explict `echo()` calls
|
||||
exports.silent = function() {
|
||||
state.silent = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -889,6 +943,10 @@ function log() {
|
|||
console.log.apply(this, arguments);
|
||||
}
|
||||
|
||||
function deprecate(what, msg) {
|
||||
console.log('*** ShellJS.'+what+': This function is deprecated.', msg);
|
||||
}
|
||||
|
||||
function write(msg) {
|
||||
if (!state.silent)
|
||||
process.stdout.write(msg);
|
||||
|
@ -984,10 +1042,22 @@ function copyFileSync(srcFile, destFile) {
|
|||
|
||||
var BUF_LENGTH = 64*1024,
|
||||
buf = new Buffer(BUF_LENGTH),
|
||||
fdr = fs.openSync(srcFile, 'r'),
|
||||
fdw = fs.openSync(destFile, 'w'),
|
||||
bytesRead = BUF_LENGTH,
|
||||
pos = 0;
|
||||
pos = 0,
|
||||
fdr = null,
|
||||
fdw = null;
|
||||
|
||||
try {
|
||||
fdr = fs.openSync(srcFile, 'r');
|
||||
} catch(e) {
|
||||
error('copyFileSync: could not read src file ('+srcFile+')');
|
||||
}
|
||||
|
||||
try {
|
||||
fdw = fs.openSync(destFile, 'w');
|
||||
} catch(e) {
|
||||
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);
|
||||
|
@ -1050,28 +1120,42 @@ function cpdirSyncRecursive(sourceDir, destDir, opts) {
|
|||
//
|
||||
// Licensed under the MIT License
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
function rmdirSyncRecursive(dir) {
|
||||
function rmdirSyncRecursive(dir, force) {
|
||||
var files;
|
||||
|
||||
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 currFile = fs.lstatSync(dir + "/" + files[i]);
|
||||
var file = dir + "/" + files[i],
|
||||
currFile = fs.lstatSync(file);
|
||||
|
||||
if(currFile.isDirectory()) // Recursive function back to the beginning
|
||||
rmdirSyncRecursive(dir + "/" + files[i]);
|
||||
if(currFile.isDirectory()) { // Recursive function back to the beginning
|
||||
rmdirSyncRecursive(file, force);
|
||||
}
|
||||
|
||||
else if(currFile.isSymbolicLink()) // Unlink symlinks
|
||||
fs.unlinkSync(dir + "/" + files[i]);
|
||||
else if(currFile.isSymbolicLink()) { // Unlink symlinks
|
||||
if (force || isWriteable(file))
|
||||
_unlinkSync(file);
|
||||
}
|
||||
|
||||
else // Assume it's a file - perhaps a try/catch belongs here?
|
||||
fs.unlinkSync(dir + "/" + files[i]);
|
||||
if (force || isWriteable(file))
|
||||
_unlinkSync(file);
|
||||
}
|
||||
|
||||
// Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
|
||||
// Huzzah for the shopkeep.
|
||||
return fs.rmdirSync(dir);
|
||||
|
||||
var result;
|
||||
try {
|
||||
result = fs.rmdirSync(dir);
|
||||
} catch(e) {
|
||||
if (e.code === 'ENOTEMPTY')
|
||||
error('directory not empty: ' + dir, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}; // rmdirSyncRecursive
|
||||
|
||||
// Recursively creates 'dir'
|
||||
|
@ -1118,7 +1202,7 @@ function writeableDir(dir) {
|
|||
var testFile = dir+'/'+randomFileName();
|
||||
try {
|
||||
fs.writeFileSync(testFile, ' ');
|
||||
fs.unlinkSync(testFile);
|
||||
_unlinkSync(testFile);
|
||||
return dir;
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
@ -1150,7 +1234,8 @@ function tempDir() {
|
|||
|
||||
// Wrapper around exec() to enable echoing output to console in real time
|
||||
function execAsync(cmd, opts, callback) {
|
||||
var output = '';
|
||||
var output = '',
|
||||
silent = 'silent' in opts ? opts.silent : state.silent;
|
||||
|
||||
var c = child.exec(cmd, {env: process.env}, function(err) {
|
||||
if (callback)
|
||||
|
@ -1159,13 +1244,13 @@ function execAsync(cmd, opts, callback) {
|
|||
|
||||
c.stdout.on('data', function(data) {
|
||||
output += data;
|
||||
if (!opts.silent)
|
||||
if (!silent)
|
||||
write(data);
|
||||
});
|
||||
|
||||
c.stderr.on('data', function(data) {
|
||||
output += data;
|
||||
if (!opts.silent)
|
||||
if (!silent)
|
||||
write(data);
|
||||
});
|
||||
}
|
||||
|
@ -1178,16 +1263,17 @@ function execAsync(cmd, opts, callback) {
|
|||
function execSync(cmd, opts) {
|
||||
var stdoutFile = path.resolve(tempDir()+'/'+randomFileName()),
|
||||
codeFile = path.resolve(tempDir()+'/'+randomFileName()),
|
||||
scriptFile = path.resolve(tempDir()+'/'+randomFileName());
|
||||
scriptFile = path.resolve(tempDir()+'/'+randomFileName()),
|
||||
sleepFile = path.resolve(tempDir()+'/'+randomFileName());
|
||||
|
||||
var options = extend({
|
||||
silent: false
|
||||
silent: state.silent
|
||||
}, opts);
|
||||
|
||||
var previousStdoutContent = '';
|
||||
// Echoes stdout changes from running process, if not silent
|
||||
function updateStdout() {
|
||||
if (state.silent || options.silent || !fs.existsSync(stdoutFile))
|
||||
if (options.silent || !fs.existsSync(stdoutFile))
|
||||
return;
|
||||
|
||||
var stdoutContent = fs.readFileSync(stdoutFile, 'utf8');
|
||||
|
@ -1214,9 +1300,9 @@ function execSync(cmd, opts) {
|
|||
fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0'); \
|
||||
});";
|
||||
|
||||
if (fs.existsSync(scriptFile)) fs.unlinkSync(scriptFile);
|
||||
if (fs.existsSync(stdoutFile)) fs.unlinkSync(stdoutFile);
|
||||
if (fs.existsSync(codeFile)) fs.unlinkSync(codeFile);
|
||||
if (fs.existsSync(scriptFile)) _unlinkSync(scriptFile);
|
||||
if (fs.existsSync(stdoutFile)) _unlinkSync(stdoutFile);
|
||||
if (fs.existsSync(codeFile)) _unlinkSync(codeFile);
|
||||
|
||||
fs.writeFileSync(scriptFile, script);
|
||||
child.exec('node '+scriptFile, {
|
||||
|
@ -1225,8 +1311,11 @@ function execSync(cmd, opts) {
|
|||
});
|
||||
|
||||
// The wait loop
|
||||
while (!fs.existsSync(codeFile)) { updateStdout(); };
|
||||
while (!fs.existsSync(stdoutFile)) { updateStdout(); };
|
||||
// sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage
|
||||
// (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing
|
||||
// CPU usage, though apparently not so much on Windows)
|
||||
while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); };
|
||||
while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); };
|
||||
|
||||
// At this point codeFile exists, but it's not necessarily flushed yet.
|
||||
// Keep reading it until it is.
|
||||
|
@ -1236,9 +1325,10 @@ function execSync(cmd, opts) {
|
|||
|
||||
var stdout = fs.readFileSync(stdoutFile, 'utf8');
|
||||
|
||||
fs.unlinkSync(scriptFile);
|
||||
fs.unlinkSync(stdoutFile);
|
||||
fs.unlinkSync(codeFile);
|
||||
_unlinkSync(scriptFile);
|
||||
_unlinkSync(stdoutFile);
|
||||
_unlinkSync(codeFile);
|
||||
_unlinkSync(sleepFile);
|
||||
|
||||
// True if successful, false if not
|
||||
var obj = {
|
||||
|
@ -1257,8 +1347,9 @@ function expand(list) {
|
|||
list.forEach(function(listEl) {
|
||||
// Wildcard present?
|
||||
if (listEl.search(/\*/) > -1) {
|
||||
for (file in _ls('', listEl))
|
||||
_ls('', listEl).forEach(function(file) {
|
||||
expanded.push(file);
|
||||
});
|
||||
} else {
|
||||
expanded.push(listEl);
|
||||
}
|
||||
|
@ -1290,3 +1381,33 @@ function extend(target) {
|
|||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
|
||||
// file can be unlinked even if it's read-only, see joyent/node#3006
|
||||
function _unlinkSync(file) {
|
||||
try {
|
||||
fs.unlinkSync(file);
|
||||
} catch(e) {
|
||||
// Try to override file permission
|
||||
if (e.code === 'EPERM') {
|
||||
fs.chmodSync(file, '0666');
|
||||
fs.unlinkSync(file);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hack to determine if file has write permissions for current user
|
||||
// Avoids having to check user, group, etc, but it's probably slow
|
||||
function isWriteable(file) {
|
||||
var writePermission = true;
|
||||
try {
|
||||
var __fd = fs.openSync(file, 'a');
|
||||
fs.closeSync(__fd);
|
||||
} catch(e) {
|
||||
writePermission = false;
|
||||
}
|
||||
|
||||
return writePermission;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue