UNPKG

gitlab-ci-local

Version:

Tired of pushing to test your .gitlab-ci.yml?

136 lines 28.3 kB
import fs from "fs-extra"; import * as yaml from "js-yaml"; import chalk from "chalk"; import assert from "assert"; import { Utils } from "./utils.js"; import dotenv from "dotenv"; export class VariablesFromFiles { static async init(argv, writeStreams, gitData) { const cwd = argv.cwd; const stateDir = argv.stateDir; const homeDir = argv.home; const remoteVariables = argv.remoteVariables; const autoCompleting = argv.autoCompleting; const homeVariablesFile = `${homeDir}/${stateDir}/variables.yml`; const variables = {}; let remoteFileData = {}; let homeFileData = {}; if (remoteVariables && !autoCompleting) { const match = /(?<url>git@.*?)=(?<file>.*?)=(?<ref>.*)/.exec(remoteVariables); assert(match != null, "--remote-variables is malformed use 'git@gitlab.com:firecow/example.git=gitlab-variables.yml=master' syntax"); const url = match.groups?.url; const file = match.groups?.file; const ref = match.groups?.ref; const res = await Utils.bash(`set -eou pipefail; git archive --remote=${url} ${ref} ${file} | tar -xO ${file}`, cwd); remoteFileData = yaml.load(`${res.stdout}`); } if (await fs.pathExists(homeVariablesFile)) { homeFileData = yaml.load(await fs.readFile(homeVariablesFile, "utf8"), { schema: yaml.FAILSAFE_SCHEMA }); } const unpack = (v) => { if (typeof v === "string") { const catchAll = { values: {}, type: null }; catchAll.values = {}; catchAll.values["*"] = v; return catchAll; } else { v.type = v.type ?? "variable"; } return v; }; const addToVariables = async (key, val, scopePriority, isDotEnv = false) => { const { type, values } = unpack(val); for (const [matcher, content] of Object.entries(values)) { assert(typeof content == "string", `${key}.${matcher} content must be text or multiline text`); if (isDotEnv || type === "variable" || (type === null && !/^[/~]/.exec(content))) { const regexp = matcher === "*" ? /.*/g : new RegExp(`^${matcher.replace(/\*/g, ".*")}$`, "g"); variables[key] = variables[key] ?? { type: "variable", environments: [] }; variables[key].environments.push({ content, regexp, regexpPriority: matcher.length, scopePriority }); } else if (type === null && /^[/~]/.exec(content)) { const fileSource = content.replace(/^~\/(.*)/, `${homeDir}/$1`); const regexp = matcher === "*" ? /.*/g : new RegExp(`^${matcher.replace(/\*/g, ".*")}$`, "g"); variables[key] = variables[key] ?? { type: "file", environments: [] }; if (fs.existsSync(fileSource)) { variables[key].environments.push({ content, regexp, regexpPriority: matcher.length, scopePriority, fileSource }); } else { variables[key].environments.push({ content: `warn: ${key} is pointing to invalid path\n`, regexp, regexpPriority: matcher.length, scopePriority }); } } else if (type === "file") { const regexp = matcher === "*" ? /.*/g : new RegExp(`^${matcher.replace(/\*/g, ".*")}$`, "g"); variables[key] = variables[key] ?? { type: "file", environments: [] }; variables[key].environments.push({ content, regexp, regexpPriority: matcher.length, scopePriority }); } else { assert(false, `${key} was not handled properly`); } } }; const addVariableFileToVariables = async (fileData, filePriority) => { for (const [globalKey, globalEntry] of Object.entries(fileData?.global ?? {})) { await addToVariables(globalKey, globalEntry, 1 + filePriority); } const groupUrl = `${gitData.remote.host}/${gitData.remote.group}/`; for (const [groupKey, groupEntries] of Object.entries(fileData?.group ?? {})) { if (!groupUrl.includes(this.normalizeProjectKey(groupKey, writeStreams))) continue; assert(groupEntries != null, "groupEntries cannot be null/undefined"); assert(Utils.isObject(groupEntries), "group entries in variable files must be an object"); for (const [k, v] of Object.entries(groupEntries)) { await addToVariables(k, v, 2 + filePriority); } } const projectUrl = `${gitData.remote.host}/${gitData.remote.group}/${gitData.remote.project}.git`; for (const [projectKey, projectEntries] of Object.entries(fileData?.project ?? [])) { if (!projectUrl.includes(this.normalizeProjectKey(projectKey, writeStreams))) continue; assert(projectEntries != null, "projectEntries cannot be null/undefined"); assert(Utils.isObject(projectEntries), "project entries in variable files must be an object"); for (const [k, v] of Object.entries(projectEntries)) { await addToVariables(k, v, 3 + filePriority); } } }; await addVariableFileToVariables(remoteFileData, 0); await addVariableFileToVariables(homeFileData, 10); const projectVariablesFile = `${argv.cwd}/${argv.variablesFile}`; if (fs.existsSync(projectVariablesFile)) { let isDotEnvFormat = false; const projectVariablesFileRawContent = await fs.readFile(projectVariablesFile, "utf8"); let projectVariablesFileData; try { projectVariablesFileData = yaml.load(projectVariablesFileRawContent, { schema: yaml.FAILSAFE_SCHEMA }) ?? {}; if (typeof (projectVariablesFileData) === "string") { isDotEnvFormat = true; projectVariablesFileData = dotenv.parse(projectVariablesFileRawContent); } } catch (e) { if (e instanceof yaml.YAMLException) { isDotEnvFormat = true; projectVariablesFileData = dotenv.parse(projectVariablesFileRawContent); } } assert(projectVariablesFileData != null, "projectEntries cannot be null/undefined"); assert(Utils.isObject(projectVariablesFileData), `${argv.cwd}/.gitlab-ci-local-variables.yml must contain an object`); for (const [k, v] of Object.entries(projectVariablesFileData)) { await addToVariables(k, v, 24, isDotEnvFormat); } } for (const varObj of Object.values(variables)) { varObj.environments.sort((a, b) => b.scopePriority - a.scopePriority); varObj.environments.sort((a, b) => b.regexpPriority - a.regexpPriority); } return variables; } static normalizeProjectKey(key, writeStreams) { if (!key.includes(":")) return key; writeStreams.stderr(chalk `{yellow WARNING: Interpreting '${key}' as '${key.replace(":", "/")}'}\n`); return key.replace(":", "/"); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaWFibGVzLWZyb20tZmlsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2YXJpYWJsZXMtZnJvbS1maWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDMUIsT0FBTyxLQUFLLElBQUksTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBRTFCLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ2pDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQWE1QixNQUFNLE9BQU8sa0JBQWtCO0lBRTNCLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFFLElBQVUsRUFBRSxZQUEwQixFQUFFLE9BQWdCO1FBQ3ZFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDckIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUMvQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzFCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDN0MsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUMzQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsT0FBTyxJQUFJLFFBQVEsZ0JBQWdCLENBQUM7UUFDakUsTUFBTSxTQUFTLEdBQW1DLEVBQUUsQ0FBQztRQUNyRCxJQUFJLGNBQWMsR0FBUSxFQUFFLENBQUM7UUFDN0IsSUFBSSxZQUFZLEdBQVEsRUFBRSxDQUFDO1FBRTNCLElBQUksZUFBZSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDckMsTUFBTSxLQUFLLEdBQUcseUNBQXlDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlFLE1BQU0sQ0FBQyxLQUFLLElBQUksSUFBSSxFQUFFLDZH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LENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7V3JpdGVTdHJlYW1zfSBmcm9tIFwiLi93cml0ZS1zdHJlYW1zLmpzXCI7XG5pbXBvcnQge0dpdERhdGF9IGZyb20gXCIuL2dpdC1kYXRhLmpzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzLWV4dHJhXCI7XG5pbXBvcnQgKiBhcyB5YW1sIGZyb20gXCJqcy15YW1sXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQge0FyZ3Z9IGZyb20gXCIuL2FyZ3YuanNcIjtcbmltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHtVdGlsc30gZnJvbSBcIi4vdXRpbHMuanNcIjtcbmltcG9ydCBkb3RlbnYgZnJvbSBcImRvdGVudlwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIENJQ0RWYXJpYWJsZSB7XG4gICAgdHlwZTogXCJmaWxlXCIgfCBcInZhcmlhYmxlXCI7XG4gICAgZW52aXJvbm1lbnRzOiB7XG4gICAgICAgIGNvbnRlbnQ6IHN0cmluZztcbiAgICAgICAgcmVnZXhwOiBSZWdFeHA7XG4gICAgICAgIHJlZ2V4cFByaW9yaXR5OiBudW1iZXI7XG4gICAgICAgIHNjb3BlUHJpb3JpdHk6IG51bWJlcjtcbiAgICAgICAgZmlsZVNvdXJjZT86IHN0cmluZztcbiAgICB9W107XG59XG5cbmV4cG9ydCBjbGFzcyBWYXJpYWJsZXNGcm9tRmlsZXMge1xuXG4gICAgc3RhdGljIGFzeW5jIGluaXQgKGFyZ3Y6IEFyZ3YsIHdyaXRlU3RyZWFtczogV3JpdGVTdHJlYW1zLCBnaXREYXRhOiBHaXREYXRhKTogUHJvbWlzZTx7W25hbWU6IHN0cmluZ106IENJQ0RWYXJpYWJsZX0+IHtcbiAgICAgICAgY29uc3QgY3dkID0gYXJndi5jd2Q7XG4gICAgICAgIGNvbnN0IHN0YXRlRGlyID0gYXJndi5zdGF0ZURpcjtcbiAgICAgICAgY29uc3QgaG9tZURpciA9IGFyZ3YuaG9tZTtcbiAgICAgICAgY29uc3QgcmVtb3RlVmFyaWFibGVzID0gYXJndi5yZW1vdGVWYXJpYWJsZXM7XG4gICAgICAgIGNvbnN0IGF1dG9Db21wbGV0aW5nID0gYXJndi5hdXRvQ29tcGxldGluZztcbiAgICAgICAgY29uc3QgaG9tZVZhcmlhYmxlc0ZpbGUgPSBgJHtob21lRGlyfS8ke3N0YXRlRGlyfS92YXJpYWJsZXMueW1sYDtcbiAgICAgICAgY29uc3QgdmFyaWFibGVzOiB7W25hbWU6IHN0cmluZ106IENJQ0RWYXJpYWJsZX0gPSB7fTtcbiAgICAgICAgbGV0IHJlbW90ZUZpbGVEYXRhOiBhbnkgPSB7fTtcbiAgICAgICAgbGV0IGhvbWVGaWxlRGF0YTogYW55ID0ge307XG5cbiAgICAgICAgaWYgKHJlbW90ZVZhcmlhYmxlcyAmJiAhYXV0b0NvbXBsZXRpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gLyg/PHVybD5naXRALio/KT0oPzxmaWxlPi4qPyk9KD88cmVmPi4qKS8uZXhlYyhyZW1vdGVWYXJpYWJsZXMpO1xuICAgICAgICAgICAgYXNzZXJ0KG1hdGNoICE9IG51bGwsIFwiLS1yZW1vdGUtdmFyaWFibGVzIGlzIG1hbGZvcm1lZCB1c2UgJ2dpdEBnaXRsYWIuY29tOmZpcmVjb3cvZXhhbXBsZS5naXQ9Z2l0bGFiLXZhcmlhYmxlcy55bWw9bWFzdGVyJyBzeW50YXhcIik7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBtYXRjaC5ncm91cHM/LnVybDtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBtYXRjaC5ncm91cHM/LmZpbGU7XG4gICAgICAgICAgICBjb25zdCByZWYgPSBtYXRjaC5ncm91cHM/LnJlZjtcbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IFV0aWxzLmJhc2goYHNldCAtZW91IHBpcGVmYWlsOyBnaXQgYXJjaGl2ZSAtLXJlbW90ZT0ke3VybH0gJHtyZWZ9ICR7ZmlsZX0gfCB0YXIgLXhPICR7ZmlsZX1gLCBjd2QpO1xuICAgICAgICAgICAgcmVtb3RlRmlsZURhdGEgPSB5YW1sLmxvYWQoYCR7cmVzLnN0ZG91dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhd2FpdCBmcy5wYXRoRXhpc3RzKGhvbWVWYXJpYWJsZXNGaWxlKSkge1xuICAgICAgICAgICAgaG9tZUZpbGVEYXRhID0geWFtbC5sb2FkKGF3YWl0IGZzLnJlYWRGaWxlKGhvbWVWYXJpYWJsZXNGaWxlLCBcInV0ZjhcIiksIHtzY2hlbWE6IHlhbWwuRkFJTFNBRkVfU0NIRU1BfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1bnBhY2sgPSAodjogYW55KToge3ZhbHVlczogYW55OyB0eXBlOiBcImZpbGVcIiB8IFwidmFyaWFibGVcIiB8IG51bGx9ID0+IHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhdGNoQWxsOiB7dmFsdWVzOiBhbnk7IHR5cGU6IFwiZmlsZVwiIHwgXCJ2YXJpYWJsZVwiIHwgbnVsbH0gPSB7dmFsdWVzOiB7fSwgdHlwZTogbnVsbH07XG4gICAgICAgICAgICAgICAgY2F0Y2hBbGwudmFsdWVzID0ge307XG4gICAgICAgICAgICAgICAgY2F0Y2hBbGwudmFsdWVzW1wiKlwiXSA9IHY7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhdGNoQWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2LnR5cGUgPSB2LnR5cGUgPz8gXCJ2YXJpYWJsZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFkZFRvVmFyaWFibGVzID0gYXN5bmMgKGtleTogc3RyaW5nLCB2YWw6IGFueSwgc2NvcGVQcmlvcml0eTogbnVtYmVyLCBpc0RvdEVudiA9IGZhbHNlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7dHlwZSwgdmFsdWVzfSA9IHVucGFjayh2YWwpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBbbWF0Y2hlciwgY29udGVudF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWVzKSkge1xuICAgICAgICAgICAgICAgIGFzc2VydCh0eXBlb2YgY29udGVudCA9PSBcInN0cmluZ1wiLCBgJHtrZXl9LiR7bWF0Y2hlcn0gY29udGVudCBtdXN0IGJlIHRleHQgb3IgbXVsdGlsaW5lIHRleHRgKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNEb3RFbnYgfHwgdHlwZSA9PT0gXCJ2YXJpYWJsZVwiIHx8ICh0eXBlID09PSBudWxsICYmICEvXlsvfl0vLmV4ZWMoY29udGVudCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4cCA9IG1hdGNoZXIgPT09IFwiKlwiID8gLy4qL2cgOiBuZXcgUmVnRXhwKGBeJHttYXRjaGVyLnJlcGxhY2UoL1xcKi9nLCBcIi4qXCIpfSRgLCBcImdcIik7XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlc1trZXldID0gdmFyaWFibGVzW2tleV0gPz8ge3R5cGU6IFwidmFyaWFibGVcIiwgZW52aXJvbm1lbnRzOiBbXX07XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlc1trZXldLmVudmlyb25tZW50cy5wdXNoKHtjb250ZW50LCByZWdleHAsIHJlZ2V4cFByaW9yaXR5OiBtYXRjaGVyLmxlbmd0aCwgc2NvcGVQcmlvcml0eX0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gbnVsbCAmJiAvXlsvfl0vLmV4ZWMoY29udGVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZVNvdXJjZSA9IGNvbnRlbnQucmVwbGFjZSgvXn5cXC8oLiopLywgYCR7aG9tZURpcn0vJDFgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVnZXhwID0gbWF0Y2hlciA9PT0gXCIqXCIgPyAvLiovZyA6IG5ldyBSZWdFeHAoYF4ke21hdGNoZXIucmVwbGFjZSgvXFwqL2csIFwiLipcIil9JGAsIFwiZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzW2tleV0gPSB2YXJpYWJsZXNba2V5XSA/PyB7dHlwZTogXCJmaWxlXCIsIGVudmlyb25tZW50czogW119O1xuICAgICAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhmaWxlU291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzW2tleV0uZW52aXJvbm1lbnRzLnB1c2goe2NvbnRlbnQsIHJlZ2V4cCwgcmVnZXhwUHJpb3JpdHk6IG1hdGNoZXIubGVuZ3RoLCBzY29wZVByaW9yaXR5LCBmaWxlU291cmNlfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXNba2V5XS5lbnZpcm9ubWVudHMucHVzaCh7Y29udGVudDogYHdhcm46ICR7a2V5fSBpcyBwb2ludGluZyB0byBpbnZhbGlkIHBhdGhcXG5gLCByZWdleHAsIHJlZ2V4cFByaW9yaXR5OiBtYXRjaGVyLmxlbmd0aCwgc2NvcGVQcmlvcml0eX0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWdleHAgPSBtYXRjaGVyID09PSBcIipcIiA/IC8uKi9nIDogbmV3IFJlZ0V4cChgXiR7bWF0Y2hlci5yZXBsYWNlKC9cXCovZywgXCIuKlwiKX0kYCwgXCJnXCIpO1xuICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXNba2V5XSA9IHZhcmlhYmxlc1trZXldID8/IHt0eXBlOiBcImZpbGVcIiwgZW52aXJvbm1lbnRzOiBbXX07XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlc1trZXldLmVudmlyb25tZW50cy5wdXNoKHtjb250ZW50LCByZWdleHAsIHJlZ2V4cFByaW9yaXR5OiBtYXRjaGVyLmxlbmd0aCwgc2NvcGVQcmlvcml0eX0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFzc2VydChmYWxzZSwgYCR7a2V5fSB3YXMgbm90IGhhbmRsZWQgcHJvcGVybHlgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYWRkVmFyaWFibGVGaWxlVG9WYXJpYWJsZXMgPSBhc3luYyAoZmlsZURhdGE6IGFueSwgZmlsZVByaW9yaXR5OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2dsb2JhbEtleSwgZ2xvYmFsRW50cnldIG9mIE9iamVjdC5lbnRyaWVzKGZpbGVEYXRhPy5nbG9iYWwgPz8ge30pKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgYWRkVG9WYXJpYWJsZXMoZ2xvYmFsS2V5LCBnbG9iYWxFbnRyeSwgMSArIGZpbGVQcmlvcml0eSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGdyb3VwVXJsID0gYCR7Z2l0RGF0YS5yZW1vdGUuaG9zdH0vJHtnaXREYXRhLnJlbW90ZS5ncm91cH0vYDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2dyb3VwS2V5LCBncm91cEVudHJpZXNdIG9mIE9iamVjdC5lbnRyaWVzKGZpbGVEYXRhPy5ncm91cCA/PyB7fSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWdyb3VwVXJsLmluY2x1ZGVzKHRoaXMubm9ybWFsaXplUHJvamVjdEtleShncm91cEtleSwgd3JpdGVTdHJlYW1zKSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGFzc2VydChncm91cEVudHJpZXMgIT0gbnVsbCwgXCJncm91cEVudHJpZXMgY2Fubm90IGJlIG51bGwvdW5kZWZpbmVkXCIpO1xuICAgICAgICAgICAgICAgIGFzc2VydChVdGlscy5pc09iamVjdChncm91cEVudHJpZXMpLCBcImdyb3VwIGVudHJpZXMgaW4gdmFyaWFibGUgZmlsZXMgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaywgdl0gb2YgT2JqZWN0LmVudHJpZXMoZ3JvdXBFbnRyaWVzKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBhZGRUb1ZhcmlhYmxlcyhrLCB2LCAyICsgZmlsZVByaW9yaXR5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHByb2plY3RVcmwgPSBgJHtnaXREYXRhLnJlbW90ZS5ob3N0fS8ke2dpdERhdGEucmVtb3RlLmdyb3VwfS8ke2dpdERhdGEucmVtb3RlLnByb2plY3R9LmdpdGA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtwcm9qZWN0S2V5LCBwcm9qZWN0RW50cmllc10gb2YgT2JqZWN0LmVudHJpZXMoZmlsZURhdGE/LnByb2plY3QgPz8gW10pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwcm9qZWN0VXJsLmluY2x1ZGVzKHRoaXMubm9ybWFsaXplUHJvamVjdEtleShwcm9qZWN0S2V5LCB3cml0ZVN0cmVhbXMpKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHByb2plY3RFbnRyaWVzICE9IG51bGwsIFwicHJvamVjdEVudHJpZXMgY2Fubm90IGJlIG51bGwvdW5kZWZpbmVkXCIpO1xuICAgICAgICAgICAgICAgIGFzc2VydChVdGlscy5pc09iamVjdChwcm9qZWN0RW50cmllcyksIFwicHJvamVjdCBlbnRyaWVzIGluIHZhcmlhYmxlIGZpbGVzIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHByb2plY3RFbnRyaWVzKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBhZGRUb1ZhcmlhYmxlcyhrLCB2LCAzICsgZmlsZVByaW9yaXR5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYWRkVmFyaWFibGVGaWxlVG9WYXJpYWJsZXMocmVtb3RlRmlsZURhdGEsIDApO1xuICAgICAgICBhd2FpdCBhZGRWYXJpYWJsZUZpbGVUb1ZhcmlhYmxlcyhob21lRmlsZURhdGEsIDEwKTtcblxuICAgICAgICBjb25zdCBwcm9qZWN0VmFyaWFibGVzRmlsZSA9IGAke2FyZ3YuY3dkfS8ke2FyZ3YudmFyaWFibGVzRmlsZX1gO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhwcm9qZWN0VmFyaWFibGVzRmlsZSkpIHtcbiAgICAgICAgICAgIGxldCBpc0RvdEVudkZvcm1hdCA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgcHJvamVjdFZhcmlhYmxlc0ZpbGVSYXdDb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUocHJvamVjdFZhcmlhYmxlc0ZpbGUsIFwidXRmOFwiKTtcbiAgICAgICAgICAgIGxldCBwcm9qZWN0VmFyaWFibGVzRmlsZURhdGE7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHByb2plY3RWYXJpYWJsZXNGaWxlRGF0YSA9IHlhbWwubG9hZChwcm9qZWN0VmFyaWFibGVzRmlsZVJhd0NvbnRlbnQsIHtzY2hlbWE6IHlhbWwuRkFJTFNBRkVfU0NIRU1BfSkgPz8ge307XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mKHByb2plY3RWYXJpYWJsZXNGaWxlRGF0YSkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNEb3RFbnZGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0VmFyaWFibGVzRmlsZURhdGEgPSBkb3RlbnYucGFyc2UocHJvamVjdFZhcmlhYmxlc0ZpbGVSYXdDb250ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiB5YW1sLllBTUxFeGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaXNEb3RFbnZGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0VmFyaWFibGVzRmlsZURhdGEgPSBkb3RlbnYucGFyc2UocHJvamVjdFZhcmlhYmxlc0ZpbGVSYXdDb250ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhc3NlcnQocHJvamVjdFZhcmlhYmxlc0ZpbGVEYXRhICE9IG51bGwsIFwicHJvamVjdEVudHJpZXMgY2Fubm90IGJlIG51bGwvdW5kZWZpbmVkXCIpO1xuICAgICAgICAgICAgYXNzZXJ0KFV0aWxzLmlzT2JqZWN0KHByb2plY3RWYXJpYWJsZXNGaWxlRGF0YSksIGAke2FyZ3YuY3dkfS8uZ2l0bGFiLWNpLWxvY2FsLXZhcmlhYmxlcy55bWwgbXVzdCBjb250YWluIGFuIG9iamVjdGApO1xuICAgICAgICAgICAgZm9yIChjb25zdCBbaywgdl0gb2YgT2JqZWN0LmVudHJpZXMocHJvamVjdFZhcmlhYmxlc0ZpbGVEYXRhKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGFkZFRvVmFyaWFibGVzKGssIHYsIDI0LCBpc0RvdEVudkZvcm1hdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHZhck9iaiBvZiBPYmplY3QudmFsdWVzKHZhcmlhYmxlcykpIHtcbiAgICAgICAgICAgIHZhck9iai5lbnZpcm9ubWVudHMuc29ydCgoYSwgYikgPT4gYi5zY29wZVByaW9yaXR5IC0gYS5zY29wZVByaW9yaXR5KTtcbiAgICAgICAgICAgIHZhck9iai5lbnZpcm9ubWVudHMuc29ydCgoYSwgYikgPT4gYi5yZWdleHBQcmlvcml0eSAtIGEucmVnZXhwUHJpb3JpdHkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZhcmlhYmxlcztcbiAgICB9XG5cbiAgICBzdGF0aWMgbm9ybWFsaXplUHJvamVjdEtleSAoa2V5OiBzdHJpbmcsIHdyaXRlU3RyZWFtczogV3JpdGVTdHJlYW1zKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKCFrZXkuaW5jbHVkZXMoXCI6XCIpKSByZXR1cm4ga2V5O1xuICAgICAgICB3cml0ZVN0cmVhbXMuc3RkZXJyKGNoYWxrYHt5ZWxsb3cgV0FSTklORzogSW50ZXJwcmV0aW5nICcke2tleX0nIGFzICcke2tleS5yZXBsYWNlKFwiOlwiLCBcIi9cIil9J31cXG5gKTtcbiAgICAgICAgcmV0dXJuIGtleS5yZXBsYWNlKFwiOlwiLCBcIi9cIik7XG4gICAgfVxufVxuIl19