diff --git a/lib/modules/manager/nuget/extract.ts b/lib/modules/manager/nuget/extract.ts index fd740ba30930ffb7e6f4deb009fcf7659f336136..80d15ad9f0c0a6ae825e2be45b39a9b5c9f6b35f 100644 --- a/lib/modules/manager/nuget/extract.ts +++ b/lib/modules/manager/nuget/extract.ts @@ -12,7 +12,7 @@ import type { } from '../types'; import { extractMsbuildGlobalManifest } from './extract/global-manifest'; import type { DotnetToolsManifest } from './types'; -import { getConfiguredRegistries } from './util'; +import { findVersion, getConfiguredRegistries } from './util'; /** * https://docs.microsoft.com/en-us/nuget/concepts/package-versioning @@ -123,14 +123,14 @@ export async function extractPackageFile( } let deps: PackageDependency[] = []; - let packageFileVersion = undefined; + let packageFileVersion: string | undefined; try { const parsedXml = new XmlDocument(content); deps = extractDepsFromXml(parsedXml).map((dep) => ({ ...dep, ...(registryUrls && { registryUrls }), })); - packageFileVersion = parsedXml.valueWithPath('PropertyGroup.Version'); + packageFileVersion = findVersion(parsedXml)?.val; } catch (err) { logger.debug({ err, packageFile }, `Failed to parse XML`); } diff --git a/lib/modules/manager/nuget/update.spec.ts b/lib/modules/manager/nuget/update.spec.ts index 1701d0625c35e51e8bb54f029ab6a2be6883586d..42bc169f7b2f8dee28ff2adfeed16bb6d6787236 100644 --- a/lib/modules/manager/nuget/update.spec.ts +++ b/lib/modules/manager/nuget/update.spec.ts @@ -66,7 +66,7 @@ describe('modules/manager/nuget/update', () => { expect(project.valueWithPath('PropertyGroup.Version')).toBe('1'); }); - it('does not bump version if csproj has no version', () => { + it('does not bump version if extract found no version', () => { const { bumpedContent } = bumpPackageVersion( minimumContent, undefined, @@ -76,6 +76,18 @@ describe('modules/manager/nuget/update', () => { expect(bumpedContent).toEqual(minimumContent); }); + it('does not bump version if csproj has no version', () => { + const originalContent = + '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework></PropertyGroup></Project>'; + const { bumpedContent } = bumpPackageVersion( + originalContent, + '0.0.1', + 'patch' + ); + + expect(bumpedContent).toEqual(originalContent); + }); + it('returns content if bumping errors', () => { const { bumpedContent } = bumpPackageVersion( simpleContent, @@ -95,5 +107,16 @@ describe('modules/manager/nuget/update', () => { const project = new XmlDocument(bumpedContent!); expect(project.valueWithPath('PropertyGroup.Version')).toBe('1.0.0-2'); }); + + it('bumps csproj version prefix', () => { + const content = + '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><VersionPrefix>1.0.0</VersionPrefix></PropertyGroup></Project>'; + const { bumpedContent } = bumpPackageVersion(content, '1.0.0', 'patch'); + + const project = new XmlDocument(bumpedContent!); + expect(project.valueWithPath('PropertyGroup.VersionPrefix')).toBe( + '1.0.1' + ); + }); }); }); diff --git a/lib/modules/manager/nuget/update.ts b/lib/modules/manager/nuget/update.ts index 232c1ab8508d24d57afa4f2ed13ed72456a88245..60b6fe5b08b270297c780d5531d704017b095a34 100644 --- a/lib/modules/manager/nuget/update.ts +++ b/lib/modules/manager/nuget/update.ts @@ -3,6 +3,7 @@ import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import { replaceAt } from '../../../util/string'; import type { BumpPackageVersionResult } from '../types'; +import { findVersion } from './util'; export function bumpPackageVersion( content: string, @@ -30,8 +31,23 @@ export function bumpPackageVersion( try { const project = new XmlDocument(content); - const versionNode = project.descendantWithPath('PropertyGroup.Version')!; + const versionNode = findVersion(project); + if (!versionNode) { + logger.warn( + "Couldn't find Version or VersionPrefix in any PropertyGroup" + ); + return { bumpedContent }; + } + const currentProjVersion = versionNode.val; + if (currentProjVersion !== currentValue) { + logger.warn( + { currentValue, currentProjVersion }, + "currentValue passed to bumpPackageVersion() doesn't match value found" + ); + return { bumpedContent }; + } + const startTagPosition = versionNode.startTagPosition; const versionPosition = content.indexOf( currentProjVersion, @@ -43,11 +59,6 @@ export function bumpPackageVersion( throw new Error('semver inc failed'); } - if (currentProjVersion === newProjVersion) { - logger.debug('Version was already bumped'); - return { bumpedContent }; - } - logger.debug(`newProjVersion: ${newProjVersion}`); bumpedContent = replaceAt( content, diff --git a/lib/modules/manager/nuget/util.spec.ts b/lib/modules/manager/nuget/util.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..58729ed3ce02bb89cbe794acdcd3f85e708867d1 --- /dev/null +++ b/lib/modules/manager/nuget/util.spec.ts @@ -0,0 +1,29 @@ +import { XmlDocument } from 'xmldoc'; +import { bumpPackageVersion } from './update'; +import { findVersion } from './util'; + +describe('modules/manager/nuget/util', () => { + describe('findVersion', () => { + it('finds the version in a later property group', () => { + const content = + '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework></PropertyGroup><PropertyGroup><Version>0.0.1</Version></PropertyGroup></Project>'; + const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'patch'); + + const project = new XmlDocument(bumpedContent!); + const versionNode = findVersion(project); + const newVersion = versionNode!.val; + expect(newVersion).toBe('0.0.2'); + }); + + it('picks version over versionprefix', () => { + const content = + '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><VersionPrefix>0.0.5</VersionPrefix></PropertyGroup><PropertyGroup><Version>0.0.1</Version></PropertyGroup></Project>'; + const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'patch'); + + const project = new XmlDocument(bumpedContent!); + const versionNode = findVersion(project); + const newVersion = versionNode!.val; + expect(newVersion).toBe('0.0.2'); + }); + }); +}); diff --git a/lib/modules/manager/nuget/util.ts b/lib/modules/manager/nuget/util.ts index f21c787d54c55b0c339917efbf0b90099bcda5f4..b9463b118d7a6de680f9ef74a4c5ee3d622dc0d3 100644 --- a/lib/modules/manager/nuget/util.ts +++ b/lib/modules/manager/nuget/util.ts @@ -1,5 +1,5 @@ import upath from 'upath'; -import { XmlDocument } from 'xmldoc'; +import { XmlDocument, XmlElement } from 'xmldoc'; import { logger } from '../../../logger'; import { findUpLocal, readLocalFile } from '../../../util/fs'; import { regEx } from '../../../util/regex'; @@ -83,3 +83,14 @@ export async function getConfiguredRegistries( } return registries; } + +export function findVersion(parsedXml: XmlDocument): XmlElement | null { + for (const tag of ['Version', 'VersionPrefix']) { + for (const l1Elem of parsedXml.childrenNamed('PropertyGroup')) { + for (const l2Elem of l1Elem.childrenNamed(tag)) { + return l2Elem; + } + } + } + return null; +}