UNPKG

renovate

Version:

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

202 lines • 8.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readFileAsXmlDocument = readFileAsXmlDocument; exports.getDefaultRegistries = getDefaultRegistries; exports.getConfiguredRegistries = getConfiguredRegistries; exports.isXmlElement = isXmlElement; exports.findVersion = findVersion; exports.applyRegistries = applyRegistries; exports.findGlobalJson = findGlobalJson; const tslib_1 = require("tslib"); const upath_1 = tslib_1.__importDefault(require("upath")); const xmldoc_1 = require("xmldoc"); const logger_1 = require("../../../logger"); const fs_1 = require("../../../util/fs"); const minimatch_1 = require("../../../util/minimatch"); const regex_1 = require("../../../util/regex"); const nuget_1 = require("../../datasource/nuget"); const schema_1 = require("./schema"); async function readFileAsXmlDocument(file) { try { // TODO #22198 const doc = new xmldoc_1.XmlDocument((await (0, fs_1.readLocalFile)(file, 'utf8'))); // don't return empty documents return doc?.firstChild ? doc : undefined; } catch (err) { logger_1.logger.debug({ err, file }, `failed to parse file as XML document`); return undefined; } } /** * The default `nuget.org` named registry. * @returns the default registry for NuGet */ function getDefaultRegistries() { return [{ url: nuget_1.nugetOrg, name: 'nuget.org' }]; } async function getConfiguredRegistries(packageFile) { // Valid file names taken from https://github.com/NuGet/NuGet.Client/blob/f64621487c0b454eda4b98af853bf4a528bef72a/src/NuGet.Core/NuGet.Configuration/Settings/Settings.cs#L34 const nuGetConfigFileNames = ['nuget.config', 'NuGet.config', 'NuGet.Config']; // normalize paths, otherwise startsWith can fail because of path delimitter mismatch const nuGetConfigPath = await (0, fs_1.findUpLocal)(nuGetConfigFileNames, upath_1.default.dirname(packageFile)); if (!nuGetConfigPath) { return undefined; } logger_1.logger.debug(`Found NuGet.config at ${nuGetConfigPath}`); const nuGetConfig = await readFileAsXmlDocument(nuGetConfigPath); if (!nuGetConfig) { return undefined; } const packageSources = nuGetConfig.childNamed('packageSources'); if (!packageSources) { // If there are no packageSources, don't even look for any // disabledPackageSources // Even if NuGet default source (nuget.org) was among the // disabledPackageSources, Renovate will default to the default source // (nuget.org) anyway return undefined; } const packageSourceMapping = nuGetConfig.childNamed('packageSourceMapping'); let registries = getDefaultRegistries(); // Map optional source mapped package patterns to default registries for (const registry of registries) { const sourceMappedPackagePatterns = packageSourceMapping ?.childWithAttribute('key', registry.name) ?.childrenNamed('package') .map((packagePattern) => packagePattern.attr.pattern); registry.sourceMappedPackagePatterns = sourceMappedPackagePatterns; } for (const child of packageSources.children) { if (isXmlElement(child)) { if (child.name === 'clear') { logger_1.logger.debug(`clearing registry URLs`); registries.length = 0; } else if (child.name === 'add') { const isHttpUrl = (0, regex_1.regEx)(/^https?:\/\//i).test(child.attr.value); if (isHttpUrl) { 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_1.logger.debug({ name: child.attr.key, registryUrl, sourceMappedPackagePatterns, }, `Adding registry URL ${registryUrl}`); registries.push({ name: child.attr.key, url: registryUrl, sourceMappedPackagePatterns, }); } else { logger_1.logger.debug({ registryUrl: child.attr.value }, 'ignoring local registry URL'); } } // child.name === 'remove' not supported } } 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_1.logger.debug(`Disabled registry with key: ${disabledRegistryKey}`); } } } // Deduplicate registries with #procolVersion=3 // Keep any which include sourceMappedPackagePatterns 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 ((0, minimatch_1.minimatch)(pattern, { nocase: true }).match(depName)) { urls.push(...regs.map((r) => r.url)); break; } } if (urls.length) { dep.registryUrls = urls; } } return dep; } /* * Sorts patterns by specificity: * 1. Exact match patterns * 2. Wildcard match patterns * The longest pattern has precedence. */ 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 (0, fs_1.findLocalSiblingOrParent)(packageFile, 'global.json'); if (!globalJsonPath) { return null; } const content = await (0, fs_1.readLocalFile)(globalJsonPath, 'utf8'); if (!content) { logger_1.logger.debug({ packageFile, globalJsonPath }, 'Failed to read global.json'); return null; } const result = await schema_1.GlobalJson.safeParseAsync(content); if (!result.success) { logger_1.logger.debug({ packageFile, globalJsonPath, err: result.error }, 'Failed to parse global.json'); return null; } return result.data; } //# sourceMappingURL=util.js.map