projen
Version:
CDK for software projects
108 lines • 15.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.synthSnapshot = synthSnapshot;
exports.directorySnapshot = directorySnapshot;
const fs = require("fs");
const os = require("os");
const path = require("path");
const JSONC = require("comment-json");
const comment_json_1 = require("comment-json");
const glob_1 = require("glob");
const json_1 = require("../json");
/**
* Creates a snapshot of the files generated by a project. Ignores any non-text
* files so that the snapshots are human readable.
*/
function synthSnapshot(project, options = {}) {
// defensive: verify that "outdir" is actually in a temporary directory
if (!path.resolve(project.outdir).startsWith(os.tmpdir()) &&
!project.outdir.includes("project-temp-dir")) {
throw new Error("Trying to capture a snapshot of a project outside of tmpdir, which implies this test might corrupt an existing project");
}
const synthed = Symbol.for("synthed");
if (synthed in project) {
throw new Error("duplicate synth()");
}
project[synthed] = true;
const ENV_PROJEN_DISABLE_POST = process.env.PROJEN_DISABLE_POST;
try {
process.env.PROJEN_DISABLE_POST = "true";
project.synth();
const ignoreExts = ["png", "ico"];
return directorySnapshot(project.outdir, {
...options,
excludeGlobs: ignoreExts.map((ext) => `**/*.${ext}`),
supportJsonComments: project.files.some(
// At least one json file in project supports comments
(file) => file instanceof json_1.JsonFile && file.supportsComments),
});
}
finally {
fs.rmSync(project.outdir, { force: true, recursive: true });
// values assigned to process.env.XYZ are automatically converted to strings
if (ENV_PROJEN_DISABLE_POST === undefined) {
delete process.env.PROJEN_DISABLE_POST;
}
else {
process.env.PROJEN_DISABLE_POST = ENV_PROJEN_DISABLE_POST;
}
}
}
function isJsonLikeFile(filePath) {
const file = filePath.toLowerCase();
return (file.endsWith(".json") || file.endsWith(".json5") || file.endsWith(".jsonc"));
}
function directorySnapshot(root, options = {}) {
const output = {};
const files = glob_1.glob.sync("**", {
ignore: [".git/**", ...(options.excludeGlobs ?? [])],
cwd: root,
nodir: true,
dot: true,
}); // returns relative file paths with POSIX separators
const parseJson = options.parseJson ?? true;
for (const file of files) {
const filePath = path.join(root, file);
let content;
if (!options.onlyFileNames) {
content = fs.readFileSync(filePath, "utf-8");
if (parseJson && isJsonLikeFile(filePath)) {
content = cleanCommentArrays(JSONC.parse(content, undefined, !options.supportJsonComments));
}
}
else {
content = true;
}
output[file] = content;
}
return output;
}
/**
* Converts type "CommentArray" back to regular JS "Array"
* if there are no comments stored in it.
* Prevents strict checks from failing.
*/
function cleanCommentArrays(obj) {
if (Array.isArray(obj) || isCommentArrayWithoutComments(obj)) {
return Array.from(obj).map(cleanCommentArrays);
}
if (obj instanceof Object) {
for (const p of Object.keys(obj)) {
if (isCommentArrayWithoutComments(obj[p])) {
obj[p] = Array.from(obj[p]).map(cleanCommentArrays);
}
else if (obj[p] instanceof Object) {
obj[p] = cleanCommentArrays(obj[p]);
}
}
}
return obj;
}
/**
* Checks if a "CommentArray" has no comments stored in it.
*/
function isCommentArrayWithoutComments(obj) {
return (obj instanceof comment_json_1.CommentArray &&
Object.getOwnPropertySymbols(obj).length === 0);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC9zeW50aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQThCQSxzQ0E0Q0M7QUFnQ0QsOENBa0NDO0FBNUlELHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHNDQUFzQztBQUN0QywrQ0FBNEM7QUFDNUMsK0JBQTRCO0FBQzVCLGtDQUFtQztBQW9CbkM7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUMzQixPQUFnQixFQUNoQixVQUEyQixFQUFFO0lBRTdCLHVFQUF1RTtJQUN2RSxJQUNFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyRCxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQzVDLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLHdIQUF3SCxDQUN6SCxDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEMsSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFQSxPQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBRWpDLE1BQU0sdUJBQXVCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztJQUNoRSxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQztRQUN6QyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFD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QUM7UUFDN0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxJQUFJLEdBQUcsWUFBWSxNQUFNLEVBQUUsQ0FBQztRQUMxQixLQUFLLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxJQUFJLDZCQUE2QixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3RELENBQUM7aUJBQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLFlBQVksTUFBTSxFQUFFLENBQUM7Z0JBQ3BDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsNkJBQTZCLENBQUMsR0FBUTtJQUM3QyxPQUFPLENBQ0wsR0FBRyxZQUFZLDJCQUFZO1FBQzNCLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUMvQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0ICogYXMgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgKiBhcyBKU09OQyBmcm9tIFwiY29tbWVudC1qc29uXCI7XG5pbXBvcnQgeyBDb21tZW50QXJyYXkgfSBmcm9tIFwiY29tbWVudC1qc29uXCI7XG5pbXBvcnQgeyBnbG9iIH0gZnJvbSBcImdsb2JcIjtcbmltcG9ydCB7IEpzb25GaWxlIH0gZnJvbSBcIi4uL2pzb25cIjtcbmltcG9ydCB7IFByb2plY3QgfSBmcm9tIFwiLi4vcHJvamVjdFwiO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBTbmFwc2hvdCBzeW50aGVzaXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbmFwc2hvdE9wdGlvbnMge1xuICAvKipcbiAgICogUGFyc2UgLmpzb24gZmlsZXMgYXMgYSBKUyBvYmplY3QgZm9yIGltcHJvdmVkIGluc3BlY3Rpb24uXG4gICAqIFRoaXMgd2lsbCBmYWlsIGlmIHRoZSBjb250ZW50cyBhcmUgaW52YWxpZCBKU09OLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlIHBhcnNlIC5qc29uIGZpbGVzIGludG8gYW4gb2JqZWN0XG4gICAqL1xuICByZWFkb25seSBwYXJzZUpzb24/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN5bnRoT3V0cHV0IHtcbiAgW2ZpbGVQYXRoOiBzdHJpbmddOiBhbnk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNuYXBzaG90IG9mIHRoZSBmaWxlcyBnZW5lcmF0ZWQgYnkgYSBwcm9qZWN0LiBJZ25vcmVzIGFueSBub24tdGV4dFxuICogZmlsZXMgc28gdGhhdCB0aGUgc25hcHNob3RzIGFyZSBodW1hbiByZWFkYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN5bnRoU25hcHNob3QoXG4gIHByb2plY3Q6IFByb2plY3QsXG4gIG9wdGlvbnM6IFNuYXBzaG90T3B0aW9ucyA9IHt9XG4pOiBTeW50aE91dHB1dCB7XG4gIC8vIGRlZmVuc2l2ZTogdmVyaWZ5IHRoYXQgXCJvdXRkaXJcIiBpcyBhY3R1YWxseSBpbiBhIHRlbXBvcmFyeSBkaXJlY3RvcnlcbiAgaWYgKFxuICAgICFwYXRoLnJlc29sdmUocHJvamVjdC5vdXRkaXIpLnN0YXJ0c1dpdGgob3MudG1wZGlyKCkpICYmXG4gICAgIXByb2plY3Qub3V0ZGlyLmluY2x1ZGVzKFwicHJvamVjdC10ZW1wLWRpclwiKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcIlRyeWluZyB0byBjYXB0dXJlIGEgc25hcHNob3Qgb2YgYSBwcm9qZWN0IG91dHNpZGUgb2YgdG1wZGlyLCB3aGljaCBpbXBsaWVzIHRoaXMgdGVzdCBtaWdodCBjb3JydXB0IGFuIGV4aXN0aW5nIHByb2plY3RcIlxuICAgICk7XG4gIH1cblxuICBjb25zdCBzeW50aGVkID0gU3ltYm9sLmZvcihcInN5bnRoZWRcIik7XG4gIGlmIChzeW50aGVkIGluIHByb2plY3QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJkdXBsaWNhdGUgc3ludGgoKVwiKTtcbiAgfVxuXG4gIChwcm9qZWN0IGFzIGFueSlbc3ludGhlZF0gPSB0cnVlO1xuXG4gIGNvbnN0IEVOVl9QUk9KRU5fRElTQUJMRV9QT1NUID0gcHJvY2Vzcy5lbnYuUFJPSkVOX0RJU0FCTEVfUE9TVDtcbiAgdHJ5IHtcbiAgICBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUID0gXCJ0cnVlXCI7XG4gICAgcHJvamVjdC5zeW50aCgpO1xuICAgIGNvbnN0IGlnbm9yZUV4dHMgPSBbXCJwbmdcIiwgXCJpY29cIl07XG4gICAgcmV0dXJuIGRpcmVjdG9yeVNuYXBzaG90KHByb2plY3Qub3V0ZGlyLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgZXhjbHVkZUdsb2JzOiBpZ25vcmVFeHRzLm1hcCgoZXh0KSA9PiBgKiovKi4ke2V4dH1gKSxcbiAgICAgIHN1cHBvcnRKc29uQ29tbWVudHM6IHByb2plY3QuZmlsZXMuc29tZShcbiAgICAgICAgLy8gQXQgbGVhc3Qgb25lIGpzb24gZmlsZSBpbiBwcm9qZWN0IHN1cHBvcnRzIGNvbW1lbnRzXG4gICAgICAgIChmaWxlKSA9PiBmaWxlIGluc3RhbmNlb2YgSnNvbkZpbGUgJiYgZmlsZS5zdXBwb3J0c0NvbW1lbnRzXG4gICAgICApLFxuICAgIH0pO1xuICB9IGZpbmFsbHkge1xuICAgIGZzLnJtU3luYyhwcm9qZWN0Lm91dGRpciwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gICAgLy8gdmFsdWVzIGFzc2lnbmVkIHRvIHByb2Nlc3MuZW52LlhZWiBhcmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gc3RyaW5nc1xuICAgIGlmIChFTlZfUFJPSkVOX0RJU0FCTEVfUE9TVCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZWxldGUgcHJvY2Vzcy5lbnYuUFJPSkVOX0RJU0FCTEVfUE9TVDtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzcy5lbnYuUFJPSkVOX0RJU0FCTEVfUE9TVCA9IEVOVl9QUk9KRU5fRElTQUJMRV9QT1NUO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERpcmVjdG9yeVNuYXBzaG90T3B0aW9ucyBleHRlbmRzIFNuYXBzaG90T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBHbG9icyBvZiBmaWxlcyB0byBleGNsdWRlLlxuICAgKiBAZGVmYXVsdCBbXSBpbmNsdWRlIGFsbCBmaWxlc1xuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZUdsb2JzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE9ubHkgc25hcHNob3QgdGhlIG5hbWVzIG9mIGZpbGVzIGFuZCBub3QgdGhlaXIgY29udGVudHMuXG4gICAqIFRoZSB2YWx1ZSBmb3IgYSBwYXRoIHdpbGwgYmUgYHRydWVgIGlmIGl0IGV4aXN0cy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2UgaW5jbHVkZSBmaWxlIGNvbnRlbnRcbiAgICovXG4gIHJlYWRvbmx5IG9ubHlGaWxlTmFtZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXJzZXMgZmlsZXMgd2l0aCBkaWZmZXJlbnQgcGFyc2VyLCBzdXBwb3J0aW5nIGNvbW1lbnRzXG4gICAqIGluc2lkZSAuanNvbiBmaWxlcy5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHN1cHBvcnRKc29uQ29tbWVudHM/OiBib29sZWFuO1xufVxuXG5mdW5jdGlvbiBpc0pzb25MaWtlRmlsZShmaWxlUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGZpbGUgPSBmaWxlUGF0aC50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKFxuICAgIGZpbGUuZW5kc1dpdGgoXCIuanNvblwiKSB8fCBmaWxlLmVuZHNXaXRoKFwiLmpzb241XCIpIHx8IGZpbGUuZW5kc1dpdGgoXCIuanNvbmNcIilcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpcmVjdG9yeVNuYXBzaG90KFxuICByb290OiBzdHJpbmcsXG4gIG9wdGlvbnM6IERpcmVjdG9yeVNuYXBzaG90T3B0aW9ucyA9IHt9XG4pIHtcbiAgY29uc3Qgb3V0cHV0OiBTeW50aE91dHB1dCA9IHt9O1xuXG4gIGNvbnN0IGZpbGVzID0gZ2xvYi5zeW5jKFwiKipcIiwge1xuICAgIGlnbm9yZTogW1wiLmdpdC8qKlwiLCAuLi4ob3B0aW9ucy5leGNsdWRlR2xvYnMgPz8gW10pXSxcbiAgICBjd2Q6IHJvb3QsXG4gICAgbm9kaXI6IHRydWUsXG4gICAgZG90OiB0cnVlLFxuICB9KTsgLy8gcmV0dXJucyByZWxhdGl2ZSBmaWxlIHBhdGhzIHdpdGggUE9TSVggc2VwYXJhdG9yc1xuXG4gIGNvbnN0IHBhcnNlSnNvbiA9IG9wdGlvbnMucGFyc2VKc29uID8/IHRydWU7XG5cbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4ocm9vdCwgZmlsZSk7XG5cbiAgICBsZXQgY29udGVudDtcbiAgICBpZiAoIW9wdGlvbnMub25seUZpbGVOYW1lcykge1xuICAgICAgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICAgIGlmIChwYXJzZUpzb24gJiYgaXNKc29uTGlrZUZpbGUoZmlsZVBhdGgpKSB7XG4gICAgICAgIGNvbnRlbnQgPSBjbGVhbkNvbW1lbnRBcnJheXMoXG4gICAgICAgICAgSlNPTkMucGFyc2UoY29udGVudCwgdW5kZWZpbmVkLCAhb3B0aW9ucy5zdXBwb3J0SnNvbkNvbW1lbnRzKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBvdXRwdXRbZmlsZV0gPSBjb250ZW50O1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0eXBlIFwiQ29tbWVudEFycmF5XCIgYmFjayB0byByZWd1bGFyIEpTIFwiQXJyYXlcIlxuICogaWYgdGhlcmUgYXJlIG5vIGNvbW1lbnRzIHN0b3JlZCBpbiBpdC5cbiAqIFByZXZlbnRzIHN0cmljdCBjaGVja3MgZnJvbSBmYWlsaW5nLlxuICovXG5mdW5jdGlvbiBjbGVhbkNvbW1lbnRBcnJheXMob2JqOiBhbnkpOiB0eXBlb2Ygb2JqIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSB8fCBpc0NvbW1lbnRBcnJheVdpdGhvdXRDb21tZW50cyhvYmopKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20ob2JqKS5tYXAoY2xlYW5Db21tZW50QXJyYXlzKTtcbiAgfVxuXG4gIGlmIChvYmogaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICBmb3IgKGNvbnN0IHAgb2YgT2JqZWN0LmtleXMob2JqKSkge1xuICAgICAgaWYgKGlzQ29tbWVudEFycmF5V2l0aG91dENvbW1lbnRzKG9ialtwXSkpIHtcbiAgICAgICAgb2JqW3BdID0gQXJyYXkuZnJvbShvYmpbcF0pLm1hcChjbGVhbkNvbW1lbnRBcnJheXMpO1xuICAgICAgfSBlbHNlIGlmIChvYmpbcF0gaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgb2JqW3BdID0gY2xlYW5Db21tZW50QXJyYXlzKG9ialtwXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBcIkNvbW1lbnRBcnJheVwiIGhhcyBubyBjb21tZW50cyBzdG9yZWQgaW4gaXQuXG4gKi9cbmZ1bmN0aW9uIGlzQ29tbWVudEFycmF5V2l0aG91dENvbW1lbnRzKG9iajogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgb2JqIGluc3RhbmNlb2YgQ29tbWVudEFycmF5ICYmXG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopLmxlbmd0aCA9PT0gMFxuICApO1xufVxuIl19