UNPKG

projen

Version:

CDK for software projects

109 lines • 15.2 kB
"use strict"; 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 = require("fast-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.sync("**", { ignore: [".git/**", ...(options.excludeGlobs ?? [])], cwd: root, onlyFiles: true, followSymbolicLinks: false, 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC9zeW50aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQThCQSxzQ0E0Q0M7QUFnQ0QsOENBbUNDO0FBN0lELHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHNDQUFzQztBQUN0QywrQ0FBNEM7QUFDNUMsa0NBQWtDO0FBQ2xDLGtDQUFtQztBQW9CbkM7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUMzQixPQUFnQixFQUNoQixVQUEyQixFQUFFO0lBRTdCLHVFQUF1RTtJQUN2RSxJQUNFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyRCxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQzVDLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLHdIQUF3SCxDQUN6SCxDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEMsSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFQSxPQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBRWpDLE1BQU0sdUJBQXVCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztJQUNoRSxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQztRQUN6QyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFD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LENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM3RCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELElBQUksR0FBRyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQzFCLEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2pDLElBQUksNkJBQTZCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDdEQsQ0FBQztpQkFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsWUFBWSxNQUFNLEVBQUUsQ0FBQztnQkFDcEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyw2QkFBNkIsQ0FBQyxHQUFRO0lBQzdDLE9BQU8sQ0FDTCxHQUFHLFlBQVksMkJBQVk7UUFDM0IsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQy9DLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgKiBhcyBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCAqIGFzIEpTT05DIGZyb20gXCJjb21tZW50LWpzb25cIjtcbmltcG9ydCB7IENvbW1lbnRBcnJheSB9IGZyb20gXCJjb21tZW50LWpzb25cIjtcbmltcG9ydCAqIGFzIGdsb2IgZnJvbSBcImZhc3QtZ2xvYlwiO1xuaW1wb3J0IHsgSnNvbkZpbGUgfSBmcm9tIFwiLi4vanNvblwiO1xuaW1wb3J0IHsgUHJvamVjdCB9IGZyb20gXCIuLi9wcm9qZWN0XCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIFNuYXBzaG90IHN5bnRoZXNpc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNuYXBzaG90T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBQYXJzZSAuanNvbiBmaWxlcyBhcyBhIEpTIG9iamVjdCBmb3IgaW1wcm92ZWQgaW5zcGVjdGlvbi5cbiAgICogVGhpcyB3aWxsIGZhaWwgaWYgdGhlIGNvbnRlbnRzIGFyZSBpbnZhbGlkIEpTT04uXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWUgcGFyc2UgLmpzb24gZmlsZXMgaW50byBhbiBvYmplY3RcbiAgICovXG4gIHJlYWRvbmx5IHBhcnNlSnNvbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3ludGhPdXRwdXQge1xuICBbZmlsZVBhdGg6IHN0cmluZ106IGFueTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc25hcHNob3Qgb2YgdGhlIGZpbGVzIGdlbmVyYXRlZCBieSBhIHByb2plY3QuIElnbm9yZXMgYW55IG5vbi10ZXh0XG4gKiBmaWxlcyBzbyB0aGF0IHRoZSBzbmFwc2hvdHMgYXJlIGh1bWFuIHJlYWRhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3ludGhTbmFwc2hvdChcbiAgcHJvamVjdDogUHJvamVjdCxcbiAgb3B0aW9uczogU25hcHNob3RPcHRpb25zID0ge31cbik6IFN5bnRoT3V0cHV0IHtcbiAgLy8gZGVmZW5zaXZlOiB2ZXJpZnkgdGhhdCBcIm91dGRpclwiIGlzIGFjdHVhbGx5IGluIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeVxuICBpZiAoXG4gICAgIXBhdGgucmVzb2x2ZShwcm9qZWN0Lm91dGRpcikuc3RhcnRzV2l0aChvcy50bXBkaXIoKSkgJiZcbiAgICAhcHJvamVjdC5vdXRkaXIuaW5jbHVkZXMoXCJwcm9qZWN0LXRlbXAtZGlyXCIpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiVHJ5aW5nIHRvIGNhcHR1cmUgYSBzbmFwc2hvdCBvZiBhIHByb2plY3Qgb3V0c2lkZSBvZiB0bXBkaXIsIHdoaWNoIGltcGxpZXMgdGhpcyB0ZXN0IG1pZ2h0IGNvcnJ1cHQgYW4gZXhpc3RpbmcgcHJvamVjdFwiXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHN5bnRoZWQgPSBTeW1ib2wuZm9yKFwic3ludGhlZFwiKTtcbiAgaWYgKHN5bnRoZWQgaW4gcHJvamVjdCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImR1cGxpY2F0ZSBzeW50aCgpXCIpO1xuICB9XG5cbiAgKHByb2plY3QgYXMgYW55KVtzeW50aGVkXSA9IHRydWU7XG5cbiAgY29uc3QgRU5WX1BST0pFTl9ESVNBQkxFX1BPU1QgPSBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUO1xuICB0cnkge1xuICAgIHByb2Nlc3MuZW52LlBST0pFTl9ESVNBQkxFX1BPU1QgPSBcInRydWVcIjtcbiAgICBwcm9qZWN0LnN5bnRoKCk7XG4gICAgY29uc3QgaWdub3JlRXh0cyA9IFtcInBuZ1wiLCBcImljb1wiXTtcbiAgICByZXR1cm4gZGlyZWN0b3J5U25hcHNob3QocHJvamVjdC5vdXRkaXIsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBleGNsdWRlR2xvYnM6IGlnbm9yZUV4dHMubWFwKChleHQpID0+IGAqKi8qLiR7ZXh0fWApLFxuICAgICAgc3VwcG9ydEpzb25Db21tZW50czogcHJvamVjdC5maWxlcy5zb21lKFxuICAgICAgICAvLyBBdCBsZWFzdCBvbmUganNvbiBmaWxlIGluIHByb2plY3Qgc3VwcG9ydHMgY29tbWVudHNcbiAgICAgICAgKGZpbGUpID0+IGZpbGUgaW5zdGFuY2VvZiBKc29uRmlsZSAmJiBmaWxlLnN1cHBvcnRzQ29tbWVudHNcbiAgICAgICksXG4gICAgfSk7XG4gIH0gZmluYWxseSB7XG4gICAgZnMucm1TeW5jKHByb2plY3Qub3V0ZGlyLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAvLyB2YWx1ZXMgYXNzaWduZWQgdG8gcHJvY2Vzcy5lbnYuWFlaIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBzdHJpbmdzXG4gICAgaWYgKEVOVl9QUk9KRU5fRElTQUJMRV9QT1NUID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUID0gRU5WX1BST0pFTl9ESVNBQkxFX1BPU1Q7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlyZWN0b3J5U25hcHNob3RPcHRpb25zIGV4dGVuZHMgU25hcHNob3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEdsb2JzIG9mIGZpbGVzIHRvIGV4Y2x1ZGUuXG4gICAqIEBkZWZhdWx0IFtdIGluY2x1ZGUgYWxsIGZpbGVzXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlR2xvYnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogT25seSBzbmFwc2hvdCB0aGUgbmFtZXMgb2YgZmlsZXMgYW5kIG5vdCB0aGVpciBjb250ZW50cy5cbiAgICogVGhlIHZhbHVlIGZvciBhIHBhdGggd2lsbCBiZSBgdHJ1ZWAgaWYgaXQgZXhpc3RzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZSBpbmNsdWRlIGZpbGUgY29udGVudFxuICAgKi9cbiAgcmVhZG9ubHkgb25seUZpbGVOYW1lcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBmaWxlcyB3aXRoIGRpZmZlcmVudCBwYXJzZXIsIHN1cHBvcnRpbmcgY29tbWVudHNcbiAgICogaW5zaWRlIC5qc29uIGZpbGVzLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc3VwcG9ydEpzb25Db21tZW50cz86IGJvb2xlYW47XG59XG5cbmZ1bmN0aW9uIGlzSnNvbkxpa2VGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgZmlsZSA9IGZpbGVQYXRoLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgZmlsZS5lbmRzV2l0aChcIi5qc29uXCIpIHx8IGZpbGUuZW5kc1dpdGgoXCIuanNvbjVcIikgfHwgZmlsZS5lbmRzV2l0aChcIi5qc29uY1wiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlyZWN0b3J5U25hcHNob3QoXG4gIHJvb3Q6IHN0cmluZyxcbiAgb3B0aW9uczogRGlyZWN0b3J5U25hcHNob3RPcHRpb25zID0ge31cbikge1xuICBjb25zdCBvdXRwdXQ6IFN5bnRoT3V0cHV0ID0ge307XG5cbiAgY29uc3QgZmlsZXMgPSBnbG9iLnN5bmMoXCIqKlwiLCB7XG4gICAgaWdub3JlOiBbXCIuZ2l0LyoqXCIsIC4uLihvcHRpb25zLmV4Y2x1ZGVHbG9icyA/PyBbXSldLFxuICAgIGN3ZDogcm9vdCxcbiAgICBvbmx5RmlsZXM6IHRydWUsXG4gICAgZm9sbG93U3ltYm9saWNMaW5rczogZmFsc2UsXG4gICAgZG90OiB0cnVlLFxuICB9KTsgLy8gcmV0dXJucyByZWxhdGl2ZSBmaWxlIHBhdGhzIHdpdGggUE9TSVggc2VwYXJhdG9yc1xuXG4gIGNvbnN0IHBhcnNlSnNvbiA9IG9wdGlvbnMucGFyc2VKc29uID8/IHRydWU7XG5cbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4ocm9vdCwgZmlsZSk7XG5cbiAgICBsZXQgY29udGVudDtcbiAgICBpZiAoIW9wdGlvbnMub25seUZpbGVOYW1lcykge1xuICAgICAgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICAgIGlmIChwYXJzZUpzb24gJiYgaXNKc29uTGlrZUZpbGUoZmlsZVBhdGgpKSB7XG4gICAgICAgIGNvbnRlbnQgPSBjbGVhbkNvbW1lbnRBcnJheXMoXG4gICAgICAgICAgSlNPTkMucGFyc2UoY29udGVudCwgdW5kZWZpbmVkLCAhb3B0aW9ucy5zdXBwb3J0SnNvbkNvbW1lbnRzKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBvdXRwdXRbZmlsZV0gPSBjb250ZW50O1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0eXBlIFwiQ29tbWVudEFycmF5XCIgYmFjayB0byByZWd1bGFyIEpTIFwiQXJyYXlcIlxuICogaWYgdGhlcmUgYXJlIG5vIGNvbW1lbnRzIHN0b3JlZCBpbiBpdC5cbiAqIFByZXZlbnRzIHN0cmljdCBjaGVja3MgZnJvbSBmYWlsaW5nLlxuICovXG5mdW5jdGlvbiBjbGVhbkNvbW1lbnRBcnJheXMob2JqOiBhbnkpOiB0eXBlb2Ygb2JqIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSB8fCBpc0NvbW1lbnRBcnJheVdpdGhvdXRDb21tZW50cyhvYmopKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20ob2JqKS5tYXAoY2xlYW5Db21tZW50QXJyYXlzKTtcbiAgfVxuXG4gIGlmIChvYmogaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICBmb3IgKGNvbnN0IHAgb2YgT2JqZWN0LmtleXMob2JqKSkge1xuICAgICAgaWYgKGlzQ29tbWVudEFycmF5V2l0aG91dENvbW1lbnRzKG9ialtwXSkpIHtcbiAgICAgICAgb2JqW3BdID0gQXJyYXkuZnJvbShvYmpbcF0pLm1hcChjbGVhbkNvbW1lbnRBcnJheXMpO1xuICAgICAgfSBlbHNlIGlmIChvYmpbcF0gaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgb2JqW3BdID0gY2xlYW5Db21tZW50QXJyYXlzKG9ialtwXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBcIkNvbW1lbnRBcnJheVwiIGhhcyBubyBjb21tZW50cyBzdG9yZWQgaW4gaXQuXG4gKi9cbmZ1bmN0aW9uIGlzQ29tbWVudEFycmF5V2l0aG91dENvbW1lbnRzKG9iajogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgb2JqIGluc3RhbmNlb2YgQ29tbWVudEFycmF5ICYmXG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopLmxlbmd0aCA9PT0gMFxuICApO1xufVxuIl19