jsii-diff
Version:
Assembly comparison for jsii
117 lines • 3.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RecursionBreaker = void 0;
exports.inTempDir = inTempDir;
exports.showDownloadFailure = showDownloadFailure;
exports.downloadNpmPackage = downloadNpmPackage;
exports.flatMap = flatMap;
const childProcess = require("child_process");
const fs = require("fs-extra");
const log4js = require("log4js");
const os = require("os");
const path = require("path");
const util = require("util");
const LOG = log4js.getLogger('jsii-diff');
const exec = util.promisify(childProcess.exec);
async function inTempDir(block) {
const origDir = process.cwd();
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'jsii'));
process.chdir(tmpDir);
try {
return await block();
}
finally {
process.chdir(origDir);
await fs.remove(tmpDir);
}
}
function showDownloadFailure(f) {
switch (f) {
case 'no_such_package':
return 'NPM package does not exist';
default:
return undefined;
}
}
async function downloadNpmPackage(pkg, block) {
return inTempDir(async () => {
LOG.info(`Fetching NPM package ${pkg}`);
try {
// Need to install package and dependencies in order for jsii-reflect
// to not bork when it can find the dependencies.
await exec(`npm install --silent --prefix . ${pkg}`);
}
catch (e) {
// If this fails, might be because the package doesn't exist
if (!isSubprocesFailedError(e)) {
throw e;
}
if (await npmPackageExists(pkg)) {
throw new Error(`NPM fetch failed: ${e}. Please try again.`);
}
LOG.warn(`NPM package ${pkg} does not exist.`);
return {
success: false,
reason: 'no_such_package',
};
}
const pkgDir = trimVersionString(pkg);
return {
success: true,
result: await block(path.join(process.cwd(), 'node_modules', pkgDir)),
};
});
}
function isSubprocesFailedError(e) {
return e.code !== undefined && e.cmd !== undefined;
}
async function npmPackageExists(pkg) {
try {
LOG.info(`Checking existence of ${pkg}`);
await exec(`npm show --silent ${pkg}`);
return true;
}
catch (e) {
if (!isSubprocesFailedError(e)) {
throw e;
}
return false;
}
}
/**
* Trim an optional version string from an NPM package name
*/
function trimVersionString(pkg) {
// The arbitrary char before the @ prevents matching a @ at the start of the
// string.
return pkg.replace(/(.)@.*$/, '$1');
}
function flatMap(xs, fn) {
const ret = new Array();
for (const x of xs) {
ret.push(...fn(x));
}
return ret;
}
/**
* Don't recurse infinitely by guarding a block with `do()`.
*/
class RecursionBreaker {
constructor() {
this.elements = new Set();
}
do(key, block) {
if (this.elements.has(key)) {
return;
}
this.elements.add(key);
try {
block();
}
finally {
this.elements.delete(key);
}
}
}
exports.RecursionBreaker = RecursionBreaker;
//# sourceMappingURL=util.js.map