UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

92 lines 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shell = shell; const child_process = require("child_process"); const chalk = require("chalk"); const api_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api"); const logging_1 = require("../../logging"); /** * OS helpers * * Shell function which both prints to stdout and collects the output into a * string. */ async function shell(command) { const commandLine = renderCommandLine(command); (0, logging_1.debug)(`Executing ${chalk.blue(commandLine)}`); const child = child_process.spawn(command[0], renderArguments(command.slice(1)), { // Need this for Windows where we want .cmd and .bat to be found as well. shell: true, stdio: ['ignore', 'pipe', 'inherit'], }); return new Promise((resolve, reject) => { const stdout = new Array(); // Both write to stdout and collect child.stdout.on('data', chunk => { process.stdout.write(chunk); stdout.push(chunk); }); child.once('error', reject); child.once('exit', code => { if (code === 0) { resolve(Buffer.from(stdout).toString('utf-8')); } else { reject(new api_1.ToolkitError(`${commandLine} exited with error code ${code}`)); } }); }); } function renderCommandLine(cmd) { return renderArguments(cmd).join(' '); } /** * Render the arguments to include escape characters for each platform. */ function renderArguments(cmd) { if (process.platform !== 'win32') { return doRender(cmd, hasAnyChars(' ', '\\', '!', '"', "'", '&', '$'), posixEscape); } else { return doRender(cmd, hasAnyChars(' ', '"', '&', '^', '%'), windowsEscape); } } /** * Render a UNIX command line */ function doRender(cmd, needsEscaping, doEscape) { return cmd.map(x => needsEscaping(x) ? doEscape(x) : x); } /** * Return a predicate that checks if a string has any of the indicated chars in it */ function hasAnyChars(...chars) { return (str) => { return chars.some(c => str.indexOf(c) !== -1); }; } /** * Escape a shell argument for POSIX shells * * Wrapping in single quotes and escaping single quotes inside will do it for us. */ function posixEscape(x) { // Turn ' -> '"'"' x = x.replace(/'/g, "'\"'\"'"); return `'${x}'`; } /** * Escape a shell argument for cmd.exe * * This is how to do it right, but I'm not following everything: * * https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ */ function windowsEscape(x) { // First surround by double quotes, ignore the part about backslashes x = `"${x}"`; // Now escape all special characters const shellMeta = new Set(['"', '&', '^', '%']); return x.split('').map(c => shellMeta.has(x) ? '^' + c : c).join(''); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJvcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLHNCQTRCQztBQXZDRCwrQ0FBK0M7QUFDL0MsK0JBQStCO0FBQy9CLDBFQUFnRjtBQUNoRiwyQ0FBc0M7QUFFdEM7Ozs7O0dBS0c7QUFDSSxLQUFLLFVBQVUsS0FBSyxDQUFDLE9BQWlCO0lBQzNDLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLElBQUEsZUFBSyxFQUFDLGFBQWEsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUMsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUMvRSx5RUFBeUU7UUFDekUsS0FBSyxFQUFFLElBQUk7UUFDWCxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQztLQUNyQyxDQUFDLENBQUM7SUFFSCxPQUFPLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzdDLE1BQU0sTUFBTSxHQUFHLElBQUksS0FBSyxFQUFPLENBQUM7UUFFaEMsbUNBQW1DO1FBQ25DLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRTtZQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO1FBRUgsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDeEIsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDakQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sQ0FBQyxJQUFJLGtCQUFZLENBQUMsR0FBRyxXQUFXLDJCQUEyQixJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDNUUsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxHQUFhO0lBQ3RDLE9BQU8sZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGVBQWUsQ0FBQyxHQUFhO0lBQ3BDLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUNqQyxPQUFPLFFBQVEsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDNUUsQ0FBQztBQUNILENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsUUFBUSxDQUFDLEdBQWEsRUFBRSxhQUFxQyxFQUFFLFFBQStCO0lBQ3JHLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFdBQVcsQ0FBQyxHQUFHLEtBQWU7SUFDckMsT0FBTyxDQUFDLEdBQVcsRUFBRSxFQUFFO1FBQ3JCLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsV0FBVyxDQUFDLENBQVM7SUFDNUIsa0JBQWtCO0lBQ2xCLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztJQUMvQixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUM7QUFDbEIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsYUFBYSxDQUFDLENBQVM7SUFDOUIscUVBQXFFO0lBQ3JFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2Isb0NBQW9DO0lBQ3BDLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxDQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjaGlsZF9wcm9jZXNzIGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0IHsgVG9vbGtpdEVycm9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vQGF3cy1jZGsvdG1wLXRvb2xraXQtaGVscGVycy9zcmMvYXBpJztcbmltcG9ydCB7IGRlYnVnIH0gZnJvbSAnLi4vLi4vbG9nZ2luZyc7XG5cbi8qKlxuICogT1MgaGVscGVyc1xuICpcbiAqIFNoZWxsIGZ1bmN0aW9uIHdoaWNoIGJvdGggcHJpbnRzIHRvIHN0ZG91dCBhbmQgY29sbGVjdHMgdGhlIG91dHB1dCBpbnRvIGFcbiAqIHN0cmluZy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgY29tbWFuZExpbmUgPSByZW5kZXJDb21tYW5kTGluZShjb21tYW5kKTtcbiAgZGVidWcoYEV4ZWN1dGluZyAke2NoYWxrLmJsdWUoY29tbWFuZExpbmUpfWApO1xuICBjb25zdCBjaGlsZCA9IGNoaWxkX3Byb2Nlc3Muc3Bhd24oY29tbWFuZFswXSwgcmVuZGVyQXJndW1lbnRzKGNvbW1hbmQuc2xpY2UoMSkpLCB7XG4gICAgLy8gTmVlZCB0aGlzIGZvciBXaW5kb3dzIHdoZXJlIHdlIHdhbnQgLmNtZCBhbmQgLmJhdCB0byBiZSBmb3VuZCBhcyB3ZWxsLlxuICAgIHNoZWxsOiB0cnVlLFxuICAgIHN0ZGlvOiBbJ2lnbm9yZScsICdwaXBlJywgJ2luaGVyaXQnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHN0ZG91dCA9IG5ldyBBcnJheTxhbnk+KCk7XG5cbiAgICAvLyBCb3RoIHdyaXRlIHRvIHN0ZG91dCBhbmQgY29sbGVjdFxuICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGNodW5rKTtcbiAgICAgIHN0ZG91dC5wdXNoKGNodW5rKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcblxuICAgIGNoaWxkLm9uY2UoJ2V4aXQnLCBjb2RlID0+IHtcbiAgICAgIGlmIChjb2RlID09PSAwKSB7XG4gICAgICAgIHJlc29sdmUoQnVmZmVyLmZyb20oc3Rkb3V0KS50b1N0cmluZygndXRmLTgnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWplY3QobmV3IFRvb2xraXRFcnJvcihgJHtjb21tYW5kTGluZX0gZXhpdGVkIHdpdGggZXJyb3IgY29kZSAke2NvZGV9YCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyQ29tbWFuZExpbmUoY21kOiBzdHJpbmdbXSkge1xuICByZXR1cm4gcmVuZGVyQXJndW1lbnRzKGNtZCkuam9pbignICcpO1xufVxuXG4vKipcbiAqIFJlbmRlciB0aGUgYXJndW1lbnRzIHRvIGluY2x1ZGUgZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGVhY2ggcGxhdGZvcm0uXG4gKi9cbmZ1bmN0aW9uIHJlbmRlckFyZ3VtZW50cyhjbWQ6IHN0cmluZ1tdKSB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtICE9PSAnd2luMzInKSB7XG4gICAgcmV0dXJuIGRvUmVuZGVyKGNtZCwgaGFzQW55Q2hhcnMoJyAnLCAnXFxcXCcsICchJywgJ1wiJywgXCInXCIsICcmJywgJyQnKSwgcG9zaXhFc2NhcGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBkb1JlbmRlcihjbWQsIGhhc0FueUNoYXJzKCcgJywgJ1wiJywgJyYnLCAnXicsICclJyksIHdpbmRvd3NFc2NhcGUpO1xuICB9XG59XG5cbi8qKlxuICogUmVuZGVyIGEgVU5JWCBjb21tYW5kIGxpbmVcbiAqL1xuZnVuY3Rpb24gZG9SZW5kZXIoY21kOiBzdHJpbmdbXSwgbmVlZHNFc2NhcGluZzogKHg6IHN0cmluZykgPT4gYm9vbGVhbiwgZG9Fc2NhcGU6ICh4OiBzdHJpbmcpID0+IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGNtZC5tYXAoeCA9PiBuZWVkc0VzY2FwaW5nKHgpID8gZG9Fc2NhcGUoeCkgOiB4KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBwcmVkaWNhdGUgdGhhdCBjaGVja3MgaWYgYSBzdHJpbmcgaGFzIGFueSBvZiB0aGUgaW5kaWNhdGVkIGNoYXJzIGluIGl0XG4gKi9cbmZ1bmN0aW9uIGhhc0FueUNoYXJzKC4uLmNoYXJzOiBzdHJpbmdbXSk6ICh4OiBzdHJpbmcpID0+IGJvb2xlYW4ge1xuICByZXR1cm4gKHN0cjogc3RyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNoYXJzLnNvbWUoYyA9PiBzdHIuaW5kZXhPZihjKSAhPT0gLTEpO1xuICB9O1xufVxuXG4vKipcbiAqIEVzY2FwZSBhIHNoZWxsIGFyZ3VtZW50IGZvciBQT1NJWCBzaGVsbHNcbiAqXG4gKiBXcmFwcGluZyBpbiBzaW5nbGUgcXVvdGVzIGFuZCBlc2NhcGluZyBzaW5nbGUgcXVvdGVzIGluc2lkZSB3aWxsIGRvIGl0IGZvciB1cy5cbiAqL1xuZnVuY3Rpb24gcG9zaXhFc2NhcGUoeDogc3RyaW5nKSB7XG4gIC8vIFR1cm4gJyAtPiAnXCInXCInXG4gIHggPSB4LnJlcGxhY2UoLycvZywgXCInXFxcIidcXFwiJ1wiKTtcbiAgcmV0dXJuIGAnJHt4fSdgO1xufVxuXG4vKipcbiAqIEVzY2FwZSBhIHNoZWxsIGFyZ3VtZW50IGZvciBjbWQuZXhlXG4gKlxuICogVGhpcyBpcyBob3cgdG8gZG8gaXQgcmlnaHQsIGJ1dCBJJ20gbm90IGZvbGxvd2luZyBldmVyeXRoaW5nOlxuICpcbiAqIGh0dHBzOi8vYmxvZ3MubXNkbi5taWNyb3NvZnQuY29tL3R3aXN0eWxpdHRsZXBhc3NhZ2VzYWxsYWxpa2UvMjAxMS8wNC8yMy9ldmVyeW9uZS1xdW90ZXMtY29tbWFuZC1saW5lLWFyZ3VtZW50cy10aGUtd3Jvbmctd2F5L1xuICovXG5mdW5jdGlvbiB3aW5kb3dzRXNjYXBlKHg6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIEZpcnN0IHN1cnJvdW5kIGJ5IGRvdWJsZSBxdW90ZXMsIGlnbm9yZSB0aGUgcGFydCBhYm91dCBiYWNrc2xhc2hlc1xuICB4ID0gYFwiJHt4fVwiYDtcbiAgLy8gTm93IGVzY2FwZSBhbGwgc3BlY2lhbCBjaGFyYWN0ZXJzXG4gIGNvbnN0IHNoZWxsTWV0YSA9IG5ldyBTZXQ8c3RyaW5nPihbJ1wiJywgJyYnLCAnXicsICclJ10pO1xuICByZXR1cm4geC5zcGxpdCgnJykubWFwKGMgPT4gc2hlbGxNZXRhLmhhcyh4KSA/ICdeJyArIGMgOiBjKS5qb2luKCcnKTtcbn1cbiJdfQ==