UNPKG

projen

Version:

CDK for software projects

143 lines • 21.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Uv = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const pyproject_toml_file_1 = require("./pyproject-toml-file"); const component_1 = require("../component"); const uv_config_1 = require("./uv-config"); const dependencies_1 = require("../dependencies"); const exec_1 = require("../util/exec"); /** * Manage project dependencies, virtual environments, and packaging through uv. */ class Uv extends component_1.Component { static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.python.Uv", version: "0.103.12" }; /** * The `pyproject.toml` file */ file; installTask; installCiTask; publishTask; publishTestTask; venvPython; 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", steps: [{ execArgs: ["uv", "sync"] }, { execArgs: ["uv", "lock"] }], }); this.installCiTask = this.project.addTask("install:ci", { description: "Install dependencies with frozen lockfile", execArgs: ["uv", "sync"], }); this.project.tasks.addEnvironment("VIRTUAL_ENV", ".venv"); this.project.tasks.addEnvironment("PATH", "$(echo .venv/bin:$PATH)"); this.project.packageTask.execArgs(["uv", "build"]); this.publishTestTask = this.project.addTask("publish:test", { description: "Uploads the package against a test PyPI endpoint.", execArgs: ["uv", "publish", "--index", "testpypi"], }); this.publishTask = this.project.addTask("publish", { description: "Uploads the package to PyPI.", execArgs: ["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 = exec_1.uv.tryCapture(["--version"], { 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 exec_1.uv.run(["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..."); if (this.file.changed) { this.project.tasks.runTask(this.installTask.name); } else { this.project.tasks.runTask(this.installCiTask.name); } } } exports.Uv = Uv; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHl0aG9uL3V2LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFFQSwrREFBMEQ7QUFJMUQsNENBQXlDO0FBR3pDLDJDQUFxRDtBQUVyRCxrREFBaUQ7QUFFakQsdUNBQWtDO0FBd0JsQzs7R0FFRztBQUNILE1BQWEsRUFDWCxTQUFRLHFCQUFTOztJQUdqQjs7T0FFRztJQUNhLElBQUksQ0FBb0I7SUFDeEIsV0FBVyxDQUFPO0lBQ2xCLGFBQWEsQ0FBTztJQUNwQixXQUFXLENBQU87SUFDbEIsZUFBZSxDQUFPO0lBRXJCLFVBQVUsQ0FBUztJQUVwQyxZQUFZLEtBQWlCLEVBQUUsT0FBa0I7UUFDL0MsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxjQUFjLElBQUksYUFBYSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsSUFBSSxjQUFjLENBQUM7UUFFdkQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDakQsV0FBVyxFQUFFLDBDQUEwQztZQUN2RCxLQUFLLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7U0FDcEUsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUU7WUFDdEQsV0FBVyxFQUFFLDJDQUEyQztZQUN4RCxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO1NBQ3pCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFD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SSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BELENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7O0FBbktILGdCQW9LQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgdHlwZSB7IEJ1aWxkU3lzdGVtLCBQeXByb2plY3RUb21sUHJvamVjdCB9IGZyb20gXCIuL3B5cHJvamVjdC10b21sXCI7XG5pbXBvcnQgeyBQeXByb2plY3RUb21sRmlsZSB9IGZyb20gXCIuL3B5cHJvamVjdC10b21sLWZpbGVcIjtcbmltcG9ydCB0eXBlIHsgSVB5dGhvbkRlcHMgfSBmcm9tIFwiLi9weXRob24tZGVwc1wiO1xuaW1wb3J0IHR5cGUgeyBJUHl0aG9uRW52IH0gZnJvbSBcIi4vcHl0aG9uLWVudlwiO1xuaW1wb3J0IHR5cGUgeyBJUHl0aG9uUGFja2FnaW5nIH0gZnJvbSBcIi4vcHl0aG9uLXBhY2thZ2luZ1wiO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NvbXBvbmVudFwiO1xuaW1wb3J0IHR5cGUgeyBQeXRob25FeGVjdXRhYmxlT3B0aW9ucyB9IGZyb20gXCIuL3B5dGhvbi1wcm9qZWN0XCI7XG5pbXBvcnQgdHlwZSB7IFV2Q29uZmlndXJhdGlvbiB9IGZyb20gXCIuL3V2LWNvbmZpZ1wiO1xuaW1wb3J0IHsgdG9Kc29uX1V2Q29uZmlndXJhdGlvbiB9IGZyb20gXCIuL3V2LWNvbmZpZ1wiO1xuaW1wb3J0IHR5cGUgeyBEZXBlbmRlbmN5IH0gZnJvbSBcIi4uL2RlcGVuZGVuY2llc1wiO1xuaW1wb3J0IHsgRGVwZW5kZW5jeVR5cGUgfSBmcm9tIFwiLi4vZGVwZW5kZW5jaWVzXCI7XG5pbXBvcnQgdHlwZSB7IFRhc2sgfSBmcm9tIFwiLi4vdGFza1wiO1xuaW1wb3J0IHsgdXYgfSBmcm9tIFwiLi4vdXRpbC9leGVjXCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgVVYgcHJvamVjdFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFV2T3B0aW9ucyBleHRlbmRzIFB5dGhvbkV4ZWN1dGFibGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBwcm9qZWN0J3MgYmFzaWMgbWV0YWRhdGEgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3Q/OiBQeXByb2plY3RUb21sUHJvamVjdDtcblxuICAvKipcbiAgICogRGVjbGFyZXMgYW55IFB5dGhvbiBsZXZlbCBkZXBlbmRlbmNpZXMgdGhhdCBtdXN0IGJlIGluc3RhbGxlZCBpbiBvcmRlciB0byBydW4gdGhlIHByb2plY3TigJlzIGJ1aWxkIHN5c3RlbSBzdWNjZXNzZnVsbHkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYnVpbGQgc3lzdGVtXG4gICAqL1xuICByZWFkb25seSBidWlsZFN5c3RlbT86IEJ1aWxkU3lzdGVtO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBhbmQgbWV0YWRhdGEgZm9yIHV2LlxuICAgKi9cbiAgcmVhZG9ubHkgdXY/OiBVdkNvbmZpZ3VyYXRpb247XG59XG5cbi8qKlxuICogTWFuYWdlIHByb2plY3QgZGVwZW5kZW5jaWVzLCB2aXJ0dWFsIGVudmlyb25tZW50cywgYW5kIHBhY2thZ2luZyB0aHJvdWdoIHV2LlxuICovXG5leHBvcnQgY2xhc3MgVXZcbiAgZXh0ZW5kcyBDb21wb25lbnRcbiAgaW1wbGVtZW50cyBJUHl0aG9uRGVwcywgSVB5dGhvbkVudiwgSVB5dGhvblBhY2thZ2luZ1xue1xuICAvKipcbiAgICogVGhlIGBweXByb2plY3QudG9tbGAgZmlsZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGZpbGU6IFB5cHJvamVjdFRvbWxGaWxlO1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFsbFRhc2s6IFRhc2s7XG4gIHB1YmxpYyByZWFkb25seSBpbnN0YWxsQ2lUYXNrOiBUYXNrO1xuICBwdWJsaWMgcmVhZG9ubHkgcHVibGlzaFRhc2s6IFRhc2s7XG4gIHB1YmxpYyByZWFkb25seSBwdWJsaXNoVGVzdFRhc2s6IFRhc2s7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2ZW52UHl0aG9uOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIG9wdGlvbnM6IFV2T3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlKTtcblxuICAgIGNvbnN0IHJlcXVpcmVzUHl0aG9uID0gb3B0aW9ucy5wcm9qZWN0Py5yZXF1aXJlc1B5dGhvbiA/PyBcIj49My4xMiw8NC4wXCI7XG4gICAgdGhpcy52ZW52UHl0aG9uID0gb3B0aW9ucy5weXRob25FeGVjID8/IHJlcXVpcmVzUHl0aG9uO1xuXG4gICAgdGhpcy5pbnN0YWxsVGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwiaW5zdGFsbFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJJbnN0YWxsIGRlcGVuZGVuY2llcyBhbmQgdXBkYXRlIGxvY2tmaWxlXCIsXG4gICAgICBzdGVwczogW3sgZXhlY0FyZ3M6IFtcInV2XCIsIFwic3luY1wiXSB9LCB7IGV4ZWNBcmdzOiBbXCJ1dlwiLCBcImxvY2tcIl0gfV0sXG4gICAgfSk7XG5cbiAgICB0aGlzLmluc3RhbGxDaVRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcImluc3RhbGw6Y2lcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXMgd2l0aCBmcm96ZW4gbG9ja2ZpbGVcIixcbiAgICAgIGV4ZWNBcmdzOiBbXCJ1dlwiLCBcInN5bmNcIl0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2plY3QudGFza3MuYWRkRW52aXJvbm1lbnQoXCJWSVJUVUFMX0VOVlwiLCBcIi52ZW52XCIpO1xuICAgIHRoaXMucHJvamVjdC50YXNrcy5hZGRFbnZpcm9ubWVudChcIlBBVEhcIiwgXCIkKGVjaG8gLnZlbnYvYmluOiRQQVRIKVwiKTtcblxuICAgIHRoaXMucHJvamVjdC5wYWNrYWdlVGFzay5leGVjQXJncyhbXCJ1dlwiLCBcImJ1aWxkXCJdKTtcblxuICAgIHRoaXMucHVibGlzaFRlc3RUYXNrID0gdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJwdWJsaXNoOnRlc3RcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiVXBsb2FkcyB0aGUgcGFja2FnZSBhZ2FpbnN0IGEgdGVzdCBQeVBJIGVuZHBvaW50LlwiLFxuICAgICAgZXhlY0FyZ3M6IFtcInV2XCIsIFwicHVibGlzaFwiLCBcIi0taW5kZXhcIiwgXCJ0ZXN0cHlwaVwiXSxcbiAgICB9KTtcblxuICAgIHRoaXMucHVibGlzaFRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcInB1Ymxpc2hcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiVXBsb2FkcyB0aGUgcGFja2FnZSB0byBQeVBJLlwiLFxuICAgICAgZXhlY0FyZ3M6IFtcInV2XCIsIFwicHVibGlzaFwiXSxcbiAgICB9KTtcblxuICAgIHRoaXMuZmlsZSA9IG5ldyBQeXByb2plY3RUb21sRmlsZSh0aGlzLnByb2plY3QsIHtcbiAgICAgIHByb2plY3Q6IHtcbiAgICAgICAgbmFtZTogb3B0aW9ucy5wcm9qZWN0Py5uYW1lID8/IHRoaXMucHJvamVjdC5uYW1lLFxuICAgICAgICByZXF1aXJlc1B5dGhvbixcbiAgICAgICAgLi4ub3B0aW9ucy5wcm9qZWN0LFxuICAgICAgICBkZXBlbmRlbmNpZXM6ICgoKSA9PiBbXG4gICAgICAgICAgLi4uKG9wdGlvbnM/LnByb2plY3Q/LmRlcGVuZGVuY2llcyA/PyBbXSksXG4gICAgICAgICAgLi4udGhpcy5zeW50aERlcGVuZGVuY2llcygpLFxuICAgICAgICBdKSBhcyBhbnksXG4gICAgICB9LFxuICAgICAgZGVwZW5kZW5jeUdyb3VwczogKCgpID0+IHRoaXMuc3ludGhEZXBlbmRlbmN5R3JvdXBzKCkpIGFzIGFueSxcbiAgICAgIGJ1aWxkU3lzdGVtOiBvcHRpb25zLmJ1aWxkU3lzdGVtLFxuICAgICAgdG9vbDoge1xuICAgICAgICB1djogdG9Kc29uX1V2Q29uZmlndXJhdGlvbihvcHRpb25zLnV2KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogRm9ybWF0cyBkZXBlbmRlbmNpZXMgaW4gVVYgc3R5bGUuICovXG4gIHByaXZhdGUgZm9ybWF0RGVwZW5kZW5jeShkZXA6IERlcGVuZGVuY3kpOiBzdHJpbmcge1xuICAgIGNvbnN0IG5hbWUgPSBkZXAubmFtZTtcbiAgICBjb25zdCB2ZXJzaW9uID0gZGVwLnZlcnNpb247XG5cbiAgICBpZiAoIXZlcnNpb24gfHwgdmVyc2lvbiA9PT0gXCIqXCIpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cblxuICAgIC8vIFRyYW5zbGF0ZSBjYXJldCAoXikgdG8gUHl0aG9uIGNvbXBhdGlibGUgY29uc3RyYWludHNcbiAgICBpZiAodmVyc2lvbi5zdGFydHNXaXRoKFwiXlwiKSkge1xuICAgICAgY29uc3QgY2xlYW5WZXJzaW9uID0gdmVyc2lvbi5zbGljZSgxKTtcbiAgICAgIGNvbnN0IFttYWpvcl0gPSBjbGVhblZlcnNpb24uc3BsaXQoXCIuXCIpO1xuICAgICAgY29uc3QgbmV4dE1ham9yID0gTnVtYmVyKG1ham9yKSArIDE7XG4gICAgICByZXR1cm4gYCR7bmFtZX0+PSR7Y2xlYW5WZXJzaW9ufSw8JHtuZXh0TWFqb3J9LjAuMGA7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNsYXRlIHRpbGRlICh+KSB0byBjb21wYXRpYmxlIHJlbGVhc2UgY2xhdXNlIHBlciBQRVAgNDQwXG4gICAgaWYgKHZlcnNpb24uc3RhcnRzV2l0aChcIn5cIikpIHtcbiAgICAgIGNvbnN0IGNsZWFuVmVyc2lvbiA9IHZlcnNpb24uc2xpY2UoMSk7XG5cbiAgICAgIC8vIE9ubHkga2VlcCBtYWpvci5taW5vciBmb3IgdGlsZGUgaWYgcG9zc2libGVcbiAgICAgIGNvbnN0IFttYWpvciwgbWlub3IgPSBcIjBcIiwgcGF0Y2ggPSBcIjBcIl0gPSBjbGVhblZlcnNpb24uc3BsaXQoXCIuXCIpO1xuICAgICAgY29uc3QgbmV4dE1pbm9yID0gTnVtYmVyKG1pbm9yKSArIDE7XG4gICAgICByZXR1cm4gYCR7bmFtZX0+PSR7bWFqb3J9LiR7bWlub3J9LiR7cGF0Y2h9LDwke21ham9yfS4ke25leHRNaW5vcn0uMGA7XG4gICAgfVxuXG4gICAgLy8gT3RoZXJ3aXNlIHRyZWF0IGFzIGFuIGV4YWN0IHZlcnNpb25cbiAgICByZXR1cm4gYCR7bmFtZX09PSR7dmVyc2lvbn1gO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZXBlbmRlbmNpZXMoZGVwZW5kZW5jeVR5cGVzOiBEZXBlbmRlbmN5VHlwZVtdKTogc3RyaW5nW10ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnByb2plY3QuZGVwcy5hbGxcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAocGtnKSA9PiBkZXBlbmRlbmN5VHlwZXMuaW5jbHVkZXMocGtnLnR5cGUpICYmIHBrZy5uYW1lICE9PSBcInB5dGhvblwiLFxuICAgICAgICApXG4gICAgICAgIC8vIHJlbW92ZSBkdXBsaWNhdGUgdmVyc2lvbnMgb2YgdGhlIHNhbWUgZGVwZW5kZW5jeVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChkZXAsIGluZGV4LCBzZWxmKSA9PlxuICAgICAgICAgICAgaW5kZXggPT09IHNlbGYuZmluZEluZGV4KChkKSA9PiBkLm5hbWUgPT09IGRlcC5uYW1lKSxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChwa2cpID0+IHRoaXMuZm9ybWF0RGVwZW5kZW5jeShwa2cpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN5bnRoRGVwZW5kZW5jaWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5nZXREZXBlbmRlbmNpZXMoW0RlcGVuZGVuY3lUeXBlLlJVTlRJTUVdKTtcbiAgfVxuXG4gIHByaXZhdGUgc3ludGhEZXBlbmRlbmN5R3JvdXBzKCk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZGV2RGVwcyA9IHRoaXMuZ2V0RGVwZW5kZW5jaWVzKFtcbiAgICAgIERlcGVuZGVuY3lUeXBlLkRFVkVOVixcbiAgICAgIERlcGVuZGVuY3lUeXBlLlRFU1QsXG4gICAgXSk7XG5cbiAgICBpZiAoZGV2RGVwcykge1xuICAgICAgcmV0dXJuIHsgZGV2OiBkZXZEZXBzIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZERlcGVuZGVuY3koc3BlYzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5wcm9qZWN0LmRlcHMuYWRkRGVwZW5kZW5jeShzcGVjLCBEZXBlbmRlbmN5VHlwZS5SVU5USU1FKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGREZXZEZXBlbmRlbmN5KHNwZWM6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucHJvamVjdC5kZXBzLmFkZERlcGVuZGVuY3koc3BlYywgRGVwZW5kZW5jeVR5cGUuREVWRU5WKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cEVudmlyb25tZW50KCk6IHZvaWQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHV2LnRyeUNhcHR1cmUoW1wiLS12ZXJzaW9uXCJdLCB7XG4gICAgICBjd2Q6IHRoaXMucHJvamVjdC5vdXRkaXIsXG4gICAgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIuaW5mbyhcbiAgICAgICAgXCJVbmFibGUgdG8gc2V0dXAgYW4gZW52aXJvbm1lbnQgc2luY2UgdXYgaXMgbm90IGluc3RhbGxlZC4gUGxlYXNlIGluc3RhbGwgdXYgKGh0dHBzOi8vZ2l0aHViLmNvbS9hc3RyYWwtc2gvdXYpIG9yIHVzZSBhIGRpZmZlcmVudCBjb21wb25lbnQgZm9yIG1hbmFnaW5nIGVudmlyb25tZW50cy5cIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHZlbnYgd2l0aCB0aGUgc3BlY2lmaWMgUHl0aG9uIHZlcnNpb25cbiAgICAvLyB0aGlzIHdpbGwgaW5zdGFsbCB0aGUgcmVxdWVzdGVkIHB5dGhvbiB2ZXJzaW9uIGlmIG5lZWRlZFxuICAgIHV2LnJ1bihbXCJ2ZW52XCIsIFwiLS1weXRob25cIiwgdGhpcy52ZW52UHl0aG9uLCBcIi0tY2xlYXJcIiwgXCIudmVudlwiXSwge1xuICAgICAgY3dkOiB0aGlzLnByb2plY3Qub3V0ZGlyLFxuICAgIH0pO1xuICAgIHRoaXMucHJvamVjdC5sb2dnZXIuaW5mbyhcbiAgICAgIGBFbnZpcm9ubWVudCBzdWNjZXNzZnVsbHkgY3JlYXRlZCBpbiAudmVudiBkaXJlY3Rvcnkgd2l0aCBQeXRob24gJHt0aGlzLnZlbnZQeXRob259LmAsXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBpbnN0YWxsRGVwZW5kZW5jaWVzKCk6IHZvaWQge1xuICAgIHRoaXMucHJvamVjdC5sb2dnZXIuaW5mbyhcIkluc3RhbGxpbmcgZGVwZW5kZW5jaWVzLi4uXCIpO1xuICAgIGlmICh0aGlzLmZpbGUuY2hhbmdlZCkge1xuICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLnJ1blRhc2sodGhpcy5pbnN0YWxsVGFzay5uYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLnJ1blRhc2sodGhpcy5pbnN0YWxsQ2lUYXNrLm5hbWUpO1xuICAgIH1cbiAgfVxufVxuIl19