UNPKG

jsii-release

Version:

Release jsii modules to multiple package managers

239 lines 34.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.GoReleaser = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs-extra")); const git = __importStar(require("../help/git")); const os = __importStar(require("../help/os")); const shell = __importStar(require("../help/shell")); /** * Release a set of Golang modules. */ class GoReleaser { constructor(props) { if (!shell.which('git')) { throw new Error('git must be available to in order to be able to push Go code to GitHub'); } this.version = props.version; this.gitCommitMessage = props.message; this.dir = path.resolve(props.dir ?? path.join(process.cwd(), 'dist', 'go')); this.gitBranch = props.branch ?? 'main'; this.dryRun = props.dryRun ?? false; const gitUsername = props.username ?? git.username(); const gitUseremail = props.email ?? git.email(); if (!gitUsername) { throw new Error('Unable to detect username. either configure a git user.name or pass GIT_USER_NAME env variable'); } if (!gitUseremail) { throw new Error('Unable to detect user email. either configure a git user.email or pass GIT_USER_EMAIL env variable'); } this.gitUseremail = gitUseremail; this.gitUsername = gitUsername; } /** * Run the release process. * * @returns metadata about the release. */ release() { const modules = this.collectModules(this.dir); if (modules.length === 0) { console.log('No modules detected. Skipping'); return {}; } console.log('Detected modules:'); modules.forEach(m => console.log(` - ${m.modFile}`)); const repoURL = this.extractRepoURL(modules); const repoDir = path.join(os.mkdtempSync(), 'repo'); git.clone(repoURL, repoDir); const cwd = process.cwd(); try { process.chdir(repoDir); return this.doRelease(modules, repoDir); } finally { process.chdir(cwd); } } doRelease(modules, repoDir) { git.identify(this.gitUsername, this.gitUseremail); git.checkout(this.gitBranch, { createIfMissing: true }); this.syncRepo(repoDir); git.add('.'); if (!git.diffIndex()) { console.log('No changes. Skipping release'); return {}; } const commitMessage = this.gitCommitMessage ?? this.buildReleaseMessage(modules); git.commit(commitMessage); const tags = []; for (const module of modules) { const name = this.buildTagName(module); const created = git.tag(name); if (created) { tags.push(name); } } if (tags.length === 0) { console.log('All tags already exist. Skipping release'); return {}; } const refs = [...tags, this.gitBranch]; if (this.dryRun) { console.log('==========================================='); console.log(' 🏜️ DRY-RUN MODE 🏜️'); console.log('==========================================='); refs.forEach(t => console.log(`Remote ref will be updated: ${t}`)); } else { refs.forEach(t => git.push(t)); } return { tags, commitMessage, repoDir }; } collectModules(dir) { const modules = []; for (const p of [...fs.readdirSync(dir), '.']) { const modFile = path.join(dir, p, 'go.mod'); if (fs.existsSync(modFile)) { modules.push(this.parseModule(modFile)); } } return modules; } parseModule(modFile) { const version = this.extractVersion(path.dirname(modFile)); const majorVersion = Number(version.split('.')[0]); // extract the module decleration (e.g 'module github.com/aws/constructs-go/constructs/v3') const match = fs.readFileSync(modFile).toString().match(/module (.*)/); if (!match || !match[1]) { throw new Error(`Unable to detected module declaration in ${modFile}`); } // e.g 'github.com/aws/constructs-go/constructs/v3' const cannonicalName = match[1]; // e.g ['github.com', 'aws', 'constructs-go', 'constructs', 'v3'] const cannonicalNameParts = cannonicalName.split('/'); // e.g 'github.com/aws/constructs-go' const repoURL = cannonicalNameParts.slice(0, 3).join('/'); // e.g 'v3' const majorVersionSuffix = majorVersion > 1 ? `/v${majorVersion}` : ''; if (!cannonicalName.endsWith(majorVersionSuffix)) { throw new Error(`Module declaration in '${modFile}' expected to end with '${majorVersionSuffix}' since its major version is larger than 1`); } if (!repoURL.startsWith('github.com')) { if (!(git.detectSSH() || git.detectGHE())) { throw new Error(`Repository must be hosted on github.com. Found: '${repoURL}' in ${modFile}`); } } let repoPath = cannonicalNameParts .slice(3) // e.g ['constructs', 'v3'] .join('/'); // e.g 'constructs/v3' // we could have something like // constructs/v3 // or something like // constructsv3/v3 // we only want to strip the last 'v3' const split = repoPath.split('/'); if (split[split.length - 1] === `v${majorVersion}`) { split.pop(); repoPath = split.join('/'); } // strip '/' if exists (wont exist for top level modules) repoPath = repoPath.endsWith('/') ? repoPath.substr(0, repoPath.length - 1) : repoPath; return { modFile, version, cannonicalName, repoPath, repoURL }; } buildTagName(m) { return m.repoPath === '' ? `v${m.version}` : `${m.repoPath}/v${m.version}`; } buildReleaseMessage(modules) { const semantic = 'chore(release)'; const versions = new Set(modules.map(m => m.version)); if (versions.size === 1) { // single version (e.g chore(release): v1.2.3) return `${semantic}: v${versions.values().next().value}`; } else { // multiple versions (e.g chore(release): chore(release): module1@v1.2.3 module2@v1.2.3) return `${semantic}: ${modules.map(m => `${m.repoPath ? `${m.repoPath}@` : ''}v${m.version}`).join(' ')}`; } } syncRepo(repoDir) { const topLevel = path.join(repoDir, 'go.mod'); if (fs.existsSync(topLevel)) { // with top level modules we sync the entire repository // so we just empty it out fs.readdirSync(repoDir) .filter(f => f !== '.git') .forEach(f => fs.removeSync(path.join(repoDir, f))); } else { // otherwise, we selectively remove the submodules only. for (const p of fs.readdirSync(repoDir)) { const submodule = path.join(repoDir, p, 'go.mod'); if (fs.existsSync(submodule)) { fs.removeSync(path.join(repoDir, p)); } } } fs.copySync(this.dir, repoDir, { recursive: true }); } extractRepoURL(modules) { const repos = new Set(modules.map(m => m.repoURL)); if (repos.size === 0) { throw new Error('Unable to detect repository from module files.'); } if (repos.size > 1) { throw new Error('Multiple repositories found in module files'); } return repos.values().next().value; } extractVersion(moduleDirectory) { const versionFile = path.join(moduleDirectory, 'version'); const repoVersion = this.version; const moduleVersion = fs.existsSync(versionFile) ? fs.readFileSync(versionFile).toString() : undefined; if (repoVersion && moduleVersion && repoVersion !== moduleVersion) { throw new Error(`Repo version (${repoVersion}) conflicts with module version (${moduleVersion}) for module in ${moduleDirectory}`); } // just take the one thats defined, they have to the same if both are. const version = moduleVersion ? moduleVersion : repoVersion; if (!version) { throw new Error(`Unable to determine version of module ${moduleDirectory}. ` + "Either include a 'version' file, or specify a global version using the VERSION environment variable."); } return version; } } exports.GoReleaser = GoReleaser; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFyZ2V0cy9nby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsNkNBQStCO0FBQy9CLGlEQUFtQztBQUNuQywrQ0FBaUM7QUFDakMscURBQXVDO0FBNEd2Qzs7R0FFRztBQUNILE1BQWEsVUFBVTtJQVdyQixZQUFZLEtBQXNCO1FBRWhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3RUFBd0UsQ0FBQyxDQUFDO1FBQzVGLENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDdEMsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQztRQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDO1FBRXBDLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRWhELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLGdHQUFn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SUFBSSxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBTSxDQUFDO0lBQ3RDLENBQUM7SUFFTyxjQUFjLENBQUMsZUFBdUI7UUFFNUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFMUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUNqQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFdkcsSUFBSSxXQUFXLElBQUksYUFBYSxJQUFJLFdBQVcsS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUNsRSxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixXQUFXLG9DQUFvQyxhQUFhLG1CQUFtQixlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQ3JJLENBQUM7UUFFRCxzRUFBc0U7UUFDdEUsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUU1RCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxlQUFlLElBQUk7a0JBQ3hFLHNHQUFzRyxDQUFDLENBQUM7UUFDOUcsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBRWpCLENBQUM7Q0FFRjtBQWxQRCxnQ0FrUEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0ICogYXMgZ2l0IGZyb20gJy4uL2hlbHAvZ2l0JztcbmltcG9ydCAqIGFzIG9zIGZyb20gJy4uL2hlbHAvb3MnO1xuaW1wb3J0ICogYXMgc2hlbGwgZnJvbSAnLi4vaGVscC9zaGVsbCc7XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlbGVhc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR29SZWxlYXNlIHtcblxuICAvKipcbiAgICogVGhlIHRhZ3MgdGhlIHJlbGVhc2UgY3JlYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGNvbW1pdCBtZXNzYWdlIG9mIHRoZSByZWxlYXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWl0TWVzc2FnZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgcmVwb3NpdG9yeSB3YXMgcmVsZWFzZWQgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG9EaXI/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYEdvUmVsZWFzZXJgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdvUmVsZWFzZXJQcm9wcyB7XG5cbiAgLyoqXG4gICAqIFRoZSBzb3VyY2UgY29kZSBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdkaXN0L2dvJ1xuICAgKi9cbiAgcmVhZG9ubHkgZGlyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgZHJ5IHJ1biBvbmx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZHJ5UnVuPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGJyYW5jaCB0byBwdXNoIHRvLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnbWFpbidcbiAgICovXG4gIHJlYWRvbmx5IGJyYW5jaD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHVzZXJuYW1lIHRvIHVzZSBmb3IgdGhlIGNvbW1pdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0YWtlbiBmcm9tIGdpdCBjb25maWcuIHRocm93cyBpZiBub3QgY29uZmlndXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZW1haWwgdG8gdXNlIGZvciB0aGUgY29tbWl0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRha2VuIGZyb20gZ2l0IGNvbmZpZy4gdGhyb3dzIGlmIG5vdCBjb25maWd1cmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZW1haWw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2ZXJzaW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRha2VuIGZyb20gdGhlICd2ZXJzaW9uJy4gdGhyb3dzIGlmIGRvZXNuJ3QgZXhpc3QuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbWVzc2FnZSB0byB1c2UgZm9yIHRoZSBjb21taXQgbWFya2luZyB0aGUgcmVsZWFzZS5cbiAgICovXG4gIHJlYWRvbmx5IG1lc3NhZ2U/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSW5mb3JtYXRpb24gYWJvdXQgYSBzcGVjaWZpYyBtb2R1bGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR29Nb2R1bGUge1xuXG4gIC8qKlxuICAgKiBQYXRoIHRvIHRoZSBtb2QgZmlsZS5cbiAgICovXG4gIHJlYWRvbmx5IG1vZEZpbGU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNhbm5vbmljYWwgbmFtZSBvZiB0aGUgbW9kdWxlLiAoZS5nICdnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzLWdvL2NvbnN0cnVjdHMvdjNgKVxuICAgKi9cbiAgcmVhZG9ubHkgY2Fubm9uaWNhbE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBhdGggaW5zaWRlIHRoZSByZXBvc2l0b3J5IHRoZSBtb2R1bGUgaXMgbG9jYXRlZCBpbi4gKGUuZyAnY29uc3RydWN0cycpXG4gICAqL1xuICByZWFkb25seSByZXBvUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVwb3NpdG9yeSBVUkwuIChlLmcgJ2dpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMnKVxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb1VSTDogc3RyaW5nO1xuXG59XG5cbi8qKlxuICogUmVsZWFzZSBhIHNldCBvZiBHb2xhbmcgbW9kdWxlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEdvUmVsZWFzZXIge1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRDb21taXRNZXNzYWdlPzogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZHJ5UnVuOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGdpdEJyYW5jaDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGdpdFVzZXJuYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2l0VXNlcmVtYWlsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IEdvUmVsZWFzZXJQcm9wcykge1xuXG4gICAgaWYgKCFzaGVsbC53aGljaCgnZ2l0JykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2l0IG11c3QgYmUgYXZhaWxhYmxlIHRvIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gcHVzaCBHbyBjb2RlIHRvIEdpdEh1YicpO1xuICAgIH1cblxuICAgIHRoaXMudmVyc2lvbiA9IHByb3BzLnZlcnNpb247XG4gICAgdGhpcy5naXRDb21taXRNZXNzYWdlID0gcHJvcHMubWVzc2FnZTtcbiAgICB0aGlzLmRpciA9IHBhdGgucmVzb2x2ZShwcm9wcy5kaXIgPz8gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdkaXN0JywgJ2dvJykpO1xuICAgIHRoaXMuZ2l0QnJhbmNoID0gcHJvcHMuYnJhbmNoID8/ICdtYWluJztcbiAgICB0aGlzLmRyeVJ1biA9IHByb3BzLmRyeVJ1biA/PyBmYWxzZTtcblxuICAgIGNvbnN0IGdpdFVzZXJuYW1lID0gcHJvcHMudXNlcm5hbWUgPz8gZ2l0LnVzZXJuYW1lKCk7XG4gICAgY29uc3QgZ2l0VXNlcmVtYWlsID0gcHJvcHMuZW1haWwgPz8gZ2l0LmVtYWlsKCk7XG5cbiAgICBpZiAoIWdpdFVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZXRlY3QgdXNlcm5hbWUuIGVpdGhlciBjb25maWd1cmUgYSBnaXQgdXNlci5uYW1lIG9yIHBhc3MgR0lUX1VTRVJfTkFNRSBlbnYgdmFyaWFibGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIWdpdFVzZXJlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZWN0IHVzZXIgZW1haWwuIGVpdGhlciBjb25maWd1cmUgYSBnaXQgdXNlci5lbWFpbCBvciBwYXNzIEdJVF9VU0VSX0VNQUlMIGVudiB2YXJpYWJsZScpO1xuICAgIH1cblxuICAgIHRoaXMuZ2l0VXNlcmVtYWlsID0gZ2l0VXNlcmVtYWlsO1xuICAgIHRoaXMuZ2l0VXNlcm5hbWUgPSBnaXRVc2VybmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gdGhlIHJlbGVhc2UgcHJvY2Vzcy5cbiAgICpcbiAgICogQHJldHVybnMgbWV0YWRhdGEgYWJvdXQgdGhlIHJlbGVhc2UuXG4gICAqL1xuICBwdWJsaWMgcmVsZWFzZSgpOiBHb1JlbGVhc2Uge1xuICAgIGNvbnN0IG1vZHVsZXMgPSB0aGlzLmNvbGxlY3RNb2R1bGVzKHRoaXMuZGlyKTtcbiAgICBpZiAobW9kdWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdObyBtb2R1bGVzIGRldGVjdGVkLiBTa2lwcGluZycpO1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCdEZXRlY3RlZCBtb2R1bGVzOicpO1xuICAgIG1vZHVsZXMuZm9yRWFjaChtID0+IGNvbnNvbGUubG9nKGAgLSAke20ubW9kRmlsZX1gKSk7XG5cbiAgICBjb25zdCByZXBvVVJMID0gdGhpcy5leHRyYWN0UmVwb1VSTChtb2R1bGVzKTtcbiAgICBjb25zdCByZXBvRGlyID0gcGF0aC5qb2luKG9zLm1rZHRlbXBTeW5jKCksICdyZXBvJyk7XG4gICAgZ2l0LmNsb25lKHJlcG9VUkwsIHJlcG9EaXIpO1xuXG4gICAgY29uc3QgY3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgICB0cnkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihyZXBvRGlyKTtcbiAgICAgIHJldHVybiB0aGlzLmRvUmVsZWFzZShtb2R1bGVzLCByZXBvRGlyKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcHJvY2Vzcy5jaGRpcihjd2QpO1xuICAgIH1cblxuICB9XG5cbiAgcHJpdmF0ZSBkb1JlbGVhc2UobW9kdWxlczogR29Nb2R1bGVbXSwgcmVwb0Rpcjogc3RyaW5nKTogR29SZWxlYXNlIHtcblxuICAgIGdpdC5pZGVudGlmeSh0aGlzLmdpdFVzZXJuYW1lLCB0aGlzLmdpdFVzZXJlbWFpbCk7XG4gICAgZ2l0LmNoZWNrb3V0KHRoaXMuZ2l0QnJhbmNoLCB7IGNyZWF0ZUlmTWlzc2luZzogdHJ1ZSB9KTtcbiAgICB0aGlzLnN5bmNSZXBvKHJlcG9EaXIpO1xuXG4gICAgZ2l0LmFkZCgnLicpO1xuICAgIGlmICghZ2l0LmRpZmZJbmRleCgpKSB7XG4gICAgICBjb25zb2xlLmxvZygnTm8gY2hhbmdlcy4gU2tpcHBpbmcgcmVsZWFzZScpO1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGNvbnN0IGNvbW1pdE1lc3NhZ2UgPSB0aGlzLmdpdENvbW1pdE1lc3NhZ2UgPz8gdGhpcy5idWlsZFJlbGVhc2VNZXNzYWdlKG1vZHVsZXMpO1xuICAgIGdpdC5jb21taXQoY29tbWl0TWVzc2FnZSk7XG5cbiAgICBjb25zdCB0YWdzID0gW107XG4gICAgZm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuYnVpbGRUYWdOYW1lKG1vZHVsZSk7XG4gICAgICBjb25zdCBjcmVhdGVkID0gZ2l0LnRhZyhuYW1lKTtcbiAgICAgIGlmIChjcmVhdGVkKSB7IHRhZ3MucHVzaChuYW1lKTsgfVxuICAgIH1cblxuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS5sb2coJ0FsbCB0YWdzIGFscmVhZHkgZXhpc3QuIFNraXBwaW5nIHJlbGVhc2UnKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCByZWZzID0gWy4uLnRhZ3MsIHRoaXMuZ2l0QnJhbmNoXTtcblxuICAgIGlmICh0aGlzLmRyeVJ1bikge1xuICAgICAgY29uc29sZS5sb2coJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTtcbiAgICAgIGNvbnNvbGUubG9nKCcgICAgICAgICAgICDwn4+c77iPIERSWS1SVU4gTU9ERSDwn4+c77iPJyk7XG4gICAgICBjb25zb2xlLmxvZygnPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PScpO1xuICAgICAgcmVmcy5mb3JFYWNoKHQgPT4gY29uc29sZS5sb2coYFJlbW90ZSByZWYgd2lsbCBiZSB1cGRhdGVkOiAke3R9YCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWZzLmZvckVhY2godCA9PiBnaXQucHVzaCh0KSk7XG4gICAgfVxuICAgIHJldHVybiB7IHRhZ3MsIGNvbW1pdE1lc3NhZ2UsIHJlcG9EaXIgfTtcbiAgfVxuXG4gIHByaXZhdGUgY29sbGVjdE1vZHVsZXMoZGlyOiBzdHJpbmcpOiBHb01vZHVsZVtdIHtcbiAgICBjb25zdCBtb2R1bGVzOiBHb01vZHVsZVtdID0gW107XG4gICAgZm9yIChjb25zdCBwIG9mIFsuLi5mcy5yZWFkZGlyU3luYyhkaXIpLCAnLiddKSB7XG4gICAgICBjb25zdCBtb2RGaWxlID0gcGF0aC5qb2luKGRpciwgcCwgJ2dvLm1vZCcpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMobW9kRmlsZSkpIHtcbiAgICAgICAgbW9kdWxlcy5wdXNoKHRoaXMucGFyc2VNb2R1bGUobW9kRmlsZSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbW9kdWxlcztcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VNb2R1bGUobW9kRmlsZTogc3RyaW5nKTogR29Nb2R1bGUge1xuXG4gICAgY29uc3QgdmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24ocGF0aC5kaXJuYW1lKG1vZEZpbGUpKTtcbiAgICBjb25zdCBtYWpvclZlcnNpb24gPSBOdW1iZXIodmVyc2lvbi5zcGxpdCgnLicpWzBdKTtcblxuICAgIC8vIGV4dHJhY3QgdGhlIG1vZHVsZSBkZWNsZXJhdGlvbiAoZS5nICdtb2R1bGUgZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nby9jb25zdHJ1Y3RzL3YzJylcbiAgICBjb25zdCBtYXRjaCA9IGZzLnJlYWRGaWxlU3luYyhtb2RGaWxlKS50b1N0cmluZygpLm1hdGNoKC9tb2R1bGUgKC4qKS8pO1xuICAgIGlmICghbWF0Y2ggfHwgIW1hdGNoWzFdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBkZXRlY3RlZCBtb2R1bGUgZGVjbGFyYXRpb24gaW4gJHttb2RGaWxlfWApO1xuICAgIH1cblxuICAgIC8vIGUuZyAnZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nby9jb25zdHJ1Y3RzL3YzJ1xuICAgIGNvbnN0IGNhbm5vbmljYWxOYW1lID0gbWF0Y2hbMV07XG5cbiAgICAvLyBlLmcgWydnaXRodWIuY29tJywgJ2F3cycsICdjb25zdHJ1Y3RzLWdvJywgJ2NvbnN0cnVjdHMnLCAndjMnXVxuICAgIGNvbnN0IGNhbm5vbmljYWxOYW1lUGFydHMgPSBjYW5ub25pY2FsTmFtZS5zcGxpdCgnLycpO1xuXG4gICAgLy8gZS5nICdnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzLWdvJ1xuICAgIGNvbnN0IHJlcG9VUkwgPSBjYW5ub25pY2FsTmFtZVBhcnRzLnNsaWNlKDAsIDMpLmpvaW4oJy8nKTtcblxuICAgIC8vIGUuZyAndjMnXG4gICAgY29uc3QgbWFqb3JWZXJzaW9uU3VmZml4ID0gbWFqb3JWZXJzaW9uID4gMSA/IGAvdiR7bWFqb3JWZXJzaW9ufWAgOiAnJztcblxuICAgIGlmICghY2Fubm9uaWNhbE5hbWUuZW5kc1dpdGgobWFqb3JWZXJzaW9uU3VmZml4KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2R1bGUgZGVjbGFyYXRpb24gaW4gJyR7bW9kRmlsZX0nIGV4cGVjdGVkIHRvIGVuZCB3aXRoICcke21ham9yVmVyc2lvblN1ZmZpeH0nIHNpbmNlIGl0cyBtYWpvciB2ZXJzaW9uIGlzIGxhcmdlciB0aGFuIDFgKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlcG9VUkwuc3RhcnRzV2l0aCgnZ2l0aHViLmNvbScpKSB7XG4gICAgICBpZiAoIShnaXQuZGV0ZWN0U1NIKCkgfHwgZ2l0LmRldGVjdEdIRSgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcG9zaXRvcnkgbXVzdCBiZSBob3N0ZWQgb24gZ2l0aHViLmNvbS4gRm91bmQ6ICcke3JlcG9VUkx9JyBpbiAke21vZEZpbGV9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIGxldCByZXBvUGF0aCA9IGNhbm5vbmljYWxOYW1lUGFydHNcbiAgICAgIC5zbGljZSgzKSAvLyBlLmcgWydjb25zdHJ1Y3RzJywgJ3YzJ11cbiAgICAgIC5qb2luKCcvJyk7IC8vIGUuZyAnY29uc3RydWN0cy92MydcblxuICAgIC8vIHdlIGNvdWxkIGhhdmUgc29tZXRoaW5nIGxpa2VcbiAgICAvLyBjb25zdHJ1Y3RzL3YzXG4gICAgLy8gb3Igc29tZXRoaW5nIGxpa2VcbiAgICAvLyBjb25zdHJ1Y3RzdjMvdjNcbiAgICAvLyB3ZSBvbmx5IHdhbnQgdG8gc3RyaXAgdGhlIGxhc3QgJ3YzJ1xuICAgIGNvbnN0IHNwbGl0ID0gcmVwb1BhdGguc3BsaXQoJy8nKTtcbiAgICBpZiAoc3BsaXRbc3BsaXQubGVuZ3RoIC0gMV0gPT09IGB2JHttYWpvclZlcnNpb259YCkge1xuICAgICAgc3BsaXQucG9wKCk7XG4gICAgICByZXBvUGF0aCA9IHNwbGl0LmpvaW4oJy8nKTtcbiAgICB9XG5cbiAgICAvLyBzdHJpcCAnLycgaWYgZXhpc3RzICh3b250IGV4aXN0IGZvciB0b3AgbGV2ZWwgbW9kdWxlcylcbiAgICByZXBvUGF0aCA9IHJlcG9QYXRoLmVuZHNXaXRoKCcvJykgPyByZXBvUGF0aC5zdWJzdHIoMCwgcmVwb1BhdGgubGVuZ3RoIC0gMSkgOiByZXBvUGF0aDtcblxuICAgIHJldHVybiB7IG1vZEZpbGUsIHZlcnNpb24sIGNhbm5vbmljYWxOYW1lLCByZXBvUGF0aCwgcmVwb1VSTCB9O1xuXG4gIH1cblxuICBwcml2YXRlIGJ1aWxkVGFnTmFtZShtOiBHb01vZHVsZSkge1xuICAgIHJldHVybiBtLnJlcG9QYXRoID09PSAnJyA/IGB2JHttLnZlcnNpb259YCA6IGAke20ucmVwb1BhdGh9L3Yke20udmVyc2lvbn1gO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFJlbGVhc2VNZXNzYWdlKG1vZHVsZXM6IEdvTW9kdWxlW10pIHtcbiAgICBjb25zdCBzZW1hbnRpYyA9ICdjaG9yZShyZWxlYXNlKSc7XG4gICAgY29uc3QgdmVyc2lvbnMgPSBuZXcgU2V0KG1vZHVsZXMubWFwKG0gPT4gbS52ZXJzaW9uKSk7XG4gICAgaWYgKHZlcnNpb25zLnNpemUgPT09IDEpIHtcbiAgICAgIC8vIHNpbmdsZSB2ZXJzaW9uIChlLmcgY2hvcmUocmVsZWFzZSk6IHYxLjIuMylcbiAgICAgIHJldHVybiBgJHtzZW1hbnRpY306IHYke3ZlcnNpb25zLnZhbHVlcygpLm5leHQoKS52YWx1ZX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBtdWx0aXBsZSB2ZXJzaW9ucyAoZS5nIGNob3JlKHJlbGVhc2UpOiBjaG9yZShyZWxlYXNlKTogbW9kdWxlMUB2MS4yLjMgIG1vZHVsZTJAdjEuMi4zKVxuICAgICAgcmV0dXJuIGAke3NlbWFudGljfTogJHttb2R1bGVzLm1hcChtID0+IGAke20ucmVwb1BhdGggPyBgJHttLnJlcG9QYXRofUBgIDogJyd9diR7bS52ZXJzaW9ufWApLmpvaW4oJyAnKX1gO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3luY1JlcG8ocmVwb0Rpcjogc3RyaW5nKSB7XG4gICAgY29uc3QgdG9wTGV2ZWwgPSBwYXRoLmpvaW4ocmVwb0RpciwgJ2dvLm1vZCcpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKHRvcExldmVsKSkge1xuICAgICAgLy8gd2l0aCB0b3AgbGV2ZWwgbW9kdWxlcyB3ZSBzeW5jIHRoZSBlbnRpcmUgcmVwb3NpdG9yeVxuICAgICAgLy8gc28gd2UganVzdCBlbXB0eSBpdCBvdXRcbiAgICAgIGZzLnJlYWRkaXJTeW5jKHJlcG9EaXIpXG4gICAgICAgIC5maWx0ZXIoZiA9PiBmICE9PSAnLmdpdCcpXG4gICAgICAgIC5mb3JFYWNoKGYgPT4gZnMucmVtb3ZlU3luYyhwYXRoLmpvaW4ocmVwb0RpciwgZikpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb3RoZXJ3aXNlLCB3ZSBzZWxlY3RpdmVseSByZW1vdmUgdGhlIHN1Ym1vZHVsZXMgb25seS5cbiAgICAgIGZvciAoY29uc3QgcCBvZiBmcy5yZWFkZGlyU3luYyhyZXBvRGlyKSkge1xuICAgICAgICBjb25zdCBzdWJtb2R1bGUgPSBwYXRoLmpvaW4ocmVwb0RpciwgcCwgJ2dvLm1vZCcpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhzdWJtb2R1bGUpKSB7XG4gICAgICAgICAgZnMucmVtb3ZlU3luYyhwYXRoLmpvaW4ocmVwb0RpciwgcCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZzLmNvcHlTeW5jKHRoaXMuZGlyLCByZXBvRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdFJlcG9VUkwobW9kdWxlczogR29Nb2R1bGVbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgcmVwb3MgPSBuZXcgU2V0PHN0cmluZz4obW9kdWxlcy5tYXAobSA9PiBtLnJlcG9VUkwpKTtcbiAgICBpZiAocmVwb3Muc2l6ZSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZWN0IHJlcG9zaXRvcnkgZnJvbSBtb2R1bGUgZmlsZXMuJyk7XG4gICAgfVxuICAgIGlmIChyZXBvcy5zaXplID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdWx0aXBsZSByZXBvc2l0b3JpZXMgZm91bmQgaW4gbW9kdWxlIGZpbGVzJyk7XG4gICAgfVxuICAgIHJldHVybiByZXBvcy52YWx1ZXMoKS5uZXh0KCkudmFsdWUhO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VmVyc2lvbihtb2R1bGVEaXJlY3Rvcnk6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBjb25zdCB2ZXJzaW9uRmlsZSA9IHBhdGguam9pbihtb2R1bGVEaXJlY3RvcnksICd2ZXJzaW9uJyk7XG5cbiAgICBjb25zdCByZXBvVmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICBjb25zdCBtb2R1bGVWZXJzaW9uID0gZnMuZXhpc3RzU3luYyh2ZXJzaW9uRmlsZSkgPyBmcy5yZWFkRmlsZVN5bmModmVyc2lvbkZpbGUpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVwb1ZlcnNpb24gJiYgbW9kdWxlVmVyc2lvbiAmJiByZXBvVmVyc2lvbiAhPT0gbW9kdWxlVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvIHZlcnNpb24gKCR7cmVwb1ZlcnNpb259KSBjb25mbGljdHMgd2l0aCBtb2R1bGUgdmVyc2lvbiAoJHttb2R1bGVWZXJzaW9ufSkgZm9yIG1vZHVsZSBpbiAke21vZHVsZURpcmVjdG9yeX1gKTtcbiAgICB9XG5cbiAgICAvLyBqdXN0IHRha2UgdGhlIG9uZSB0aGF0cyBkZWZpbmVkLCB0aGV5IGhhdmUgdG8gdGhlIHNhbWUgaWYgYm90aCBhcmUuXG4gICAgY29uc3QgdmVyc2lvbiA9IG1vZHVsZVZlcnNpb24gPyBtb2R1bGVWZXJzaW9uIDogcmVwb1ZlcnNpb247XG5cbiAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGRldGVybWluZSB2ZXJzaW9uIG9mIG1vZHVsZSAke21vZHVsZURpcmVjdG9yeX0uIGBcbiAgICAgICAgKyBcIkVpdGhlciBpbmNsdWRlIGEgJ3ZlcnNpb24nIGZpbGUsIG9yIHNwZWNpZnkgYSBnbG9iYWwgdmVyc2lvbiB1c2luZyB0aGUgVkVSU0lPTiBlbnZpcm9ubWVudCB2YXJpYWJsZS5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZlcnNpb247XG5cbiAgfVxuXG59XG4iXX0=