UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

139 lines (138 loc) • 5.45 kB
import { regEx } from "../../../util/regex.js"; import { minimatch } from "../../../util/minimatch.js"; import { logger } from "../../../logger/index.js"; import { findLocalSiblingOrParent, findUpLocal, readLocalFile } from "../../../util/fs/index.js"; import { nugetOrg } from "../../datasource/nuget/index.js"; import { GlobalJson } from "./schema.js"; import upath from "upath"; import { XmlDocument } from "xmldoc"; //#region lib/modules/manager/nuget/util.ts async function readFileAsXmlDocument(file) { try { const doc = new XmlDocument(await readLocalFile(file, "utf8")); return doc?.firstChild ? doc : void 0; } catch (err) { logger.debug({ err, file }, `failed to parse file as XML document`); return; } } /** * The default `nuget.org` named registry. * @returns the default registry for NuGet */ function getDefaultRegistries() { return [{ url: nugetOrg, name: "nuget.org" }]; } async function getConfiguredRegistries(packageFile) { const nuGetConfigPath = await findUpLocal([ "nuget.config", "NuGet.config", "NuGet.Config" ], upath.dirname(packageFile)); if (!nuGetConfigPath) return; logger.debug(`Found NuGet.config at ${nuGetConfigPath}`); const nuGetConfig = await readFileAsXmlDocument(nuGetConfigPath); if (!nuGetConfig) return; const packageSources = nuGetConfig.childNamed("packageSources"); if (!packageSources) return; const packageSourceMapping = nuGetConfig.childNamed("packageSourceMapping"); let registries = getDefaultRegistries(); for (const registry of registries) registry.sourceMappedPackagePatterns = packageSourceMapping?.childWithAttribute("key", registry.name)?.childrenNamed("package").map((packagePattern) => packagePattern.attr.pattern); for (const child of packageSources.children) if (isXmlElement(child)) { if (child.name === "clear") { logger.debug(`clearing registry URLs`); registries.length = 0; } else if (child.name === "add") if (regEx(/^https?:\/\//i).test(child.attr.value)) { let registryUrl = child.attr.value; if (child.attr.protocolVersion) registryUrl += `#protocolVersion=${child.attr.protocolVersion}`; const sourceMappedPackagePatterns = packageSourceMapping?.childWithAttribute("key", child.attr.key)?.childrenNamed("package").map((packagePattern) => packagePattern.attr.pattern); logger.debug({ name: child.attr.key, registryUrl, sourceMappedPackagePatterns }, `Adding registry URL ${registryUrl}`); registries.push({ name: child.attr.key, url: registryUrl, sourceMappedPackagePatterns }); } else logger.debug({ registryUrl: child.attr.value }, "ignoring local registry URL"); } const disabledPackageSources = nuGetConfig.childNamed("disabledPackageSources"); if (disabledPackageSources) { for (const child of disabledPackageSources.children) if (isXmlElement(child) && child.name === "add" && child.attr.value === "true") { const disabledRegistryKey = child.attr.key; registries = registries.filter((o) => o.name !== disabledRegistryKey); logger.debug(`Disabled registry with key: ${disabledRegistryKey}`); } } const plainRegistryUrls = registries.filter((r) => !r.sourceMappedPackagePatterns).map((r) => r.url); registries = registries.filter((r) => { return r.sourceMappedPackagePatterns ?? !plainRegistryUrls.includes(`${r.url}#protocolVersion=3`); }); return registries; } function isXmlElement(child) { return child.type === "element"; } function findVersion(parsedXml) { for (const tag of ["Version", "VersionPrefix"]) for (const l1Elem of parsedXml.childrenNamed("PropertyGroup")) for (const l2Elem of l1Elem.childrenNamed(tag)) return l2Elem; return null; } function applyRegistries(dep, registries) { if (registries) { if (!registries.some((reg) => reg.sourceMappedPackagePatterns)) { dep.registryUrls = registries.map((reg) => reg.url); return dep; } const regs = registries.filter((r) => r.sourceMappedPackagePatterns); const map = new Map(regs.flatMap((r) => r.sourceMappedPackagePatterns.map((p) => [p, []]))); const depName = dep.depName; for (const reg of regs) for (const pattern of reg.sourceMappedPackagePatterns) map.get(pattern).push(reg); const urls = []; for (const [pattern, regs] of [...map].sort(sortPatterns)) if (minimatch(pattern, { nocase: true }).match(depName)) { urls.push(...regs.map((r) => r.url)); break; } if (urls.length) dep.registryUrls = urls; } return dep; } function sortPatterns(a, b) { if (a[0].endsWith("*") && !b[0].endsWith("*")) return 1; if (!a[0].endsWith("*") && b[0].endsWith("*")) return -1; const aTrim = a[0].slice(0, -1); const bTrim = b[0].slice(0, -1); return aTrim.localeCompare(bTrim) * -1; } async function findGlobalJson(packageFile) { const globalJsonPath = await findLocalSiblingOrParent(packageFile, "global.json"); if (!globalJsonPath) return null; const content = await readLocalFile(globalJsonPath, "utf8"); if (!content) { logger.debug({ packageFile, globalJsonPath }, "Failed to read global.json"); return null; } const result = await GlobalJson.safeParseAsync(content); if (!result.success) { logger.debug({ packageFile, globalJsonPath, err: result.error }, "Failed to parse global.json"); return null; } return result.data; } //#endregion export { applyRegistries, findGlobalJson, findVersion, getConfiguredRegistries, getDefaultRegistries, isXmlElement, readFileAsXmlDocument }; //# sourceMappingURL=util.js.map