From 823417b6582ea4bd265be16f67ce5ff41c73c9f4 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Thu, 18 Apr 2024 17:51:32 -0600 Subject: [PATCH] allow packages.config update when project file doesn't list assembly version (#9534) --- .../UpdateWorkerTests.PackagesConfig.cs | 56 +++++++++++++++++++ .../Updater/PackagesConfigUpdater.cs | 26 +++++++-- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs index 9ade81dc585..c240bb07085 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs @@ -65,6 +65,62 @@ public async Task UpdateSingleDependencyInPackagesConfig() """); } + [Fact] + public async Task UpdateSingleDependencyInPackagesConfig_ReferenceHasNoAssemblyVersion() + { + // update Newtonsoft.Json from 7.0.1 to 13.0.1 + await TestUpdateForProject("Newtonsoft.Json", "7.0.1", "13.0.1", + // existing + projectContents: """ + + + + v4.5 + + + + + + + packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + + + + + """, + packagesConfigContents: """ + + + + """, + // expected + expectedProjectContents: """ + + + + v4.5 + + + + + + + packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + True + + + + + """, + expectedPackagesConfigContents: """ + + + + + """); + } + [Fact] public async Task UpdateSingleDependencyInPackagesConfigButNotToLatest() { diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs index 237579ec9c9..51e917ada81 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs @@ -174,11 +174,7 @@ private static void RunNuget(List updateArgs, List restoreArgs, var hintPathSubString = $"{dependencyName}.{dependencyVersion}"; string? partialPathMatch = null; - var hintPathNodes = projectBuildFile.Contents.Descendants() - .Where(e => - e.Name.Equals("HintPath", StringComparison.OrdinalIgnoreCase) && - e.Parent.Name.Equals("Reference", StringComparison.OrdinalIgnoreCase) && - e.Parent.GetAttributeValue("Include", StringComparison.OrdinalIgnoreCase)?.StartsWith($"{dependencyName},", StringComparison.OrdinalIgnoreCase) == true); + var hintPathNodes = projectBuildFile.Contents.Descendants().Where(e => e.IsHintPathNodeForDependency(dependencyName)); foreach (var hintPathNode in hintPathNodes) { var hintPath = hintPathNode.GetContentValue(); @@ -210,6 +206,26 @@ private static void RunNuget(List updateArgs, List restoreArgs, return partialPathMatch; } + private static bool IsHintPathNodeForDependency(this IXmlElementSyntax element, string dependencyName) + { + if (element.Name.Equals("HintPath", StringComparison.OrdinalIgnoreCase) && + element.Parent.Name.Equals("Reference", StringComparison.OrdinalIgnoreCase)) + { + // the include attribute will look like one of the following: + // + // or + // + string includeAttributeValue = element.Parent.GetAttributeValue("Include", StringComparison.OrdinalIgnoreCase); + if (includeAttributeValue.Equals(dependencyName, StringComparison.OrdinalIgnoreCase) || + includeAttributeValue.StartsWith($"{dependencyName},", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + private static string GetUpToIndexWithoutTrailingDirectorySeparator(string path, int index) { var subpath = path[..index];