jsii-release
Version:
Release jsii modules to multiple package managers
231 lines • 34.4 kB
JavaScript
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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__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) {
var _a, _b, _c, _d, _e;
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((_a = props.dir) !== null && _a !== void 0 ? _a : path.join(process.cwd(), 'dist', 'go'));
this.gitBranch = (_b = props.branch) !== null && _b !== void 0 ? _b : 'main';
this.dryRun = (_c = props.dryRun) !== null && _c !== void 0 ? _c : false;
const gitUsername = (_d = props.username) !== null && _d !== void 0 ? _d : git.username();
const gitUseremail = (_e = props.email) !== null && _e !== void 0 ? _e : 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) {
var _a;
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 = (_a = this.gitCommitMessage) !== null && _a !== void 0 ? _a : 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFyZ2V0cy9nby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE2QjtBQUM3Qiw2Q0FBK0I7QUFDL0IsaURBQW1DO0FBQ25DLCtDQUFpQztBQUNqQyxxREFBdUM7QUE0R3ZDOztHQUVHO0FBQ0gsTUFBYSxVQUFVO0lBV3JCLFlBQVksS0FBc0I7O1FBRWhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztTQUMzRjtRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUN0QyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBQSxLQUFLLENBQUMsR0FBRyxtQ0FBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQUEsS0FBSyxDQUFDLE1BQU0sbUNBQUksTUFBTSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBQSxLQUFLLENBQUMsTUFBTSxtQ0FBSSxLQUFLLENBQUM7UUFFcEMsTUFBTSxXQUFXLEdBQUcsTUFBQSxLQUFLLENBQUMsUUFBUSxtQ0FBSSxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckQsTUFBTSxZQUFZLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSyxtQ0FBSSxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFaEQsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFD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QUFDLENBQUM7UUFFMUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUNqQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFdkcsSUFBSSxXQUFXLElBQUksYUFBYSxJQUFJLFdBQVcsS0FBSyxhQUFhLEVBQUU7WUFDakUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsV0FBVyxvQ0FBb0MsYUFBYSxtQkFBbUIsZUFBZSxFQUFFLENBQUMsQ0FBQztTQUNwSTtRQUVELHNFQUFzRTtRQUN0RSxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBRTVELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxlQUFlLElBQUk7a0JBQ3hFLHNHQUFzRyxDQUFDLENBQUM7U0FDN0c7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUVqQixDQUFDO0NBRUY7QUFsUEQsZ0NBa1BDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIGdpdCBmcm9tICcuLi9oZWxwL2dpdCc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICcuLi9oZWxwL29zJztcbmltcG9ydCAqIGFzIHNoZWxsIGZyb20gJy4uL2hlbHAvc2hlbGwnO1xuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZWxlYXNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdvUmVsZWFzZSB7XG5cbiAgLyoqXG4gICAqIFRoZSB0YWdzIHRoZSByZWxlYXNlIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSB0YWdzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBjb21taXQgbWVzc2FnZSBvZiB0aGUgcmVsZWFzZS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1pdE1lc3NhZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIHJlcG9zaXRvcnkgd2FzIHJlbGVhc2VkIGZyb20uXG4gICAqL1xuICByZWFkb25seSByZXBvRGlyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGBHb1JlbGVhc2VyYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHb1JlbGVhc2VyUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGNvZGUgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAnZGlzdC9nbydcbiAgICovXG4gIHJlYWRvbmx5IGRpcj86IHN0cmluZztcblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGRyeSBydW4gb25seS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGRyeVJ1bj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBicmFuY2ggdG8gcHVzaCB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgJ21haW4nXG4gICAqL1xuICByZWFkb25seSBicmFuY2g/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB1c2VybmFtZSB0byB1c2UgZm9yIHRoZSBjb21taXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGFrZW4gZnJvbSBnaXQgY29uZmlnLiB0aHJvd3MgaWYgbm90IGNvbmZpZ3VyZWQuXG4gICAqL1xuICByZWFkb25seSB1c2VybmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVtYWlsIHRvIHVzZSBmb3IgdGhlIGNvbW1pdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0YWtlbiBmcm9tIGdpdCBjb25maWcuIHRocm93cyBpZiBub3QgY29uZmlndXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVtYWlsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0YWtlbiBmcm9tIHRoZSAndmVyc2lvbicuIHRocm93cyBpZiBkb2Vzbid0IGV4aXN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG1lc3NhZ2UgdG8gdXNlIGZvciB0aGUgY29tbWl0IG1hcmtpbmcgdGhlIHJlbGVhc2UuXG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWMgbW9kdWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdvTW9kdWxlIHtcblxuICAvKipcbiAgICogUGF0aCB0byB0aGUgbW9kIGZpbGUuXG4gICAqL1xuICByZWFkb25seSBtb2RGaWxlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjYW5ub25pY2FsIG5hbWUgb2YgdGhlIG1vZHVsZS4gKGUuZyAnZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nby9jb25zdHJ1Y3RzL3YzYClcbiAgICovXG4gIHJlYWRvbmx5IGNhbm5vbmljYWxOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIGluc2lkZSB0aGUgcmVwb3NpdG9yeSB0aGUgbW9kdWxlIGlzIGxvY2F0ZWQgaW4uIChlLmcgJ2NvbnN0cnVjdHMnKVxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb1BhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlcG9zaXRvcnkgVVJMLiAoZS5nICdnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzJylcbiAgICovXG4gIHJlYWRvbmx5IHJlcG9VUkw6IHN0cmluZztcblxufVxuXG4vKipcbiAqIFJlbGVhc2UgYSBzZXQgb2YgR29sYW5nIG1vZHVsZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBHb1JlbGVhc2VyIHtcblxuICBwcml2YXRlIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2l0Q29tbWl0TWVzc2FnZT86IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IGRpcjogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRyeVJ1bjogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRCcmFuY2g6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRVc2VybmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGdpdFVzZXJlbWFpbDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBHb1JlbGVhc2VyUHJvcHMpIHtcblxuICAgIGlmICghc2hlbGwud2hpY2goJ2dpdCcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dpdCBtdXN0IGJlIGF2YWlsYWJsZSB0byBpbiBvcmRlciB0byBiZSBhYmxlIHRvIHB1c2ggR28gY29kZSB0byBHaXRIdWInKTtcbiAgICB9XG5cbiAgICB0aGlzLnZlcnNpb24gPSBwcm9wcy52ZXJzaW9uO1xuICAgIHRoaXMuZ2l0Q29tbWl0TWVzc2FnZSA9IHByb3BzLm1lc3NhZ2U7XG4gICAgdGhpcy5kaXIgPSBwYXRoLnJlc29sdmUocHJvcHMuZGlyID8/IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdCcsICdnbycpKTtcbiAgICB0aGlzLmdpdEJyYW5jaCA9IHByb3BzLmJyYW5jaCA/PyAnbWFpbic7XG4gICAgdGhpcy5kcnlSdW4gPSBwcm9wcy5kcnlSdW4gPz8gZmFsc2U7XG5cbiAgICBjb25zdCBnaXRVc2VybmFtZSA9IHByb3BzLnVzZXJuYW1lID8/IGdpdC51c2VybmFtZSgpO1xuICAgIGNvbnN0IGdpdFVzZXJlbWFpbCA9IHByb3BzLmVtYWlsID8/IGdpdC5lbWFpbCgpO1xuXG4gICAgaWYgKCFnaXRVc2VybmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZWN0IHVzZXJuYW1lLiBlaXRoZXIgY29uZmlndXJlIGEgZ2l0IHVzZXIubmFtZSBvciBwYXNzIEdJVF9VU0VSX05BTUUgZW52IHZhcmlhYmxlJyk7XG4gICAgfVxuXG4gICAgaWYgKCFnaXRVc2VyZW1haWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVjdCB1c2VyIGVtYWlsLiBlaXRoZXIgY29uZmlndXJlIGEgZ2l0IHVzZXIuZW1haWwgb3IgcGFzcyBHSVRfVVNFUl9FTUFJTCBlbnYgdmFyaWFibGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLmdpdFVzZXJlbWFpbCA9IGdpdFVzZXJlbWFpbDtcbiAgICB0aGlzLmdpdFVzZXJuYW1lID0gZ2l0VXNlcm5hbWU7XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSByZWxlYXNlIHByb2Nlc3MuXG4gICAqXG4gICAqIEByZXR1cm5zIG1ldGFkYXRhIGFib3V0IHRoZSByZWxlYXNlLlxuICAgKi9cbiAgcHVibGljIHJlbGVhc2UoKTogR29SZWxlYXNlIHtcbiAgICBjb25zdCBtb2R1bGVzID0gdGhpcy5jb2xsZWN0TW9kdWxlcyh0aGlzLmRpcik7XG4gICAgaWYgKG1vZHVsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLmxvZygnTm8gbW9kdWxlcyBkZXRlY3RlZC4gU2tpcHBpbmcnKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnRGV0ZWN0ZWQgbW9kdWxlczonKTtcbiAgICBtb2R1bGVzLmZvckVhY2gobSA9PiBjb25zb2xlLmxvZyhgIC0gJHttLm1vZEZpbGV9YCkpO1xuXG4gICAgY29uc3QgcmVwb1VSTCA9IHRoaXMuZXh0cmFjdFJlcG9VUkwobW9kdWxlcyk7XG4gICAgY29uc3QgcmVwb0RpciA9IHBhdGguam9pbihvcy5ta2R0ZW1wU3luYygpLCAncmVwbycpO1xuICAgIGdpdC5jbG9uZShyZXBvVVJMLCByZXBvRGlyKTtcblxuICAgIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG4gICAgdHJ5IHtcbiAgICAgIHByb2Nlc3MuY2hkaXIocmVwb0Rpcik7XG4gICAgICByZXR1cm4gdGhpcy5kb1JlbGVhc2UobW9kdWxlcywgcmVwb0Rpcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHByb2Nlc3MuY2hkaXIoY3dkKTtcbiAgICB9XG5cbiAgfVxuXG4gIHByaXZhdGUgZG9SZWxlYXNlKG1vZHVsZXM6IEdvTW9kdWxlW10sIHJlcG9EaXI6IHN0cmluZyk6IEdvUmVsZWFzZSB7XG5cbiAgICBnaXQuaWRlbnRpZnkodGhpcy5naXRVc2VybmFtZSwgdGhpcy5naXRVc2VyZW1haWwpO1xuICAgIGdpdC5jaGVja291dCh0aGlzLmdpdEJyYW5jaCwgeyBjcmVhdGVJZk1pc3Npbmc6IHRydWUgfSk7XG4gICAgdGhpcy5zeW5jUmVwbyhyZXBvRGlyKTtcblxuICAgIGdpdC5hZGQoJy4nKTtcbiAgICBpZiAoIWdpdC5kaWZmSW5kZXgoKSkge1xuICAgICAgY29uc29sZS5sb2coJ05vIGNoYW5nZXMuIFNraXBwaW5nIHJlbGVhc2UnKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21taXRNZXNzYWdlID0gdGhpcy5naXRDb21taXRNZXNzYWdlID8/IHRoaXMuYnVpbGRSZWxlYXNlTWVzc2FnZShtb2R1bGVzKTtcbiAgICBnaXQuY29tbWl0KGNvbW1pdE1lc3NhZ2UpO1xuXG4gICAgY29uc3QgdGFncyA9IFtdO1xuICAgIGZvciAoY29uc3QgbW9kdWxlIG9mIG1vZHVsZXMpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLmJ1aWxkVGFnTmFtZShtb2R1bGUpO1xuICAgICAgY29uc3QgY3JlYXRlZCA9IGdpdC50YWcobmFtZSk7XG4gICAgICBpZiAoY3JlYXRlZCkgeyB0YWdzLnB1c2gobmFtZSk7IH1cbiAgICB9XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdBbGwgdGFncyBhbHJlYWR5IGV4aXN0LiBTa2lwcGluZyByZWxlYXNlJyk7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3QgcmVmcyA9IFsuLi50YWdzLCB0aGlzLmdpdEJyYW5jaF07XG5cbiAgICBpZiAodGhpcy5kcnlSdW4pIHtcbiAgICAgIGNvbnNvbGUubG9nKCc9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7XG4gICAgICBjb25zb2xlLmxvZygnICAgICAgICAgICAg8J+PnO+4jyBEUlktUlVOIE1PREUg8J+PnO+4jycpO1xuICAgICAgY29uc29sZS5sb2coJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTtcbiAgICAgIHJlZnMuZm9yRWFjaCh0ID0+IGNvbnNvbGUubG9nKGBSZW1vdGUgcmVmIHdpbGwgYmUgdXBkYXRlZDogJHt0fWApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVmcy5mb3JFYWNoKHQgPT4gZ2l0LnB1c2godCkpO1xuICAgIH1cbiAgICByZXR1cm4geyB0YWdzLCBjb21taXRNZXNzYWdlLCByZXBvRGlyIH07XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RNb2R1bGVzKGRpcjogc3RyaW5nKTogR29Nb2R1bGVbXSB7XG4gICAgY29uc3QgbW9kdWxlczogR29Nb2R1bGVbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcCBvZiBbLi4uZnMucmVhZGRpclN5bmMoZGlyKSwgJy4nXSkge1xuICAgICAgY29uc3QgbW9kRmlsZSA9IHBhdGguam9pbihkaXIsIHAsICdnby5tb2QnKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKG1vZEZpbGUpKSB7XG4gICAgICAgIG1vZHVsZXMucHVzaCh0aGlzLnBhcnNlTW9kdWxlKG1vZEZpbGUpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1vZHVsZXM7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTW9kdWxlKG1vZEZpbGU6IHN0cmluZyk6IEdvTW9kdWxlIHtcblxuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKHBhdGguZGlybmFtZShtb2RGaWxlKSk7XG4gICAgY29uc3QgbWFqb3JWZXJzaW9uID0gTnVtYmVyKHZlcnNpb24uc3BsaXQoJy4nKVswXSk7XG5cbiAgICAvLyBleHRyYWN0IHRoZSBtb2R1bGUgZGVjbGVyYXRpb24gKGUuZyAnbW9kdWxlIGdpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMtZ28vY29uc3RydWN0cy92MycpXG4gICAgY29uc3QgbWF0Y2ggPSBmcy5yZWFkRmlsZVN5bmMobW9kRmlsZSkudG9TdHJpbmcoKS5tYXRjaCgvbW9kdWxlICguKikvKTtcbiAgICBpZiAoIW1hdGNoIHx8ICFtYXRjaFsxXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZGV0ZWN0ZWQgbW9kdWxlIGRlY2xhcmF0aW9uIGluICR7bW9kRmlsZX1gKTtcbiAgICB9XG5cbiAgICAvLyBlLmcgJ2dpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMtZ28vY29uc3RydWN0cy92MydcbiAgICBjb25zdCBjYW5ub25pY2FsTmFtZSA9IG1hdGNoWzFdO1xuXG4gICAgLy8gZS5nIFsnZ2l0aHViLmNvbScsICdhd3MnLCAnY29uc3RydWN0cy1nbycsICdjb25zdHJ1Y3RzJywgJ3YzJ11cbiAgICBjb25zdCBjYW5ub25pY2FsTmFtZVBhcnRzID0gY2Fubm9uaWNhbE5hbWUuc3BsaXQoJy8nKTtcblxuICAgIC8vIGUuZyAnZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nbydcbiAgICBjb25zdCByZXBvVVJMID0gY2Fubm9uaWNhbE5hbWVQYXJ0cy5zbGljZSgwLCAzKS5qb2luKCcvJyk7XG5cbiAgICAvLyBlLmcgJ3YzJ1xuICAgIGNvbnN0IG1ham9yVmVyc2lvblN1ZmZpeCA9IG1ham9yVmVyc2lvbiA+IDEgPyBgL3Yke21ham9yVmVyc2lvbn1gIDogJyc7XG5cbiAgICBpZiAoIWNhbm5vbmljYWxOYW1lLmVuZHNXaXRoKG1ham9yVmVyc2lvblN1ZmZpeCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kdWxlIGRlY2xhcmF0aW9uIGluICcke21vZEZpbGV9JyBleHBlY3RlZCB0byBlbmQgd2l0aCAnJHttYWpvclZlcnNpb25TdWZmaXh9JyBzaW5jZSBpdHMgbWFqb3IgdmVyc2lvbiBpcyBsYXJnZXIgdGhhbiAxYCk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXBvVVJMLnN0YXJ0c1dpdGgoJ2dpdGh1Yi5jb20nKSkge1xuICAgICAgaWYgKCEoZ2l0LmRldGVjdFNTSCgpIHx8IGdpdC5kZXRlY3RHSEUoKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvc2l0b3J5IG11c3QgYmUgaG9zdGVkIG9uIGdpdGh1Yi5jb20uIEZvdW5kOiAnJHtyZXBvVVJMfScgaW4gJHttb2RGaWxlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgcmVwb1BhdGggPSBjYW5ub25pY2FsTmFtZVBhcnRzXG4gICAgICAuc2xpY2UoMykgLy8gZS5nIFsnY29uc3RydWN0cycsICd2MyddXG4gICAgICAuam9pbignLycpOyAvLyBlLmcgJ2NvbnN0cnVjdHMvdjMnXG5cbiAgICAvLyB3ZSBjb3VsZCBoYXZlIHNvbWV0aGluZyBsaWtlXG4gICAgLy8gY29uc3RydWN0cy92M1xuICAgIC8vIG9yIHNvbWV0aGluZyBsaWtlXG4gICAgLy8gY29uc3RydWN0c3YzL3YzXG4gICAgLy8gd2Ugb25seSB3YW50IHRvIHN0cmlwIHRoZSBsYXN0ICd2MydcbiAgICBjb25zdCBzcGxpdCA9IHJlcG9QYXRoLnNwbGl0KCcvJyk7XG4gICAgaWYgKHNwbGl0W3NwbGl0Lmxlbmd0aCAtIDFdID09PSBgdiR7bWFqb3JWZXJzaW9ufWApIHtcbiAgICAgIHNwbGl0LnBvcCgpO1xuICAgICAgcmVwb1BhdGggPSBzcGxpdC5qb2luKCcvJyk7XG4gICAgfVxuXG4gICAgLy8gc3RyaXAgJy8nIGlmIGV4aXN0cyAod29udCBleGlzdCBmb3IgdG9wIGxldmVsIG1vZHVsZXMpXG4gICAgcmVwb1BhdGggPSByZXBvUGF0aC5lbmRzV2l0aCgnLycpID8gcmVwb1BhdGguc3Vic3RyKDAsIHJlcG9QYXRoLmxlbmd0aCAtIDEpIDogcmVwb1BhdGg7XG5cbiAgICByZXR1cm4geyBtb2RGaWxlLCB2ZXJzaW9uLCBjYW5ub25pY2FsTmFtZSwgcmVwb1BhdGgsIHJlcG9VUkwgfTtcblxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ05hbWUobTogR29Nb2R1bGUpIHtcbiAgICByZXR1cm4gbS5yZXBvUGF0aCA9PT0gJycgPyBgdiR7bS52ZXJzaW9ufWAgOiBgJHttLnJlcG9QYXRofS92JHttLnZlcnNpb259YDtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRSZWxlYXNlTWVzc2FnZShtb2R1bGVzOiBHb01vZHVsZVtdKSB7XG4gICAgY29uc3Qgc2VtYW50aWMgPSAnY2hvcmUocmVsZWFzZSknO1xuICAgIGNvbnN0IHZlcnNpb25zID0gbmV3IFNldChtb2R1bGVzLm1hcChtID0+IG0udmVyc2lvbikpO1xuICAgIGlmICh2ZXJzaW9ucy5zaXplID09PSAxKSB7XG4gICAgICAvLyBzaW5nbGUgdmVyc2lvbiAoZS5nIGNob3JlKHJlbGVhc2UpOiB2MS4yLjMpXG4gICAgICByZXR1cm4gYCR7c2VtYW50aWN9OiB2JHt2ZXJzaW9ucy52YWx1ZXMoKS5uZXh0KCkudmFsdWV9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbXVsdGlwbGUgdmVyc2lvbnMgKGUuZyBjaG9yZShyZWxlYXNlKTogY2hvcmUocmVsZWFzZSk6IG1vZHVsZTFAdjEuMi4zICBtb2R1bGUyQHYxLjIuMylcbiAgICAgIHJldHVybiBgJHtzZW1hbnRpY306ICR7bW9kdWxlcy5tYXAobSA9PiBgJHttLnJlcG9QYXRoID8gYCR7bS5yZXBvUGF0aH1AYCA6ICcnfXYke20udmVyc2lvbn1gKS5qb2luKCcgJyl9YDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN5bmNSZXBvKHJlcG9EaXI6IHN0cmluZykge1xuICAgIGNvbnN0IHRvcExldmVsID0gcGF0aC5qb2luKHJlcG9EaXIsICdnby5tb2QnKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyh0b3BMZXZlbCkpIHtcbiAgICAgIC8vIHdpdGggdG9wIGxldmVsIG1vZHVsZXMgd2Ugc3luYyB0aGUgZW50aXJlIHJlcG9zaXRvcnlcbiAgICAgIC8vIHNvIHdlIGp1c3QgZW1wdHkgaXQgb3V0XG4gICAgICBmcy5yZWFkZGlyU3luYyhyZXBvRGlyKVxuICAgICAgICAuZmlsdGVyKGYgPT4gZiAhPT0gJy5naXQnKVxuICAgICAgICAuZm9yRWFjaChmID0+IGZzLnJlbW92ZVN5bmMocGF0aC5qb2luKHJlcG9EaXIsIGYpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG90aGVyd2lzZSwgd2Ugc2VsZWN0aXZlbHkgcmVtb3ZlIHRoZSBzdWJtb2R1bGVzIG9ubHkuXG4gICAgICBmb3IgKGNvbnN0IHAgb2YgZnMucmVhZGRpclN5bmMocmVwb0RpcikpIHtcbiAgICAgICAgY29uc3Qgc3VibW9kdWxlID0gcGF0aC5qb2luKHJlcG9EaXIsIHAsICdnby5tb2QnKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoc3VibW9kdWxlKSkge1xuICAgICAgICAgIGZzLnJlbW92ZVN5bmMocGF0aC5qb2luKHJlcG9EaXIsIHApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmcy5jb3B5U3luYyh0aGlzLmRpciwgcmVwb0RpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RSZXBvVVJMKG1vZHVsZXM6IEdvTW9kdWxlW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlcG9zID0gbmV3IFNldDxzdHJpbmc+KG1vZHVsZXMubWFwKG0gPT4gbS5yZXBvVVJMKSk7XG4gICAgaWYgKHJlcG9zLnNpemUgPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVjdCByZXBvc2l0b3J5IGZyb20gbW9kdWxlIGZpbGVzLicpO1xuICAgIH1cbiAgICBpZiAocmVwb3Muc2l6ZSA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTXVsdGlwbGUgcmVwb3NpdG9yaWVzIGZvdW5kIGluIG1vZHVsZSBmaWxlcycpO1xuICAgIH1cbiAgICByZXR1cm4gcmVwb3MudmFsdWVzKCkubmV4dCgpLnZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VmVyc2lvbihtb2R1bGVEaXJlY3Rvcnk6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBjb25zdCB2ZXJzaW9uRmlsZSA9IHBhdGguam9pbihtb2R1bGVEaXJlY3RvcnksICd2ZXJzaW9uJyk7XG5cbiAgICBjb25zdCByZXBvVmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICBjb25zdCBtb2R1bGVWZXJzaW9uID0gZnMuZXhpc3RzU3luYyh2ZXJzaW9uRmlsZSkgPyBmcy5yZWFkRmlsZVN5bmModmVyc2lvbkZpbGUpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVwb1ZlcnNpb24gJiYgbW9kdWxlVmVyc2lvbiAmJiByZXBvVmVyc2lvbiAhPT0gbW9kdWxlVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvIHZlcnNpb24gKCR7cmVwb1ZlcnNpb259KSBjb25mbGljdHMgd2l0aCBtb2R1bGUgdmVyc2lvbiAoJHttb2R1bGVWZXJzaW9ufSkgZm9yIG1vZHVsZSBpbiAke21vZHVsZURpcmVjdG9yeX1gKTtcbiAgICB9XG5cbiAgICAvLyBqdXN0IHRha2UgdGhlIG9uZSB0aGF0cyBkZWZpbmVkLCB0aGV5IGhhdmUgdG8gdGhlIHNhbWUgaWYgYm90aCBhcmUuXG4gICAgY29uc3QgdmVyc2lvbiA9IG1vZHVsZVZlcnNpb24gPyBtb2R1bGVWZXJzaW9uIDogcmVwb1ZlcnNpb247XG5cbiAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGRldGVybWluZSB2ZXJzaW9uIG9mIG1vZHVsZSAke21vZHVsZURpcmVjdG9yeX0uIGBcbiAgICAgICAgKyBcIkVpdGhlciBpbmNsdWRlIGEgJ3ZlcnNpb24nIGZpbGUsIG9yIHNwZWNpZnkgYSBnbG9iYWwgdmVyc2lvbiB1c2luZyB0aGUgVkVSU0lPTiBlbnZpcm9ubWVudCB2YXJpYWJsZS5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZlcnNpb247XG5cbiAgfVxuXG59XG4iXX0=
;