jsii-release
Version:
Release jsii modules to multiple package managers
239 lines • 34.8 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 () {
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=