set basic layout. adding status bar
This commit is contained in:
30
node_modules/bower/lib/util/abbreviations.js
generated
vendored
Normal file
30
node_modules/bower/lib/util/abbreviations.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
var abbrev = require('abbrev');
|
||||
var mout = require('mout');
|
||||
|
||||
function expandNames(obj, prefix, stack) {
|
||||
prefix = prefix || '';
|
||||
stack = stack || [];
|
||||
|
||||
mout.object.forOwn(obj, function(value, name) {
|
||||
name = prefix + name;
|
||||
|
||||
stack.push(name);
|
||||
|
||||
if (typeof value === 'object' && !value.line) {
|
||||
expandNames(value, name + ' ', stack);
|
||||
}
|
||||
});
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
module.exports = function(commands) {
|
||||
var abbreviations = abbrev(expandNames(commands));
|
||||
|
||||
abbreviations.i = 'install';
|
||||
abbreviations.rm = 'uninstall';
|
||||
abbreviations.unlink = 'uninstall';
|
||||
abbreviations.ls = 'list';
|
||||
|
||||
return abbreviations;
|
||||
};
|
||||
49
node_modules/bower/lib/util/cli.js
generated
vendored
Normal file
49
node_modules/bower/lib/util/cli.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
var mout = require('mout');
|
||||
var nopt = require('nopt');
|
||||
var renderers = require('../renderers');
|
||||
|
||||
function readOptions(options, argv) {
|
||||
var types;
|
||||
var noptOptions;
|
||||
var parsedOptions = {};
|
||||
var shorthands = {};
|
||||
|
||||
if (Array.isArray(options)) {
|
||||
argv = options;
|
||||
options = {};
|
||||
} else {
|
||||
options = options || {};
|
||||
}
|
||||
|
||||
types = mout.object.map(options, function(option) {
|
||||
return option.type;
|
||||
});
|
||||
mout.object.forOwn(options, function(option, name) {
|
||||
shorthands[option.shorthand] = '--' + name;
|
||||
});
|
||||
|
||||
noptOptions = nopt(types, shorthands, argv);
|
||||
|
||||
// Filter only the specified options because nopt parses every --
|
||||
// Also make them camel case
|
||||
mout.object.forOwn(noptOptions, function(value, key) {
|
||||
if (options[key]) {
|
||||
parsedOptions[mout.string.camelCase(key)] = value;
|
||||
}
|
||||
});
|
||||
|
||||
parsedOptions.argv = noptOptions.argv;
|
||||
|
||||
return parsedOptions;
|
||||
}
|
||||
|
||||
function getRenderer(command, json, config) {
|
||||
if (config.json || json) {
|
||||
return new renderers.Json(command, config);
|
||||
}
|
||||
|
||||
return new renderers.Standard(command, config);
|
||||
}
|
||||
|
||||
module.exports.readOptions = readOptions;
|
||||
module.exports.getRenderer = getRenderer;
|
||||
129
node_modules/bower/lib/util/cmd.js
generated
vendored
Normal file
129
node_modules/bower/lib/util/cmd.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
var cp = require('child_process');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var which = require('which');
|
||||
var PThrottler = require('p-throttler');
|
||||
var createError = require('./createError');
|
||||
|
||||
// The concurrency limit here is kind of magic. You don't really gain a lot from
|
||||
// having a large number of commands spawned at once, so it isn't super
|
||||
// important for this number to be large. Reports have shown that much more than 5
|
||||
// or 10 cause issues for corporate networks, private repos or situations where
|
||||
// internet bandwidth is limited. We're running with a concurrency of 5 until
|
||||
// 1.4.X is released, at which time we'll move to what was discussed in #1262
|
||||
// https://github.com/bower/bower/pull/1262
|
||||
var throttler = new PThrottler(5);
|
||||
|
||||
var winBatchExtensions;
|
||||
var winWhichCache;
|
||||
var isWin = process.platform === 'win32';
|
||||
|
||||
if (isWin) {
|
||||
winBatchExtensions = ['.bat', '.cmd'];
|
||||
winWhichCache = {};
|
||||
}
|
||||
|
||||
function getWindowsCommand(command) {
|
||||
var fullCommand;
|
||||
var extension;
|
||||
|
||||
// Do we got the value converted in the cache?
|
||||
if (mout.object.hasOwn(winWhichCache, command)) {
|
||||
return winWhichCache[command];
|
||||
}
|
||||
|
||||
// Use which to retrieve the full command, which puts the extension in the end
|
||||
try {
|
||||
fullCommand = which.sync(command);
|
||||
} catch (err) {
|
||||
return (winWhichCache[command] = command);
|
||||
}
|
||||
|
||||
extension = path.extname(fullCommand).toLowerCase();
|
||||
|
||||
// Does it need to be converted?
|
||||
if (winBatchExtensions.indexOf(extension) === -1) {
|
||||
return (winWhichCache[command] = command);
|
||||
}
|
||||
|
||||
return (winWhichCache[command] = fullCommand);
|
||||
}
|
||||
|
||||
// Executes a shell command, buffering the stdout and stderr
|
||||
// If an error occurs, a meaningful error is generated
|
||||
// Returns a promise that gets fulfilled if the command succeeds
|
||||
// or rejected if it fails
|
||||
function executeCmd(command, args, options) {
|
||||
var process;
|
||||
var stderr = '';
|
||||
var stdout = '';
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Windows workaround for .bat and .cmd files, see #626
|
||||
if (isWin) {
|
||||
command = getWindowsCommand(command);
|
||||
}
|
||||
|
||||
// Buffer output, reporting progress
|
||||
process = cp.spawn(command, args, options);
|
||||
process.stdout.on('data', function(data) {
|
||||
data = data.toString();
|
||||
deferred.notify(data);
|
||||
stdout += data;
|
||||
});
|
||||
process.stderr.on('data', function(data) {
|
||||
data = data.toString();
|
||||
deferred.notify(data);
|
||||
stderr += data;
|
||||
});
|
||||
|
||||
// If there is an error spawning the command, reject the promise
|
||||
process.on('error', function(error) {
|
||||
return deferred.reject(error);
|
||||
});
|
||||
|
||||
// Listen to the close event instead of exit
|
||||
// They are similar but close ensures that streams are flushed
|
||||
process.on('close', function(code) {
|
||||
var fullCommand;
|
||||
var error;
|
||||
|
||||
if (code) {
|
||||
// Generate the full command to be presented in the error message
|
||||
if (!Array.isArray(args)) {
|
||||
args = [];
|
||||
}
|
||||
|
||||
fullCommand = command;
|
||||
fullCommand += args.length ? ' ' + args.join(' ') : '';
|
||||
|
||||
// Build the error instance
|
||||
error = createError(
|
||||
'Failed to execute "' +
|
||||
fullCommand +
|
||||
'", exit code of #' +
|
||||
code +
|
||||
'\n' +
|
||||
stderr,
|
||||
'ECMDERR',
|
||||
{
|
||||
details: stderr,
|
||||
exitCode: code
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.reject(error);
|
||||
}
|
||||
|
||||
return deferred.resolve([stdout, stderr]);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function cmd(command, args, options) {
|
||||
return throttler.enqueue(executeCmd.bind(null, command, args, options));
|
||||
}
|
||||
|
||||
module.exports = cmd;
|
||||
119
node_modules/bower/lib/util/copy.js
generated
vendored
Normal file
119
node_modules/bower/lib/util/copy.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
var fstream = require('fstream');
|
||||
var fstreamIgnore = require('fstream-ignore');
|
||||
var fs = require('./fs');
|
||||
var Q = require('q');
|
||||
|
||||
function copy(reader, writer) {
|
||||
var deferred;
|
||||
var ignore;
|
||||
|
||||
// Filter symlinks because they are not 100% portable, specially
|
||||
// when linking between different drives
|
||||
// Following can't be enabled either because symlinks that reference
|
||||
// another symlinks will get filtered
|
||||
// See: https://github.com/bower/bower/issues/699
|
||||
reader.filter = filterSymlinks;
|
||||
reader.follow = false;
|
||||
|
||||
if (reader.type === 'Directory' && reader.ignore) {
|
||||
ignore = reader.ignore;
|
||||
reader = fstreamIgnore(reader);
|
||||
reader.addIgnoreRules(ignore);
|
||||
} else {
|
||||
reader = fstream.Reader(reader);
|
||||
}
|
||||
|
||||
deferred = Q.defer();
|
||||
|
||||
reader
|
||||
.on('error', deferred.reject)
|
||||
// Pipe to writer
|
||||
.pipe(fstream.Writer(writer))
|
||||
.on('error', deferred.reject)
|
||||
.on('close', deferred.resolve);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function copyMode(src, dst) {
|
||||
return Q.nfcall(fs.stat, src).then(function(stat) {
|
||||
return Q.nfcall(fs.chmod, dst, stat.mode);
|
||||
});
|
||||
}
|
||||
|
||||
function filterSymlinks(entry) {
|
||||
return entry.type !== 'SymbolicLink';
|
||||
}
|
||||
|
||||
function parseOptions(opts) {
|
||||
opts = opts || {};
|
||||
|
||||
if (opts.mode != null) {
|
||||
opts.copyMode = false;
|
||||
} else if (opts.copyMode == null) {
|
||||
opts.copyMode = true;
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
|
||||
// Available options:
|
||||
// - mode: force final mode of dst (defaults to null)
|
||||
// - copyMode: copy mode of src to dst, only if mode is not specified (defaults to true)
|
||||
function copyFile(src, dst, opts) {
|
||||
var promise;
|
||||
|
||||
opts = parseOptions(opts);
|
||||
|
||||
promise = copy(
|
||||
{
|
||||
path: src,
|
||||
type: 'File'
|
||||
},
|
||||
{
|
||||
path: dst,
|
||||
mode: opts.mode,
|
||||
type: 'File'
|
||||
}
|
||||
);
|
||||
|
||||
if (opts.copyMode) {
|
||||
promise = promise.then(copyMode.bind(copyMode, src, dst));
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
// Available options:
|
||||
// - ignore: array of patterns to be ignored (defaults to null)
|
||||
// - mode: force final mode of dst (defaults to null)
|
||||
// - copyMode: copy mode of src to dst, only if mode is not specified (defaults to true)
|
||||
function copyDir(src, dst, opts) {
|
||||
var promise;
|
||||
|
||||
opts = parseOptions(opts);
|
||||
|
||||
promise = copy(
|
||||
{
|
||||
path: src,
|
||||
type: 'Directory',
|
||||
ignore: opts.ignore
|
||||
},
|
||||
{
|
||||
path: dst,
|
||||
mode: opts.mode,
|
||||
type: 'Directory'
|
||||
}
|
||||
);
|
||||
|
||||
if (opts.copyMode) {
|
||||
promise = promise.then(copyMode.bind(copyMode, src, dst));
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
module.exports.copyDir = copyDir;
|
||||
module.exports.copyFile = copyFile;
|
||||
14
node_modules/bower/lib/util/createError.js
generated
vendored
Normal file
14
node_modules/bower/lib/util/createError.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
var mout = require('mout');
|
||||
|
||||
function createError(msg, code, props) {
|
||||
var err = new Error(msg);
|
||||
err.code = code;
|
||||
|
||||
if (props) {
|
||||
mout.object.mixIn(err, props);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
module.exports = createError;
|
||||
64
node_modules/bower/lib/util/createLink.js
generated
vendored
Normal file
64
node_modules/bower/lib/util/createLink.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
var fs = require('./fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var mkdirp = require('mkdirp');
|
||||
var createError = require('./createError');
|
||||
|
||||
var isWin = process.platform === 'win32';
|
||||
|
||||
function createLink(src, dst, type) {
|
||||
var dstDir = path.dirname(dst);
|
||||
|
||||
// Create directory
|
||||
return (
|
||||
Q.nfcall(mkdirp, dstDir)
|
||||
// Check if source exists
|
||||
.then(function() {
|
||||
return Q.nfcall(fs.stat, src).fail(function(error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
throw createError(
|
||||
'Failed to create link to ' + path.basename(src),
|
||||
'ENOENT',
|
||||
{
|
||||
details:
|
||||
src +
|
||||
' does not exist or points to a non-existent file'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
})
|
||||
// Create symlink
|
||||
.then(function(stat) {
|
||||
type = type || (stat.isDirectory() ? 'dir' : 'file');
|
||||
|
||||
return Q.nfcall(fs.symlink, src, dst, type).fail(function(err) {
|
||||
if (!isWin || err.code !== 'EPERM') {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Try with type "junction" on Windows
|
||||
// Junctions behave equally to true symlinks and can be created in
|
||||
// non elevated terminal (well, not always..)
|
||||
return Q.nfcall(fs.symlink, src, dst, 'junction').fail(
|
||||
function(err) {
|
||||
throw createError(
|
||||
'Unable to create link to ' +
|
||||
path.basename(src),
|
||||
err.code,
|
||||
{
|
||||
details:
|
||||
err.message.trim() +
|
||||
'\n\nTry running this command in an elevated terminal (run as root/administrator).'
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = createLink;
|
||||
153
node_modules/bower/lib/util/download.js
generated
vendored
Normal file
153
node_modules/bower/lib/util/download.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
var progress = require('request-progress');
|
||||
var request = require('request');
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var retry = require('retry');
|
||||
var createError = require('./createError');
|
||||
var createWriteStream = require('fs-write-stream-atomic');
|
||||
var destroy = require('destroy');
|
||||
|
||||
var errorCodes = [
|
||||
'EADDRINFO',
|
||||
'ETIMEDOUT',
|
||||
'ECONNRESET',
|
||||
'ESOCKETTIMEDOUT',
|
||||
'ENOTFOUND'
|
||||
];
|
||||
|
||||
function download(url, file, options) {
|
||||
var operation;
|
||||
var deferred = Q.defer();
|
||||
var progressDelay = 8000;
|
||||
|
||||
options = mout.object.mixIn(
|
||||
{
|
||||
retries: 5,
|
||||
factor: 2,
|
||||
minTimeout: 1000,
|
||||
maxTimeout: 35000,
|
||||
randomize: true,
|
||||
progressDelay: progressDelay,
|
||||
gzip: true
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
|
||||
// Retry on network errors
|
||||
operation = retry.operation(options);
|
||||
|
||||
operation.attempt(function() {
|
||||
Q.fcall(fetch, url, file, options)
|
||||
.then(function(response) {
|
||||
deferred.resolve(response);
|
||||
})
|
||||
.progress(function(status) {
|
||||
deferred.notify(status);
|
||||
})
|
||||
.fail(function(error) {
|
||||
// Save timeout before retrying to report
|
||||
var timeout = operation._timeouts[0];
|
||||
|
||||
// Reject if error is not a network error
|
||||
if (errorCodes.indexOf(error.code) === -1) {
|
||||
return deferred.reject(error);
|
||||
}
|
||||
|
||||
// Next attempt will start reporting download progress immediately
|
||||
progressDelay = 0;
|
||||
|
||||
// This will schedule next retry or return false
|
||||
if (operation.retry(error)) {
|
||||
deferred.notify({
|
||||
retry: true,
|
||||
delay: timeout,
|
||||
error: error
|
||||
});
|
||||
} else {
|
||||
deferred.reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function fetch(url, file, options) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var contentLength;
|
||||
var bytesDownloaded = 0;
|
||||
|
||||
var reject = function(error) {
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
var req = progress(request(url, options), {
|
||||
delay: options.progressDelay
|
||||
})
|
||||
.on('response', function(response) {
|
||||
contentLength = Number(response.headers['content-length']);
|
||||
|
||||
var status = response.statusCode;
|
||||
|
||||
if (status < 200 || status >= 300) {
|
||||
return deferred.reject(
|
||||
createError('Status code of ' + status, 'EHTTP')
|
||||
);
|
||||
}
|
||||
|
||||
var writeStream = createWriteStream(file);
|
||||
var errored = false;
|
||||
|
||||
// Change error listener so it cleans up writeStream before exiting
|
||||
req.removeListener('error', reject);
|
||||
req.on('error', function(error) {
|
||||
errored = true;
|
||||
destroy(req);
|
||||
destroy(writeStream);
|
||||
|
||||
// Wait for writeStream to cleanup after itself...
|
||||
// TODO: Maybe there's a better way?
|
||||
setTimeout(function() {
|
||||
deferred.reject(error);
|
||||
}, 50);
|
||||
});
|
||||
|
||||
writeStream.on('finish', function() {
|
||||
if (!errored) {
|
||||
destroy(req);
|
||||
deferred.resolve(response);
|
||||
}
|
||||
});
|
||||
|
||||
req.pipe(writeStream);
|
||||
})
|
||||
.on('data', function(data) {
|
||||
bytesDownloaded += data.length;
|
||||
})
|
||||
.on('progress', function(state) {
|
||||
deferred.notify(state);
|
||||
})
|
||||
.on('error', reject)
|
||||
.on('end', function() {
|
||||
// Check if the whole file was downloaded
|
||||
// In some unstable connections the ACK/FIN packet might be sent in the
|
||||
// middle of the download
|
||||
// See: https://github.com/joyent/node/issues/6143
|
||||
if (contentLength && bytesDownloaded < contentLength) {
|
||||
req.emit(
|
||||
'error',
|
||||
createError(
|
||||
'Transfer closed with ' +
|
||||
(contentLength - bytesDownloaded) +
|
||||
' bytes remaining to read',
|
||||
'EINCOMPLETE'
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
module.exports = download;
|
||||
278
node_modules/bower/lib/util/extract.js
generated
vendored
Normal file
278
node_modules/bower/lib/util/extract.js
generated
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
var path = require('path');
|
||||
var fs = require('./fs');
|
||||
var zlib = require('zlib');
|
||||
var DecompressZip = require('decompress-zip');
|
||||
var tar = require('tar-fs');
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var junk = require('junk');
|
||||
var createError = require('./createError');
|
||||
var createWriteStream = require('fs-write-stream-atomic');
|
||||
var destroy = require('destroy');
|
||||
var tmp = require('tmp');
|
||||
|
||||
// This forces the default chunk size to something small in an attempt
|
||||
// to avoid issue #314
|
||||
zlib.Z_DEFAULT_CHUNK = 1024 * 8;
|
||||
|
||||
var extractors;
|
||||
var extractorTypes;
|
||||
|
||||
extractors = {
|
||||
'.zip': extractZip,
|
||||
'.tar': extractTar,
|
||||
'.tar.gz': extractTarGz,
|
||||
'.tgz': extractTarGz,
|
||||
'.gz': extractGz,
|
||||
'application/zip': extractZip,
|
||||
'application/x-zip': extractZip,
|
||||
'application/x-zip-compressed': extractZip,
|
||||
'application/x-tar': extractTar,
|
||||
'application/x-tgz': extractTarGz,
|
||||
'application/x-gzip': extractGz
|
||||
};
|
||||
|
||||
extractorTypes = Object.keys(extractors);
|
||||
|
||||
function extractZip(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
new DecompressZip(archive)
|
||||
.on('error', deferred.reject)
|
||||
.on('extract', deferred.resolve.bind(deferred, dst))
|
||||
.extract({
|
||||
path: dst,
|
||||
follow: false, // Do not follow symlinks (#699)
|
||||
filter: filterSymlinks // Filter symlink files
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function extractTar(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function(error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
stream
|
||||
.on('error', reject)
|
||||
.pipe(
|
||||
tar.extract(dst, {
|
||||
ignore: isSymlink, // Filter symlink files
|
||||
dmode: 0555, // Ensure dirs are readable
|
||||
fmode: 0444 // Ensure files are readable
|
||||
})
|
||||
)
|
||||
.on('error', reject)
|
||||
.on('finish', function(result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function extractTarGz(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function(error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
stream
|
||||
.on('error', reject)
|
||||
.pipe(zlib.createGunzip())
|
||||
.on('error', reject)
|
||||
.pipe(
|
||||
tar.extract(dst, {
|
||||
ignore: isSymlink, // Filter symlink files
|
||||
dmode: 0555, // Ensure dirs are readable
|
||||
fmode: 0444 // Ensure files are readable
|
||||
})
|
||||
)
|
||||
.on('error', reject)
|
||||
.on('finish', function(result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function extractGz(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function(error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
stream
|
||||
.on('error', reject)
|
||||
.pipe(zlib.createGunzip())
|
||||
.on('error', reject)
|
||||
.pipe(createWriteStream(dst))
|
||||
.on('error', reject)
|
||||
.on('finish', function(result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function isSymlink(_, entry) {
|
||||
return entry.type === 'symlink';
|
||||
}
|
||||
|
||||
function filterSymlinks(entry) {
|
||||
return entry.type !== 'SymbolicLink';
|
||||
}
|
||||
|
||||
function getExtractor(archive) {
|
||||
// Make the archive lower case to match against the types
|
||||
// This ensures that upper-cased extensions work
|
||||
archive = archive.toLowerCase();
|
||||
|
||||
var type = mout.array.find(extractorTypes, function(type) {
|
||||
return mout.string.endsWith(archive, type);
|
||||
});
|
||||
|
||||
return type ? extractors[type] : null;
|
||||
}
|
||||
|
||||
function isSingleDir(dir) {
|
||||
return Q.nfcall(fs.readdir, dir).then(function(files) {
|
||||
var singleDir;
|
||||
|
||||
// Remove any OS specific files from the files array
|
||||
// before checking its length
|
||||
files = files.filter(junk.isnt);
|
||||
|
||||
if (files.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
singleDir = path.join(dir, files[0]);
|
||||
|
||||
return Q.nfcall(fs.stat, singleDir).then(function(stat) {
|
||||
return stat.isDirectory() ? singleDir : false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function moveDirectory(srcDir, destDir) {
|
||||
return Q.nfcall(fs.readdir, srcDir)
|
||||
.then(function(files) {
|
||||
var promises = files.map(function(file) {
|
||||
var src = path.join(srcDir, file);
|
||||
var dst = path.join(destDir, file);
|
||||
|
||||
return Q.nfcall(fs.rename, src, dst);
|
||||
});
|
||||
|
||||
return Q.all(promises);
|
||||
})
|
||||
.then(function() {
|
||||
return Q.nfcall(fs.rmdir, srcDir);
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
|
||||
function canExtract(src, mimeType) {
|
||||
if (mimeType && mimeType !== 'application/octet-stream') {
|
||||
return !!getExtractor(mimeType);
|
||||
}
|
||||
|
||||
return !!getExtractor(src);
|
||||
}
|
||||
|
||||
// Available options:
|
||||
// - keepArchive: true to keep the archive afterwards (defaults to false)
|
||||
// - keepStructure: true to keep the extracted structure unchanged (defaults to false)
|
||||
function extract(src, dst, opts) {
|
||||
var extractor;
|
||||
var promise;
|
||||
|
||||
opts = opts || {};
|
||||
extractor = getExtractor(src);
|
||||
|
||||
// Try to get extractor from mime type
|
||||
if (!extractor && opts.mimeType) {
|
||||
extractor = getExtractor(opts.mimeType);
|
||||
}
|
||||
|
||||
// If extractor is null, then the archive type is unknown
|
||||
if (!extractor) {
|
||||
return Q.reject(
|
||||
createError(
|
||||
'File ' + src + ' is not a known archive',
|
||||
'ENOTARCHIVE'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Extract to a temporary directory in case of file name clashes
|
||||
return Q.nfcall(tmp.dir, {
|
||||
template: dst + '-XXXXXX',
|
||||
mode: 0777 & ~process.umask()
|
||||
})
|
||||
.then(function(tempDir) {
|
||||
// nfcall may return multiple callback arguments as an array
|
||||
return Array.isArray(tempDir) ? tempDir[0] : tempDir;
|
||||
})
|
||||
.then(function(tempDir) {
|
||||
// Check archive file size
|
||||
promise = Q.nfcall(fs.stat, src).then(function(stat) {
|
||||
if (stat.size <= 8) {
|
||||
throw createError(
|
||||
'File ' + src + ' is an invalid archive',
|
||||
'ENOTARCHIVE'
|
||||
);
|
||||
}
|
||||
|
||||
// Extract archive
|
||||
return extractor(src, tempDir);
|
||||
});
|
||||
|
||||
// Remove archive
|
||||
if (!opts.keepArchive) {
|
||||
promise = promise.then(function() {
|
||||
return Q.nfcall(fs.unlink, src);
|
||||
});
|
||||
}
|
||||
|
||||
// Move contents from the temporary directory
|
||||
// If the contents are a single directory (and we're not preserving structure),
|
||||
// move its contents directly instead.
|
||||
promise = promise
|
||||
.then(function() {
|
||||
return isSingleDir(tempDir);
|
||||
})
|
||||
.then(function(singleDir) {
|
||||
if (singleDir && !opts.keepStructure) {
|
||||
return moveDirectory(singleDir, dst);
|
||||
} else {
|
||||
return moveDirectory(tempDir, dst);
|
||||
}
|
||||
});
|
||||
|
||||
// Resolve promise to the dst dir
|
||||
return promise.then(function() {
|
||||
return dst;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = extract;
|
||||
module.exports.canExtract = canExtract;
|
||||
34
node_modules/bower/lib/util/fs.js
generated
vendored
Normal file
34
node_modules/bower/lib/util/fs.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
var fs = require('graceful-fs');
|
||||
|
||||
var readdir = fs.readdir.bind(fs);
|
||||
var readdirSync = fs.readdirSync.bind(fs);
|
||||
|
||||
module.exports = fs;
|
||||
|
||||
module.exports.readdir = function(dir, callback) {
|
||||
fs.stat(dir, function(err, stats) {
|
||||
if (err) return callback(err);
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return readdir(dir, callback);
|
||||
} else {
|
||||
var error = new Error("ENOTDIR, not a directory '" + dir + "'");
|
||||
error.code = 'ENOTDIR';
|
||||
error.path = dir;
|
||||
error.errono = -20;
|
||||
return callback(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.readdirSync = function(dir) {
|
||||
var stats = fs.statSync(dir);
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return readdirSync(dir);
|
||||
} else {
|
||||
var error = new Error();
|
||||
error.code = 'ENOTDIR';
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
5
node_modules/bower/lib/util/isPathAbsolute.js
generated
vendored
Normal file
5
node_modules/bower/lib/util/isPathAbsolute.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
function isPathAbsolute(filePath) {
|
||||
return filePath.charAt(0) === '/';
|
||||
}
|
||||
|
||||
module.exports = isPathAbsolute;
|
||||
55
node_modules/bower/lib/util/readJson.js
generated
vendored
Normal file
55
node_modules/bower/lib/util/readJson.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
var path = require('path');
|
||||
var bowerJson = require('bower-json');
|
||||
var Q = require('q');
|
||||
|
||||
// The valid options are the same as bower-json#readFile.
|
||||
// If the "assume" option is passed, it will be used if no json file was found
|
||||
|
||||
// This promise is resolved with [json, deprecated, assumed]
|
||||
// - json: The read json
|
||||
// - deprecated: The deprecated filename being used or false otherwise
|
||||
// - assumed: True if a dummy json was returned if no json file was found, false otherwise
|
||||
function readJson(file, options) {
|
||||
options = options || {};
|
||||
|
||||
// Read
|
||||
return Q.nfcall(bowerJson.read, file, options).spread(
|
||||
function(json, jsonFile) {
|
||||
var deprecated;
|
||||
|
||||
if (options.logger) {
|
||||
var issues = bowerJson.getIssues(json);
|
||||
if (issues.warnings.length > 0) {
|
||||
options.logger.warn('invalid-meta', 'for:' + jsonFile);
|
||||
}
|
||||
issues.warnings.forEach(function(warning) {
|
||||
options.logger.warn('invalid-meta', warning);
|
||||
});
|
||||
}
|
||||
|
||||
jsonFile = path.basename(jsonFile);
|
||||
deprecated = jsonFile === 'component.json' ? jsonFile : false;
|
||||
|
||||
return [json, deprecated, false];
|
||||
},
|
||||
function(err) {
|
||||
// No json file was found, assume one
|
||||
if (err.code === 'ENOENT' && options.assume) {
|
||||
return [bowerJson.parse(options.assume, options), false, true];
|
||||
}
|
||||
|
||||
err.details = err.message;
|
||||
|
||||
if (err.file) {
|
||||
err.message = 'Failed to read ' + err.file;
|
||||
err.data = { filename: err.file };
|
||||
} else {
|
||||
err.message = 'Failed to read json from ' + file;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = readJson;
|
||||
14
node_modules/bower/lib/util/relativeToBaseDir.js
generated
vendored
Normal file
14
node_modules/bower/lib/util/relativeToBaseDir.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
var path = require('path');
|
||||
var isPathAbsolute = require('./isPathAbsolute');
|
||||
|
||||
function relativeToBaseDir(baseDir) {
|
||||
return function(filePath) {
|
||||
if (isPathAbsolute(filePath)) {
|
||||
return path.resolve(filePath);
|
||||
} else {
|
||||
return path.resolve(baseDir, filePath);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = relativeToBaseDir;
|
||||
65
node_modules/bower/lib/util/removeIgnores.js
generated
vendored
Normal file
65
node_modules/bower/lib/util/removeIgnores.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
var path = require('path');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var fstreamIgnore = require('fstream-ignore');
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
|
||||
function removeIgnores(dir, meta) {
|
||||
var reader;
|
||||
var applyIgnores;
|
||||
var deferred = Q.defer();
|
||||
var ignored = [];
|
||||
var nonIgnored = ['bower.json'];
|
||||
|
||||
// Don't ignore main files
|
||||
nonIgnored = nonIgnored.concat(meta.main || []);
|
||||
|
||||
nonIgnored = nonIgnored.map(function(file) {
|
||||
return path.join(dir, file);
|
||||
});
|
||||
|
||||
reader = fstreamIgnore({
|
||||
path: dir,
|
||||
type: 'Directory'
|
||||
});
|
||||
|
||||
reader.addIgnoreRules(meta.ignore || []);
|
||||
|
||||
// Monkey patch applyIgnores such that we get hold of all ignored files
|
||||
applyIgnores = reader.applyIgnores;
|
||||
reader.applyIgnores = function(entry) {
|
||||
var ret = applyIgnores.apply(this, arguments);
|
||||
|
||||
if (!ret) {
|
||||
ignored.push(path.join(dir, entry));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
reader
|
||||
.on('child', function(entry) {
|
||||
nonIgnored.push(entry.path);
|
||||
})
|
||||
.on('error', deferred.reject)
|
||||
.on('end', function() {
|
||||
var promises;
|
||||
|
||||
// Ensure that we are not ignoring files that should not be ignored!
|
||||
ignored = mout.array.unique(ignored);
|
||||
ignored = ignored.filter(function(file) {
|
||||
return nonIgnored.indexOf(file) === -1;
|
||||
});
|
||||
|
||||
// Delete all the ignored files
|
||||
promises = ignored.map(function(file) {
|
||||
return Q.nfcall(rimraf, file);
|
||||
});
|
||||
|
||||
return Q.all(promises).then(deferred.resolve, deferred.reject);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
module.exports = removeIgnores;
|
||||
22
node_modules/bower/lib/util/resolve.js
generated
vendored
Normal file
22
node_modules/bower/lib/util/resolve.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
var requireg = require('requireg');
|
||||
var resolve = require('resolve');
|
||||
|
||||
function startsWith(string, searchString, position) {
|
||||
position = position || 0;
|
||||
return string.substr(position, searchString.length) === searchString;
|
||||
}
|
||||
|
||||
module.exports = function(id, options) {
|
||||
var resolvedPath;
|
||||
|
||||
var cwd = (options || {}).cwd || process.cwd();
|
||||
|
||||
try {
|
||||
resolvedPath = resolve.sync(id, { basedir: cwd });
|
||||
} catch (e) {
|
||||
// Fallback to global require
|
||||
resolvedPath = requireg.resolve(id);
|
||||
}
|
||||
|
||||
return resolvedPath;
|
||||
};
|
||||
46
node_modules/bower/lib/util/rimraf.js
generated
vendored
Normal file
46
node_modules/bower/lib/util/rimraf.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
var rimraf = require('rimraf');
|
||||
var chmodr = require('chmodr');
|
||||
var fs = require('./fs');
|
||||
|
||||
module.exports = function(dir, callback) {
|
||||
var checkAndRetry = function(e) {
|
||||
fs.lstat(dir, function(err, stats) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') return callback();
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
chmodr(dir, 0777, function(err) {
|
||||
if (err) return callback(e);
|
||||
rimraf(dir, callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
checkAndRetry();
|
||||
} else {
|
||||
rimraf(dir, checkAndRetry);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.sync = function(dir) {
|
||||
var checkAndRetry = function() {
|
||||
try {
|
||||
fs.lstatSync(dir);
|
||||
chmodr.sync(dir, 0777);
|
||||
return rimraf.sync(dir);
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') return;
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
return rimraf.sync(dir);
|
||||
} catch (e) {
|
||||
return checkAndRetry();
|
||||
} finally {
|
||||
return checkAndRetry();
|
||||
}
|
||||
};
|
||||
35
node_modules/bower/lib/util/rootCheck.js
generated
vendored
Normal file
35
node_modules/bower/lib/util/rootCheck.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
var isRoot = require('is-root');
|
||||
var createError = require('./createError');
|
||||
|
||||
var renderer;
|
||||
|
||||
function rootCheck(options, config) {
|
||||
var errorMsg;
|
||||
|
||||
// Allow running the command as root
|
||||
if (options.allowRoot || config.allowRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorMsg =
|
||||
'Since bower is a user command, there is no need to execute it with \
|
||||
superuser permissions.\nIf you\'re having permission errors when using bower without \
|
||||
sudo, please spend a few minutes learning more about how your system should work and \
|
||||
make any necessary repairs.\n\n\
|
||||
http://www.joyent.com/blog/installing-node-and-npm\n\
|
||||
https://gist.github.com/isaacs/579814\n\n\
|
||||
You can however run a command with sudo using "--allow-root" option';
|
||||
|
||||
if (isRoot()) {
|
||||
var cli = require('./cli');
|
||||
renderer = cli.getRenderer('', false, config);
|
||||
renderer.error(
|
||||
createError('Cannot be run with sudo', 'ESUDO', {
|
||||
details: errorMsg
|
||||
})
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = rootCheck;
|
||||
77
node_modules/bower/lib/util/semver.js
generated
vendored
Normal file
77
node_modules/bower/lib/util/semver.js
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
var semver = require('semver');
|
||||
var mout = require('mout');
|
||||
|
||||
function maxSatisfying(versions, range, strictMatch) {
|
||||
var version;
|
||||
var filteredVersions;
|
||||
|
||||
// Filter only valid versions, since semver.maxSatisfying() throws an error
|
||||
versions = versions.filter(function(version) {
|
||||
return semver.valid(version);
|
||||
});
|
||||
|
||||
// Exact version & range match
|
||||
if (semver.valid(range)) {
|
||||
version = mout.array.find(versions, function(version) {
|
||||
return version === range;
|
||||
});
|
||||
if (version) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
range = typeof range === 'string' ? range.trim() : range;
|
||||
|
||||
// When strict match is enabled give priority to non-pre-releases
|
||||
// We do this by filtering every pre-release version
|
||||
if (strictMatch) {
|
||||
filteredVersions = versions.map(function(version) {
|
||||
return !isPreRelease(version) ? version : null;
|
||||
});
|
||||
|
||||
version = semver.maxSatisfying(filteredVersions, range);
|
||||
if (version) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to regular semver max satisfies
|
||||
return semver.maxSatisfying(versions, range);
|
||||
}
|
||||
|
||||
function maxSatisfyingIndex(versions, range, strictMatch) {
|
||||
var version = maxSatisfying(versions, range, strictMatch);
|
||||
|
||||
if (!version) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return versions.indexOf(version);
|
||||
}
|
||||
|
||||
function clean(version) {
|
||||
var parsed = semver.parse(version);
|
||||
|
||||
if (!parsed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Keep builds!
|
||||
return (
|
||||
parsed.version +
|
||||
(parsed.build.length ? '+' + parsed.build.join('.') : '')
|
||||
);
|
||||
}
|
||||
|
||||
function isPreRelease(version) {
|
||||
var parsed = semver.parse(version);
|
||||
return parsed && parsed.prerelease && parsed.prerelease.length;
|
||||
}
|
||||
|
||||
// Export a semver like object but with our custom functions
|
||||
mout.object.mixIn(module.exports, semver, {
|
||||
maxSatisfying: maxSatisfying,
|
||||
maxSatisfyingIndex: maxSatisfyingIndex,
|
||||
clean: clean,
|
||||
valid: clean
|
||||
});
|
||||
44
node_modules/bower/lib/util/template.js
generated
vendored
Normal file
44
node_modules/bower/lib/util/template.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
var path = require('path');
|
||||
var fs = require('./fs');
|
||||
var Handlebars = require('handlebars');
|
||||
var mout = require('mout');
|
||||
var helpers = require('../templates/helpers');
|
||||
|
||||
var templatesDir = path.resolve(__dirname, '../templates');
|
||||
var cache = {};
|
||||
|
||||
// Register helpers
|
||||
mout.object.forOwn(helpers, function(register) {
|
||||
register(Handlebars);
|
||||
});
|
||||
|
||||
function render(name, data, escape) {
|
||||
var contents;
|
||||
|
||||
// Check if already compiled
|
||||
if (cache[name]) {
|
||||
return cache[name](data);
|
||||
}
|
||||
|
||||
// Otherwise, read the file, compile and cache
|
||||
contents = fs.readFileSync(path.join(templatesDir, name)).toString();
|
||||
cache[name] = Handlebars.compile(contents, {
|
||||
noEscape: !escape
|
||||
});
|
||||
|
||||
// Call the function again
|
||||
return render(name, data, escape);
|
||||
}
|
||||
|
||||
function exists(name) {
|
||||
if (cache[name]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return fs.existsSync(path.join(templatesDir, name));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
render: render,
|
||||
exists: exists
|
||||
};
|
||||
12
node_modules/bower/lib/util/userAgent.js
generated
vendored
Normal file
12
node_modules/bower/lib/util/userAgent.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
var version = require('../version');
|
||||
|
||||
module.exports =
|
||||
'node/' +
|
||||
process.version +
|
||||
' ' +
|
||||
process.platform +
|
||||
' ' +
|
||||
process.arch +
|
||||
' ' +
|
||||
';Bower ' +
|
||||
version;
|
||||
22
node_modules/bower/lib/util/validLink.js
generated
vendored
Normal file
22
node_modules/bower/lib/util/validLink.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
var Q = require('q');
|
||||
var fs = require('./fs');
|
||||
|
||||
function validLink(file) {
|
||||
// Ensures that a file is a symlink that points
|
||||
// to a valid file
|
||||
return Q.nfcall(fs.lstat, file)
|
||||
.then(function(lstat) {
|
||||
if (!lstat.isSymbolicLink()) {
|
||||
return [false];
|
||||
}
|
||||
|
||||
return Q.nfcall(fs.stat, file).then(function(stat) {
|
||||
return [stat];
|
||||
});
|
||||
})
|
||||
.fail(function(err) {
|
||||
return [false, err];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = validLink;
|
||||
Reference in New Issue
Block a user