projen
Version:
CDK for software projects
138 lines • 20.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Uv = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const component_1 = require("../component");
const uv_config_1 = require("./uv-config");
const dependencies_1 = require("../dependencies");
const task_runtime_1 = require("../task-runtime");
const util_1 = require("../util");
const pyproject_toml_file_1 = require("./pyproject-toml-file");
/**
* Manage project dependencies, virtual environments, and packaging through uv.
*/
class Uv extends component_1.Component {
constructor(scope, options) {
super(scope);
const requiresPython = options.project?.requiresPython ?? ">=3.12,<4.0";
this.venvPython = options.pythonExec ?? requiresPython;
this.installTask = this.project.addTask("install", {
description: "Install dependencies and update lockfile",
exec: "uv sync && uv lock",
});
this.installCiTask = this.project.addTask("install:ci", {
description: "Install dependencies with frozen lockfile",
exec: "uv sync",
});
this.project.tasks.addEnvironment("VIRTUAL_ENV", ".venv");
this.project.tasks.addEnvironment("PATH", "$(echo .venv/bin:$PATH)");
this.project.packageTask.exec("uv build");
this.publishTestTask = this.project.addTask("publish:test", {
description: "Uploads the package against a test PyPI endpoint.",
exec: "uv publish --index testpypi",
});
this.publishTask = this.project.addTask("publish", {
description: "Uploads the package to PyPI.",
exec: "uv publish",
});
this.file = new pyproject_toml_file_1.PyprojectTomlFile(this.project, {
project: {
name: options.project?.name ?? this.project.name,
requiresPython,
...options.project,
dependencies: (() => [
...(options?.project?.dependencies ?? []),
...this.synthDependencies(),
]),
},
dependencyGroups: (() => this.synthDependencyGroups()),
buildSystem: options.buildSystem,
tool: {
uv: (0, uv_config_1.toJson_UvConfiguration)(options.uv),
},
});
}
/** Formats dependencies in UV style. */
formatDependency(dep) {
const name = dep.name;
const version = dep.version;
if (!version || version === "*") {
return name;
}
// Translate caret (^) to Python compatible constraints
if (version.startsWith("^")) {
const cleanVersion = version.slice(1);
const [major] = cleanVersion.split(".");
const nextMajor = Number(major) + 1;
return `${name}>=${cleanVersion},<${nextMajor}.0.0`;
}
// Translate tilde (~) to compatible release clause per PEP 440
if (version.startsWith("~")) {
const cleanVersion = version.slice(1);
// Only keep major.minor for tilde if possible
const [major, minor = "0", patch = "0"] = cleanVersion.split(".");
const nextMinor = Number(minor) + 1;
return `${name}>=${major}.${minor}.${patch},<${major}.${nextMinor}.0`;
}
// Otherwise treat as an exact version
return `${name}==${version}`;
}
getDependencies(dependencyTypes) {
return (this.project.deps.all
.filter((pkg) => dependencyTypes.includes(pkg.type) && pkg.name !== "python")
// remove duplicate versions of the same dependency
.filter((dep, index, self) => index === self.findIndex((d) => d.name === dep.name))
.map((pkg) => this.formatDependency(pkg)));
}
synthDependencies() {
return this.getDependencies([dependencies_1.DependencyType.RUNTIME]);
}
synthDependencyGroups() {
const devDeps = this.getDependencies([
dependencies_1.DependencyType.DEVENV,
dependencies_1.DependencyType.TEST,
]);
if (devDeps) {
return { dev: devDeps };
}
else {
return undefined;
}
}
addDependency(spec) {
this.project.deps.addDependency(spec, dependencies_1.DependencyType.RUNTIME);
}
addDevDependency(spec) {
this.project.deps.addDependency(spec, dependencies_1.DependencyType.DEVENV);
}
setupEnvironment() {
const result = (0, util_1.execOrUndefined)("which uv", {
cwd: this.project.outdir,
});
if (!result) {
this.project.logger.info("Unable to setup an environment since uv is not installed. Please install uv (https://github.com/astral-sh/uv) or use a different component for managing environments.");
return;
}
// Create venv with the specific Python version
// this will install the requested python version if needed
(0, util_1.exec)(`uv venv --python "${this.venvPython}" --clear .venv`, {
cwd: this.project.outdir,
});
this.project.logger.info(`Environment successfully created in .venv directory with Python ${this.venvPython}.`);
}
installDependencies() {
this.project.logger.info("Installing dependencies...");
const runtime = new task_runtime_1.TaskRuntime(this.project.outdir);
if (this.file.changed) {
runtime.runTask(this.installTask.name);
}
else {
runtime.runTask(this.installCiTask.name);
}
}
}
exports.Uv = Uv;
_a = JSII_RTTI_SYMBOL_1;
Uv[_a] = { fqn: "projen.python.Uv", version: "0.99.19" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHl0aG9uL3V2LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBSUEsNENBQXlDO0FBQ3pDLDJDQUFzRTtBQUN0RSxrREFBNkQ7QUFFN0Qsa0RBQThDO0FBQzlDLGtDQUFnRDtBQUVoRCwrREFBMEQ7QUF5QjFEOztHQUVHO0FBQ0gsTUFBYSxFQUNYLFNBQVEscUJBQVM7SUFjakIsWUFBWSxLQUFpQixFQUFFLE9BQWtCO1FBQy9DLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsY0FBYyxJQUFJLGFBQWEsQ0FBQztRQUN4RSxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLElBQUksY0FBYyxDQUFDO1FBRXZELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ2pELFdBQVcsRUFBRSwwQ0FBMEM7WUFDdkQsSUFBSSxFQUFFLG9CQUFvQjtTQUMzQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRTtZQUN0RCxXQUFXLEVBQUUsMkNBQTJDO1lBQ3hELElBQUksRUFBRSxTQUFTO1NBQ2hCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1FBRXJFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUUxQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENB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IjtcbmltcG9ydCB7IElQeXRob25EZXBzIH0gZnJvbSBcIi4vcHl0aG9uLWRlcHNcIjtcbmltcG9ydCB7IElQeXRob25FbnYgfSBmcm9tIFwiLi9weXRob24tZW52XCI7XG5pbXBvcnQgeyBJUHl0aG9uUGFja2FnaW5nIH0gZnJvbSBcIi4vcHl0aG9uLXBhY2thZ2luZ1wiO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NvbXBvbmVudFwiO1xuaW1wb3J0IHsgdG9Kc29uX1V2Q29uZmlndXJhdGlvbiwgVXZDb25maWd1cmF0aW9uIH0gZnJvbSBcIi4vdXYtY29uZmlnXCI7XG5pbXBvcnQgeyBEZXBlbmRlbmN5LCBEZXBlbmRlbmN5VHlwZSB9IGZyb20gXCIuLi9kZXBlbmRlbmNpZXNcIjtcbmltcG9ydCB7IFRhc2sgfSBmcm9tIFwiLi4vdGFza1wiO1xuaW1wb3J0IHsgVGFza1J1bnRpbWUgfSBmcm9tIFwiLi4vdGFzay1ydW50aW1lXCI7XG5pbXBvcnQgeyBleGVjLCBleGVjT3JVbmRlZmluZWQgfSBmcm9tIFwiLi4vdXRpbFwiO1xuaW1wb3J0IHsgQnVpbGRTeXN0ZW0sIFB5cHJvamVjdFRvbWxQcm9qZWN0IH0gZnJvbSBcIi4vcHlwcm9qZWN0LXRvbWxcIjtcbmltcG9ydCB7IFB5cHJvamVjdFRvbWxGaWxlIH0gZnJvbSBcIi4vcHlwcm9qZWN0LXRvbWwtZmlsZVwiO1xuaW1wb3J0IHsgUHl0aG9uRXhlY3V0YWJsZU9wdGlvbnMgfSBmcm9tIFwiLi9weXRob24tcHJvamVjdFwiO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIFVWIHByb2plY3RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVdk9wdGlvbnMgZXh0ZW5kcyBQeXRob25FeGVjdXRhYmxlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgcHJvamVjdCdzIGJhc2ljIG1ldGFkYXRhIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBwcm9qZWN0PzogUHlwcm9qZWN0VG9tbFByb2plY3Q7XG5cbiAgLyoqXG4gICAqIERlY2xhcmVzIGFueSBQeXRob24gbGV2ZWwgZGVwZW5kZW5jaWVzIHRoYXQgbXVzdCBiZSBpbnN0YWxsZWQgaW4gb3JkZXIgdG8gcnVuIHRoZSBwcm9qZWN04oCZcyBidWlsZCBzeXN0ZW0gc3VjY2Vzc2Z1bGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGJ1aWxkIHN5c3RlbVxuICAgKi9cbiAgcmVhZG9ubHkgYnVpbGRTeXN0ZW0/OiBCdWlsZFN5c3RlbTtcblxuICAvKipcbiAgICogVGhlIGNvbmZpZ3VyYXRpb24gYW5kIG1ldGFkYXRhIGZvciB1di5cbiAgICovXG4gIHJlYWRvbmx5IHV2PzogVXZDb25maWd1cmF0aW9uO1xufVxuXG4vKipcbiAqIE1hbmFnZSBwcm9qZWN0IGRlcGVuZGVuY2llcywgdmlydHVhbCBlbnZpcm9ubWVudHMsIGFuZCBwYWNrYWdpbmcgdGhyb3VnaCB1di5cbiAqL1xuZXhwb3J0IGNsYXNzIFV2XG4gIGV4dGVuZHMgQ29tcG9uZW50XG4gIGltcGxlbWVudHMgSVB5dGhvbkRlcHMsIElQeXRob25FbnYsIElQeXRob25QYWNrYWdpbmdcbntcbiAgLyoqXG4gICAqIFRoZSBgcHlwcm9qZWN0LnRvbWxgIGZpbGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBmaWxlOiBQeXByb2plY3RUb21sRmlsZTtcbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbGxUYXNrOiBUYXNrO1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFsbENpVGFzazogVGFzaztcbiAgcHVibGljIHJlYWRvbmx5IHB1Ymxpc2hUYXNrOiBUYXNrO1xuICBwdWJsaWMgcmVhZG9ubHkgcHVibGlzaFRlc3RUYXNrOiBUYXNrO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmVudlB5dGhvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBvcHRpb25zOiBVdk9wdGlvbnMpIHtcbiAgICBzdXBlcihzY29wZSk7XG5cbiAgICBjb25zdCByZXF1aXJlc1B5dGhvbiA9IG9wdGlvbnMucHJvamVjdD8ucmVxdWlyZXNQeXRob24gPz8gXCI+PTMuMTIsPDQuMFwiO1xuICAgIHRoaXMudmVudlB5dGhvbiA9IG9wdGlvbnMucHl0aG9uRXhlYyA/PyByZXF1aXJlc1B5dGhvbjtcblxuICAgIHRoaXMuaW5zdGFsbFRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcImluc3RhbGxcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXMgYW5kIHVwZGF0ZSBsb2NrZmlsZVwiLFxuICAgICAgZXhlYzogXCJ1diBzeW5jICYmIHV2IGxvY2tcIixcbiAgICB9KTtcblxuICAgIHRoaXMuaW5zdGFsbENpVGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwiaW5zdGFsbDpjaVwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJJbnN0YWxsIGRlcGVuZGVuY2llcyB3aXRoIGZyb3plbiBsb2NrZmlsZVwiLFxuICAgICAgZXhlYzogXCJ1diBzeW5jXCIsXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2plY3QudGFza3MuYWRkRW52aXJvbm1lbnQoXCJWSVJUVUFMX0VOVlwiLCBcIi52ZW52XCIpO1xuICAgIHRoaXMucHJvamVjdC50YXNrcy5hZGRFbnZpcm9ubWVudChcIlBBVEhcIiwgXCIkKGVjaG8gLnZlbnYvYmluOiRQQVRIKVwiKTtcblxuICAgIHRoaXMucHJvamVjdC5wYWNrYWdlVGFzay5leGVjKFwidXYgYnVpbGRcIik7XG5cbiAgICB0aGlzLnB1Ymxpc2hUZXN0VGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwicHVibGlzaDp0ZXN0XCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlVwbG9hZHMgdGhlIHBhY2thZ2UgYWdhaW5zdCBhIHRlc3QgUHlQSSBlbmRwb2ludC5cIixcbiAgICAgIGV4ZWM6IFwidXYgcHVibGlzaCAtLWluZGV4IHRlc3RweXBpXCIsXG4gICAgfSk7XG5cbiAgICB0aGlzLnB1Ymxpc2hUYXNrID0gdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJwdWJsaXNoXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlVwbG9hZHMgdGhlIHBhY2thZ2UgdG8gUHlQSS5cIixcbiAgICAgIGV4ZWM6IFwidXYgcHVibGlzaFwiLFxuICAgIH0pO1xuXG4gICAgdGhpcy5maWxlID0gbmV3IFB5cHJvamVjdFRvbWxGaWxlKHRoaXMucHJvamVjdCwge1xuICAgICAgcHJvamVjdDoge1xuICAgICAgICBuYW1lOiBvcHRpb25zLnByb2plY3Q/Lm5hbWUgPz8gdGhpcy5wcm9qZWN0Lm5hbWUsXG4gICAgICAgIHJlcXVpcmVzUHl0aG9uLFxuICAgICAgICAuLi5vcHRpb25zLnByb2plY3QsXG4gICAgICAgIGRlcGVuZGVuY2llczogKCgpID0+IFtcbiAgICAgICAgICAuLi4ob3B0aW9ucz8ucHJvamVjdD8uZGVwZW5kZW5jaWVzID8/IFtdKSxcbiAgICAgICAgICAuLi50aGlzLnN5bnRoRGVwZW5kZW5jaWVzKCksXG4gICAgICAgIF0pIGFzIGFueSxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmN5R3JvdXBzOiAoKCkgPT4gdGhpcy5zeW50aERlcGVuZGVuY3lHcm91cHMoKSkgYXMgYW55LFxuICAgICAgYnVpbGRTeXN0ZW06IG9wdGlvbnMuYnVpbGRTeXN0ZW0sXG4gICAgICB0b29sOiB7XG4gICAgICAgIHV2OiB0b0pzb25fVXZDb25maWd1cmF0aW9uKG9wdGlvbnMudXYpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBGb3JtYXRzIGRlcGVuZGVuY2llcyBpbiBVViBzdHlsZS4gKi9cbiAgcHJpdmF0ZSBmb3JtYXREZXBlbmRlbmN5KGRlcDogRGVwZW5kZW5jeSk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IGRlcC5uYW1lO1xuICAgIGNvbnN0IHZlcnNpb24gPSBkZXAudmVyc2lvbjtcblxuICAgIGlmICghdmVyc2lvbiB8fCB2ZXJzaW9uID09PSBcIipcIikge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNsYXRlIGNhcmV0ICheKSB0byBQeXRob24gY29tcGF0aWJsZSBjb25zdHJhaW50c1xuICAgIGlmICh2ZXJzaW9uLnN0YXJ0c1dpdGgoXCJeXCIpKSB7XG4gICAgICBjb25zdCBjbGVhblZlcnNpb24gPSB2ZXJzaW9uLnNsaWNlKDEpO1xuICAgICAgY29uc3QgW21ham9yXSA9IGNsZWFuVmVyc2lvbi5zcGxpdChcIi5cIik7XG4gICAgICBjb25zdCBuZXh0TWFqb3IgPSBOdW1iZXIobWFqb3IpICsgMTtcbiAgICAgIHJldHVybiBgJHtuYW1lfT49JHtjbGVhblZlcnNpb259LDwke25leHRNYWpvcn0uMC4wYDtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2xhdGUgdGlsZGUgKH4pIHRvIGNvbXBhdGlibGUgcmVsZWFzZSBjbGF1c2UgcGVyIFBFUCA0NDBcbiAgICBpZiAodmVyc2lvbi5zdGFydHNXaXRoKFwiflwiKSkge1xuICAgICAgY29uc3QgY2xlYW5WZXJzaW9uID0gdmVyc2lvbi5zbGljZSgxKTtcblxuICAgICAgLy8gT25seSBrZWVwIG1ham9yLm1pbm9yIGZvciB0aWxkZSBpZiBwb3NzaWJsZVxuICAgICAgY29uc3QgW21ham9yLCBtaW5vciA9IFwiMFwiLCBwYXRjaCA9IFwiMFwiXSA9IGNsZWFuVmVyc2lvbi5zcGxpdChcIi5cIik7XG4gICAgICBjb25zdCBuZXh0TWlub3IgPSBOdW1iZXIobWlub3IpICsgMTtcbiAgICAgIHJldHVybiBgJHtuYW1lfT49JHttYWpvcn0uJHttaW5vcn0uJHtwYXRjaH0sPCR7bWFqb3J9LiR7bmV4dE1pbm9yfS4wYDtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UgdHJlYXQgYXMgYW4gZXhhY3QgdmVyc2lvblxuICAgIHJldHVybiBgJHtuYW1lfT09JHt2ZXJzaW9ufWA7XG4gIH1cblxuICBwcml2YXRlIGdldERlcGVuZGVuY2llcyhkZXBlbmRlbmN5VHlwZXM6IERlcGVuZGVuY3lUeXBlW10pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMucHJvamVjdC5kZXBzLmFsbFxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChwa2cpID0+IGRlcGVuZGVuY3lUeXBlcy5pbmNsdWRlcyhwa2cudHlwZSkgJiYgcGtnLm5hbWUgIT09IFwicHl0aG9uXCIsXG4gICAgICAgIClcbiAgICAgICAgLy8gcmVtb3ZlIGR1cGxpY2F0ZSB2ZXJzaW9ucyBvZiB0aGUgc2FtZSBkZXBlbmRlbmN5XG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGRlcCwgaW5kZXgsIHNlbGYpID0+XG4gICAgICAgICAgICBpbmRleCA9PT0gc2VsZi5maW5kSW5kZXgoKGQpID0+IGQubmFtZSA9PT0gZGVwLm5hbWUpLFxuICAgICAgICApXG4gICAgICAgIC5tYXAoKHBrZykgPT4gdGhpcy5mb3JtYXREZXBlbmRlbmN5KHBrZykpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3ludGhEZXBlbmRlbmNpZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmdldERlcGVuZGVuY2llcyhbRGVwZW5kZW5jeVR5cGUuUlVOVElNRV0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW50aERlcGVuZGVuY3lHcm91cHMoKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBkZXZEZXBzID0gdGhpcy5nZXREZXBlbmRlbmNpZXMoW1xuICAgICAgRGVwZW5kZW5jeVR5cGUuREVWRU5WLFxuICAgICAgRGVwZW5kZW5jeVR5cGUuVEVTVCxcbiAgICBdKTtcblxuICAgIGlmIChkZXZEZXBzKSB7XG4gICAgICByZXR1cm4geyBkZXY6IGRldkRlcHMgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYWRkRGVwZW5kZW5jeShzcGVjOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnByb2plY3QuZGVwcy5hZGREZXBlbmRlbmN5KHNwZWMsIERlcGVuZGVuY3lUeXBlLlJVTlRJTUUpO1xuICB9XG5cbiAgcHVibGljIGFkZERldkRlcGVuZGVuY3koc3BlYzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5wcm9qZWN0LmRlcHMuYWRkRGVwZW5kZW5jeShzcGVjLCBEZXBlbmRlbmN5VHlwZS5ERVZFTlYpO1xuICB9XG5cbiAgcHVibGljIHNldHVwRW52aXJvbm1lbnQoKTogdm9pZCB7XG4gICAgY29uc3QgcmVzdWx0ID0gZXhlY09yVW5kZWZpbmVkKFwid2hpY2ggdXZcIiwge1xuICAgICAgY3dkOiB0aGlzLnByb2plY3Qub3V0ZGlyLFxuICAgIH0pO1xuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLmluZm8oXG4gICAgICAgIFwiVW5hYmxlIHRvIHNldHVwIGFuIGVudmlyb25tZW50IHNpbmNlIHV2IGlzIG5vdCBpbnN0YWxsZWQuIFBsZWFzZSBpbnN0YWxsIHV2IChodHRwczovL2dpdGh1Yi5jb20vYXN0cmFsLXNoL3V2KSBvciB1c2UgYSBkaWZmZXJlbnQgY29tcG9uZW50IGZvciBtYW5hZ2luZyBlbnZpcm9ubWVudHMuXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSB2ZW52IHdpdGggdGhlIHNwZWNpZmljIFB5dGhvbiB2ZXJzaW9uXG4gICAgLy8gdGhpcyB3aWxsIGluc3RhbGwgdGhlIHJlcXVlc3RlZCBweXRob24gdmVyc2lvbiBpZiBuZWVkZWRcbiAgICBleGVjKGB1diB2ZW52IC0tcHl0aG9uIFwiJHt0aGlzLnZlbnZQeXRob259XCIgLS1jbGVhciAudmVudmAsIHtcbiAgICAgIGN3ZDogdGhpcy5wcm9qZWN0Lm91dGRpcixcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QubG9nZ2VyLmluZm8oXG4gICAgICBgRW52aXJvbm1lbnQgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgaW4gLnZlbnYgZGlyZWN0b3J5IHdpdGggUHl0aG9uICR7dGhpcy52ZW52UHl0aG9ufS5gLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgaW5zdGFsbERlcGVuZGVuY2llcygpOiB2b2lkIHtcbiAgICB0aGlzLnByb2plY3QubG9nZ2VyLmluZm8oXCJJbnN0YWxsaW5nIGRlcGVuZGVuY2llcy4uLlwiKTtcbiAgICBjb25zdCBydW50aW1lID0gbmV3IFRhc2tSdW50aW1lKHRoaXMucHJvamVjdC5vdXRkaXIpO1xuICAgIGlmICh0aGlzLmZpbGUuY2hhbmdlZCkge1xuICAgICAgcnVudGltZS5ydW5UYXNrKHRoaXMuaW5zdGFsbFRhc2submFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJ1bnRpbWUucnVuVGFzayh0aGlzLmluc3RhbGxDaVRhc2submFtZSk7XG4gICAgfVxuICB9XG59XG4iXX0=