@aws-cdk/integ-runner
Version:
CDK Integration Testing Tool
143 lines • 14.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkList = void 0;
exports.exec = exec;
exports.execWithSubShell = execWithSubShell;
exports.renderCommand = renderCommand;
exports.flatten = flatten;
exports.chain = chain;
exports.chunks = chunks;
exports.promiseWithResolvers = promiseWithResolvers;
// Helper functions for CDK Exec
const child_process_1 = require("child_process");
/**
* Our own execute function which doesn't use shells and strings.
*/
function exec(commandLine, options = {}) {
const proc = (0, child_process_1.spawnSync)(commandLine[0], commandLine.slice(1), {
stdio: ['ignore', 'pipe', options.verbose ? 'inherit' : 'pipe'], // inherit STDERR in verbose mode
env: {
...process.env,
...options.env,
},
cwd: options.cwd,
});
if (proc.error) {
throw proc.error;
}
if (proc.status !== 0) {
if (process.stderr) { // will be 'null' in verbose mode
process.stderr.write(proc.stderr);
}
throw new Error(`Command exited with ${proc.status ? `status ${proc.status}` : `signal ${proc.signal}`}`);
}
const output = proc.stdout.toString('utf-8').trim();
return output;
}
/**
* Like exec, but any arrays encountered inside the command array are pull out and executed first, than their value is inserted again.
* This mimics execution a command with sub shell behavior.
*
* For example this input:
* ```
* ["git", "checkout", ["git", "merge-base", "HEAD"], "--," "path/to/file"]
* ```
* will run something like this:
* ```
* git checkout $(git merge-base HEAD) -- path/to/file
* ```
*
* Note that the algorithm will detect sub shells first, exec them and then
* substitute the return values in.
*/
function execWithSubShell(command, options = {}) {
const resolvedCommand = command.map((cmd) => {
if (Array.isArray(cmd)) {
return execWithSubShell(cmd, options);
}
return cmd;
});
return exec(resolvedCommand, options);
}
/**
* Takes the same input as `execWithSubShell` and returns a string with sub shells.
*/
function renderCommand(command) {
return command.map((cmd) => {
if (Array.isArray(cmd)) {
return `$(${renderCommand(cmd)})`;
}
return cmd;
}).join(' ');
}
/**
* Flatten a list of lists into a list of elements
*/
function flatten(xs) {
return Array.prototype.concat.apply([], xs);
}
/**
* Chain commands
*/
function chain(commands) {
return commands.filter(c => !!c).join(' && ');
}
/**
* Split command to chunks by space
*/
function chunks(command) {
const result = command.match(/(?:[^\s"]+|"[^"]*")+/g);
return result ?? [];
}
/**
* A class holding a set of items which are being crossed off in time
*
* If it takes too long to cross off a new item, print the list.
*/
class WorkList {
constructor(items, options = {}) {
this.items = items;
this.options = options;
this.remaining = new Set(this.items);
this.timeout = options.timeout ?? 60000;
this.scheduleTimer();
}
crossOff(item) {
this.remaining.delete(item);
this.stopTimer();
if (this.remaining.size > 0) {
this.scheduleTimer();
}
}
done() {
this.remaining.clear();
this.stopTimer();
}
stopTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
}
scheduleTimer() {
this.timer = setTimeout(() => this.report(), this.timeout);
}
report() {
this.options.onTimeout?.(this.remaining);
}
}
exports.WorkList = WorkList;
/**
* A backport of Promiser.withResolvers
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
*/
function promiseWithResolvers() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve: resolve, reject: reject };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQSxvQkF1QkM7QUFvQkQsNENBU0M7QUFLRCxzQ0FPQztBQUtELDBCQUVDO0FBS0Qsc0JBRUM7QUFLRCx3QkFHQztBQWlFRCxvREFPQztBQXBLRCxnQ0FBZ0M7QUFDaEMsaURBQTBDO0FBRTFDOztHQUVHO0FBQ0gsU0FBZ0IsSUFBSSxDQUFDLFdBQXFCLEVBQUUsVUFBMEQsRUFBRztJQUN2RyxNQUFNLElBQUksR0FBRyxJQUFBLHlCQUFTLEVBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDM0QsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLGlDQUFpQztRQUNsRyxHQUFHLEVBQUU7WUFDSCxHQUFHLE9BQU8sQ0FBQyxHQUFHO1lBQ2QsR0FBRyxPQUFPLENBQUMsR0FBRztTQUNmO1FBQ0QsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO0tBQ2pCLENBQUMsQ0FBQztJQUVILElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEIsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxpQ0FBaUM7WUFDckQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FB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SUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQztRQUN6QixDQUFDO0lBQ0gsQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRU8sTUFBTTtRQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7Q0FDRjtBQXJDRCw0QkFxQ0M7QUFnQkQ7Ozs7R0FJRztBQUNILFNBQWdCLG9CQUFvQjtJQUNsQyxJQUFJLE9BQTBDLEVBQUUsTUFBd0MsQ0FBQztJQUN6RixNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUMxQyxPQUFPLEdBQUcsR0FBRyxDQUFDO1FBQ2QsTUFBTSxHQUFHLEdBQUcsQ0FBQztJQUNmLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBUSxFQUFFLE1BQU0sRUFBRSxNQUFPLEVBQUUsQ0FBQztBQUN6RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgQ0RLIEV4ZWNcbmltcG9ydCB7IHNwYXduU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuXG4vKipcbiAqIE91ciBvd24gZXhlY3V0ZSBmdW5jdGlvbiB3aGljaCBkb2Vzbid0IHVzZSBzaGVsbHMgYW5kIHN0cmluZ3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleGVjKGNvbW1hbmRMaW5lOiBzdHJpbmdbXSwgb3B0aW9uczogeyBjd2Q/OiBzdHJpbmc7IHZlcmJvc2U/OiBib29sZWFuOyBlbnY/OiBhbnkgfSA9IHsgfSk6IGFueSB7XG4gIGNvbnN0IHByb2MgPSBzcGF3blN5bmMoY29tbWFuZExpbmVbMF0sIGNvbW1hbmRMaW5lLnNsaWNlKDEpLCB7XG4gICAgc3RkaW86IFsnaWdub3JlJywgJ3BpcGUnLCBvcHRpb25zLnZlcmJvc2UgPyAnaW5oZXJpdCcgOiAncGlwZSddLCAvLyBpbmhlcml0IFNUREVSUiBpbiB2ZXJib3NlIG1vZGVcbiAgICBlbnY6IHtcbiAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgLi4ub3B0aW9ucy5lbnYsXG4gICAgfSxcbiAgICBjd2Q6IG9wdGlvbnMuY3dkLFxuICB9KTtcblxuICBpZiAocHJvYy5lcnJvcikge1xuICAgIHRocm93IHByb2MuZXJyb3I7XG4gIH1cbiAgaWYgKHByb2Muc3RhdHVzICE9PSAwKSB7XG4gICAgaWYgKHByb2Nlc3Muc3RkZXJyKSB7IC8vIHdpbGwgYmUgJ251bGwnIGluIHZlcmJvc2UgbW9kZVxuICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUocHJvYy5zdGRlcnIpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvbW1hbmQgZXhpdGVkIHdpdGggJHtwcm9jLnN0YXR1cyA/IGBzdGF0dXMgJHtwcm9jLnN0YXR1c31gIDogYHNpZ25hbCAke3Byb2Muc2lnbmFsfWB9YCk7XG4gIH1cblxuICBjb25zdCBvdXRwdXQgPSBwcm9jLnN0ZG91dC50b1N0cmluZygndXRmLTgnKS50cmltKCk7XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxudHlwZSBDb21tYW5kID0gQXJyYXk8c3RyaW5nIHwgQ29tbWFuZD47XG5cbi8qKlxuICogTGlrZSBleGVjLCBidXQgYW55IGFycmF5cyBlbmNvdW50ZXJlZCBpbnNpZGUgdGhlIGNvbW1hbmQgYXJyYXkgYXJlIHB1bGwgb3V0IGFuZCBleGVjdXRlZCBmaXJzdCwgdGhhbiB0aGVpciB2YWx1ZSBpcyBpbnNlcnRlZCBhZ2Fpbi5cbiAqIFRoaXMgbWltaWNzIGV4ZWN1dGlvbiBhIGNvbW1hbmQgd2l0aCBzdWIgc2hlbGwgYmVoYXZpb3IuXG4gKlxuICogRm9yIGV4YW1wbGUgdGhpcyBpbnB1dDpcbiAqIGBgYFxuICogW1wiZ2l0XCIsIFwiY2hlY2tvdXRcIiwgW1wiZ2l0XCIsIFwibWVyZ2UtYmFzZVwiLCBcIkhFQURcIl0sIFwiLS0sXCIgXCJwYXRoL3RvL2ZpbGVcIl1cbiAqIGBgYFxuICogd2lsbCBydW4gc29tZXRoaW5nIGxpa2UgdGhpczpcbiAqIGBgYFxuICogZ2l0IGNoZWNrb3V0ICQoZ2l0IG1lcmdlLWJhc2UgSEVBRCkgLS0gcGF0aC90by9maWxlXG4gKiBgYGBcbiAqXG4gKiBOb3RlIHRoYXQgdGhlIGFsZ29yaXRobSB3aWxsIGRldGVjdCBzdWIgc2hlbGxzIGZpcnN0LCBleGVjIHRoZW0gYW5kIHRoZW5cbiAqIHN1YnN0aXR1dGUgdGhlIHJldHVybiB2YWx1ZXMgaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleGVjV2l0aFN1YlNoZWxsKGNvbW1hbmQ6IENvbW1hbmQsIG9wdGlvbnM6IHsgY3dkPzogc3RyaW5nOyB2ZXJib3NlPzogYm9vbGVhbjsgZW52PzogYW55IH0gPSB7IH0pOiBhbnkge1xuICBjb25zdCByZXNvbHZlZENvbW1hbmQ6IHN0cmluZ1tdID0gY29tbWFuZC5tYXAoKGNtZCkgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNtZCkpIHtcbiAgICAgIHJldHVybiBleGVjV2l0aFN1YlNoZWxsKGNtZCwgb3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiBjbWQ7XG4gIH0pO1xuXG4gIHJldHVybiBleGVjKHJlc29sdmVkQ29tbWFuZCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogVGFrZXMgdGhlIHNhbWUgaW5wdXQgYXMgYGV4ZWNXaXRoU3ViU2hlbGxgIGFuZCByZXR1cm5zIGEgc3RyaW5nIHdpdGggc3ViIHNoZWxscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckNvbW1hbmQoY29tbWFuZDogQ29tbWFuZCk6IHN0cmluZyB7XG4gIHJldHVybiBjb21tYW5kLm1hcCgoY21kKSA9PiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY21kKSkge1xuICAgICAgcmV0dXJuIGAkKCR7cmVuZGVyQ29tbWFuZChjbWQpfSlgO1xuICAgIH1cbiAgICByZXR1cm4gY21kO1xuICB9KS5qb2luKCcgJyk7XG59XG5cbi8qKlxuICogRmxhdHRlbiBhIGxpc3Qgb2YgbGlzdHMgaW50byBhIGxpc3Qgb2YgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW48VD4oeHM6IFRbXVtdKTogVFtdIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sIHhzKTtcbn1cblxuLyoqXG4gKiBDaGFpbiBjb21tYW5kc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhaW4oY29tbWFuZHM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGNvbW1hbmRzLmZpbHRlcihjID0+ICEhYykuam9pbignICYmICcpO1xufVxuXG4vKipcbiAqIFNwbGl0IGNvbW1hbmQgdG8gY2h1bmtzIGJ5IHNwYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaHVua3MoY29tbWFuZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCByZXN1bHQgPSBjb21tYW5kLm1hdGNoKC8oPzpbXlxcc1wiXSt8XCJbXlwiXSpcIikrL2cpO1xuICByZXR1cm4gcmVzdWx0ID8/IFtdO1xufVxuXG4vKipcbiAqIEEgY2xhc3MgaG9sZGluZyBhIHNldCBvZiBpdGVtcyB3aGljaCBhcmUgYmVpbmcgY3Jvc3NlZCBvZmYgaW4gdGltZVxuICpcbiAqIElmIGl0IHRha2VzIHRvbyBsb25nIHRvIGNyb3NzIG9mZiBhIG5ldyBpdGVtLCBwcmludCB0aGUgbGlzdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtMaXN0PEE+IHtcbiAgcHJpdmF0ZSByZWFkb25seSByZW1haW5pbmcgPSBuZXcgU2V0KHRoaXMuaXRlbXMpO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpbWVvdXQ6IG51bWJlcjtcbiAgcHJpdmF0ZSB0aW1lcj86IE5vZGVKUy5UaW1lb3V0O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgaXRlbXM6IEFbXSwgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBXb3JrTGlzdE9wdGlvbnM8QT4gPSB7fSkge1xuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dCA/PyA2MF8wMDA7XG4gICAgdGhpcy5zY2hlZHVsZVRpbWVyKCk7XG4gIH1cblxuICBwdWJsaWMgY3Jvc3NPZmYoaXRlbTogQSkge1xuICAgIHRoaXMucmVtYWluaW5nLmRlbGV0ZShpdGVtKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICAgIGlmICh0aGlzLnJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgdGhpcy5zY2hlZHVsZVRpbWVyKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRvbmUoKSB7XG4gICAgdGhpcy5yZW1haW5pbmcuY2xlYXIoKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wVGltZXIoKSB7XG4gICAgaWYgKHRoaXMudGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAgIHRoaXMudGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzY2hlZHVsZVRpbWVyKCkge1xuICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVwb3J0KCksIHRoaXMudGltZW91dCk7XG4gIH1cblxuICBwcml2YXRlIHJlcG9ydCgpIHtcbiAgICB0aGlzLm9wdGlvbnMub25UaW1lb3V0Py4odGhpcy5yZW1haW5pbmcpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV29ya0xpc3RPcHRpb25zPEE+IHtcbiAgLyoqXG4gICAqIFdoZW4gdG8gcmVwbHkgd2l0aCByZW1haW5pbmcgaXRlbXNcbiAgICpcbiAgICogQGRlZmF1bHQgNjAwMDBcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aW1lb3V0IGhpdHNcbiAgICovXG4gIHJlYWRvbmx5IG9uVGltZW91dD86ICh4OiBTZXQ8QT4pID0+IHZvaWQ7XG59XG5cbi8qKlxuICogQSBiYWNrcG9ydCBvZiBQcm9taXNlci53aXRoUmVzb2x2ZXJzXG4gKlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9Qcm9taXNlL3dpdGhSZXNvbHZlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VXaXRoUmVzb2x2ZXJzPEE+KCk6IFByb21pc2VBbmRSZXNvbHZlcnM8QT4ge1xuICBsZXQgcmVzb2x2ZTogUHJvbWlzZUFuZFJlc29sdmVyczxBPlsncmVzb2x2ZSddLCByZWplY3Q6IFByb21pc2VBbmRSZXNvbHZlcnM8QT5bJ3JlamVjdCddO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8QT4oKHJlcywgcmVqKSA9PiB7XG4gICAgcmVzb2x2ZSA9IHJlcztcbiAgICByZWplY3QgPSByZWo7XG4gIH0pO1xuICByZXR1cm4geyBwcm9taXNlLCByZXNvbHZlOiByZXNvbHZlISwgcmVqZWN0OiByZWplY3QhIH07XG59XG5cbmludGVyZmFjZSBQcm9taXNlQW5kUmVzb2x2ZXJzPEE+IHtcbiAgcHJvbWlzZTogUHJvbWlzZTxBPjtcbiAgcmVzb2x2ZTogKHZhbHVlOiBBKSA9PiB2b2lkO1xuICByZWplY3Q6IChyZWFzb246IGFueSkgPT4gdm9pZDtcbn1cbiJdfQ==