Files

107 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

2016-08-19 00:28:38 +02:00
'use strict';
2017-09-10 01:31:04 +02:00
const _ = require('lodash');
const BbPromise = require('bluebird');
2018-04-25 12:25:59 +02:00
const childProcess = require('child_process');
2017-09-10 01:31:04 +02:00
2016-08-17 22:43:41 +02:00
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
/**
* Remove the specified module from the require cache.
* @param {string} moduleName
*/
2016-08-17 22:43:41 +02:00
function purgeCache(moduleName) {
return searchAndProcessCache(moduleName, function (mod) {
2016-08-17 22:43:41 +02:00
delete require.cache[mod.id];
})
.then(() => {
_.forEach(_.keys(module.constructor._pathCache), function(cacheKey) {
if (cacheKey.indexOf(moduleName)>0) {
delete module.constructor._pathCache[cacheKey];
}
});
return BbPromise.resolve();
2016-08-17 22:43:41 +02:00
});
}
function searchAndProcessCache(moduleName, processor) {
let mod_src = require.resolve(moduleName);
const visitedModules = [];
if (mod_src && ((mod_src = require.cache[mod_src]) !== undefined)) {
const modStack = [mod_src];
while (!_.isEmpty(modStack)) {
const mod = modStack.pop();
if (!_.includes(visitedModules, mod)) {
visitedModules.push(mod);
Array.prototype.push.apply(modStack, mod.children);
processor(mod);
}
}
2016-08-17 22:43:41 +02:00
}
return BbPromise.resolve();
2016-08-17 22:43:41 +02:00
}
2018-04-25 12:25:59 +02:00
class SpawnError extends Error {
constructor(message, stdout, stderr) {
super(message);
this.stdout = stdout;
this.stderr = stderr;
}
toString() {
return `${this.message}\n${this.stderr}`;
}
}
/**
* Executes a child process without limitations on stdout and stderr.
* On error (exit code is not 0), it rejects with a SpawnProcessError that contains the stdout and stderr streams,
* on success it returns the streams in an object.
* @param {string} command - Command
* @param {string[]} [args] - Arguments
* @param {Object} [options] - Options for child_process.spawn
*/
function spawnProcess(command, args, options) {
return new BbPromise((resolve, reject) => {
const child = childProcess.spawn(command, args, options);
let stdout = '';
let stderr = '';
// Configure stream encodings
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
// Listen to stream events
child.stdout.on('data', data => {
stdout += data;
});
child.stderr.on('data', data => {
stderr += data;
});
child.on('error', err => {
reject(err);
});
child.on('close', exitCode => {
if (exitCode !== 0) {
reject(new SpawnError(`${command} ${_.join(args, ' ')} failed with code ${exitCode}`, stdout, stderr));
} else {
resolve({ stdout, stderr });
}
});
});
}
2016-08-17 22:43:41 +02:00
module.exports = {
guid,
purgeCache,
searchAndProcessCache,
2018-04-25 12:25:59 +02:00
SpawnError,
spawnProcess,
2016-08-17 22:43:41 +02:00
};