dependabot-nuget 0.323.0 → 0.325.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +0 -4
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +1 -31
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +0 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyInfo.cs +1 -0
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +64 -10
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/MSBuildDependencySolver.cs +10 -4
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +4 -4
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +31 -41
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -6
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Cooldown.cs +83 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +2 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +9 -1
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGenerator.cs +6 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +8 -1
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +79 -67
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +1 -1
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +1 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +1 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +10 -7
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +245 -125
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +4 -11
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +4 -5
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +2 -2
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +14 -31
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +3 -5
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +12 -13
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/XmlExtensions.cs +3 -3
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +78 -2
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +126 -3
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +14 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +1 -2
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -2
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +1 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -6
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +2 -3
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +1 -2
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/CooldownTests.cs +99 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +168 -4
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGeneratorTests.cs +71 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +71 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +70 -39
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +43 -30
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +76 -3
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +0 -2
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +11 -27
  51. data/lib/dependabot/nuget.rb +3 -11
  52. metadata +8 -54
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +0 -49
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +0 -60
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +0 -35
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +0 -58
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +0 -380
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +0 -557
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.FrameworkCheck.cs +0 -37
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +0 -226
  61. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +0 -65
  62. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +0 -66
  63. data/lib/dependabot/nuget/cache_manager.rb +0 -29
  64. data/lib/dependabot/nuget/discovery/dependency_details.rb +0 -102
  65. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +0 -122
  66. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +0 -266
  67. data/lib/dependabot/nuget/discovery/evaluation_details.rb +0 -63
  68. data/lib/dependabot/nuget/discovery/project_discovery.rb +0 -104
  69. data/lib/dependabot/nuget/discovery/property_details.rb +0 -43
  70. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +0 -61
  71. data/lib/dependabot/nuget/file_fetcher.rb +0 -46
  72. data/lib/dependabot/nuget/file_parser.rb +0 -153
  73. data/lib/dependabot/nuget/file_updater.rb +0 -256
  74. data/lib/dependabot/nuget/language.rb +0 -98
  75. data/lib/dependabot/nuget/metadata_finder.rb +0 -197
  76. data/lib/dependabot/nuget/native_helpers.rb +0 -364
  77. data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +0 -88
  78. data/lib/dependabot/nuget/package_manager.rb +0 -51
  79. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +0 -105
  80. data/lib/dependabot/nuget/update_checker.rb +0 -210
@@ -1,7 +1,7 @@
1
1
  using System.Collections.Immutable;
2
2
  using System.Text.RegularExpressions;
3
- using System.Xml;
4
- using System.Xml.Linq;
3
+
4
+ using Microsoft.Language.Xml;
5
5
 
6
6
  using NuGet.Versioning;
7
7
 
@@ -25,7 +25,7 @@ public class XmlFileWriter : IFileWriter
25
25
  private readonly ILogger _logger;
26
26
 
27
27
  // these file extensions are valid project entrypoints; everything else is ignored
28
- private static readonly HashSet<string> SupportedProjectFileExtensions = new(StringComparer.OrdinalIgnoreCase)
28
+ internal static readonly HashSet<string> SupportedProjectFileExtensions = new(StringComparer.OrdinalIgnoreCase)
29
29
  {
30
30
  ".csproj",
31
31
  ".vbproj",
@@ -33,7 +33,7 @@ public class XmlFileWriter : IFileWriter
33
33
  };
34
34
 
35
35
  // these file extensions are valid additional files and can be updated; everything else is ignored
36
- private static readonly HashSet<string> SupportedAdditionalFileExtensions = new(StringComparer.OrdinalIgnoreCase)
36
+ internal static readonly HashSet<string> SupportedAdditionalFileExtensions = new(StringComparer.OrdinalIgnoreCase)
37
37
  {
38
38
  ".props",
39
39
  ".targets",
@@ -71,8 +71,7 @@ public class XmlFileWriter : IFileWriter
71
71
  .Where(path => SupportedProjectFileExtensions.Contains(Path.GetExtension(path)) || SupportedAdditionalFileExtensions.Contains(Path.GetExtension(path)))
72
72
  .Select(async path =>
73
73
  {
74
- var content = await ReadFileContentsAsync(repoContentsPath, path);
75
- var document = XDocument.Parse(content, LoadOptions.PreserveWhitespace);
74
+ var document = await ReadFileContentsAsync(repoContentsPath, path);
76
75
  return KeyValuePair.Create(path, document);
77
76
  })
78
77
  .ToArray();
@@ -102,17 +101,46 @@ public class XmlFileWriter : IFileWriter
102
101
  string? currentVersionString = null;
103
102
  Action<string>? updateVersionLocation = null;
104
103
 
105
- var packageReferenceElements = filesAndContents.Values
106
- .SelectMany(doc => doc.Descendants().Where(e => e.Name.LocalName == PackageReferenceElementName || e.Name.LocalName == GlobalPackageReferenceElementName))
107
- .Where(e =>
104
+ var packageReferenceElementsAndPaths = filesAndContents
105
+ .SelectMany(kvp =>
106
+ {
107
+ var path = kvp.Key;
108
+ var doc = kvp.Value;
109
+ var elements = doc.Descendants().Where(e => e.Name == PackageReferenceElementName || e.Name == GlobalPackageReferenceElementName);
110
+ var pair = elements.Select(element => KeyValuePair.Create(element, path));
111
+ return pair;
112
+ })
113
+ .Where(pair =>
108
114
  {
109
- var attributeValue = e.Attribute(IncludeAttributeName)?.Value ?? e.Attribute(UpdateAttributeName)?.Value ?? string.Empty;
115
+ var element = pair.Key;
116
+ var attributeValue = element.GetAttributeValue(IncludeAttributeName) ?? element.GetAttributeValue(UpdateAttributeName) ?? string.Empty;
110
117
  var packageNames = attributeValue.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
111
118
  return packageNames.Any(name => name.Equals(requiredPackageVersion.Name, StringComparison.OrdinalIgnoreCase));
112
119
  })
113
120
  .ToArray();
114
121
 
115
- if (packageReferenceElements.Length == 0)
122
+ SyntaxNode ReplaceNode(string filePath, SyntaxNode original, SyntaxNode replacement)
123
+ {
124
+ var doc = filesAndContents[filePath];
125
+
126
+ #if DEBUG
127
+ if (!doc.DescendantNodes().OfType<XmlNodeSyntax>().Any(n => n == original))
128
+ {
129
+ throw new NotSupportedException("original node was not found");
130
+ }
131
+ #endif
132
+
133
+ var updatedDoc = doc.ReplaceNode(original, replacement);
134
+ #if DEBUG
135
+ var docFullString = doc.ToFullString();
136
+ var updatedDocFullString = updatedDoc.ToFullString();
137
+ #endif
138
+ filesAndContents[filePath] = updatedDoc;
139
+ var newlyAddedNode = updatedDoc.DescendantNodes().OfType<XmlNodeSyntax>().First(d => d.FullSpan.Start == original.FullSpan.Start);
140
+ return newlyAddedNode;
141
+ }
142
+
143
+ if (packageReferenceElementsAndPaths.Length == 0)
116
144
  {
117
145
  // no matching `<PackageReference>` elements found; pin it as a transitive dependency
118
146
  updatesPerformed[requiredPackageVersion.Name] = true; // all cases below add the dependency
@@ -120,51 +148,112 @@ public class XmlFileWriter : IFileWriter
120
148
  // find last `<ItemGroup>` in the project...
121
149
  Action addItemGroup = () => { }; // adding an ItemGroup to the project isn't always necessary, but it's much easier to prepare for it here
122
150
  var projectDocument = filesAndContents[projectRelativePath];
123
- var lastItemGroup = projectDocument.Root!.Elements()
124
- .LastOrDefault(e => e.Name.LocalName.Equals(ItemGroupElementName, StringComparison.OrdinalIgnoreCase));
151
+ var lastItemGroup = projectDocument.RootSyntax.Elements
152
+ .LastOrDefault(e => e.Name.Equals(ItemGroupElementName, StringComparison.OrdinalIgnoreCase));
125
153
  if (lastItemGroup is null)
126
154
  {
127
155
  _logger.Info($"No `<{ItemGroupElementName}>` element found in project; adding one.");
128
- lastItemGroup = new XElement(XName.Get(ItemGroupElementName, projectDocument.Root.Name.NamespaceName));
129
- addItemGroup = () => projectDocument.Root.Add(lastItemGroup);
156
+ lastItemGroup = XmlExtensions.CreateOpenCloseXmlElementSyntax(ItemGroupElementName,
157
+ new SyntaxList<SyntaxNode>([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(" ")]),
158
+ insertIntermediateNewline: false);
159
+ addItemGroup = () =>
160
+ {
161
+ // add the new element
162
+ var updatedRootSyntax = projectDocument.RootSyntax.AddChild(lastItemGroup);
163
+ var updatedProjectDocument = projectDocument.ReplaceNode(projectDocument.RootSyntax.AsNode, updatedRootSyntax.AsNode);
164
+
165
+ // reset well-known variables
166
+ projectDocument = updatedProjectDocument;
167
+ filesAndContents[projectRelativePath] = updatedProjectDocument;
168
+ lastItemGroup = updatedProjectDocument.RootSyntax.Elements.Last(e => e.Name.Equals(ItemGroupElementName, StringComparison.OrdinalIgnoreCase));
169
+ };
130
170
  }
131
171
 
132
172
  // ...find where the new item should go...
133
- var packageReferencesBeforeNew = lastItemGroup.Elements()
134
- .Where(e => e.Name.LocalName.Equals(PackageReferenceElementName, StringComparison.OrdinalIgnoreCase))
135
- .TakeWhile(e => (e.Attribute(IncludeAttributeName)?.Value ?? e.Attribute(UpdateAttributeName)?.Value ?? string.Empty).CompareTo(requiredPackageVersion.Name) < 0)
136
- .ToArray();
173
+ var elementsBeforeNew = GetOrderedElementsBeforeSpecified(lastItemGroup, PackageReferenceElementName, [IncludeAttributeName, UpdateAttributeName], requiredPackageVersion.Name);
137
174
 
138
175
  // ...prepare a new `<PackageReference>` element...
139
- var newElement = new XElement(
140
- XName.Get(PackageReferenceElementName, projectDocument.Root.Name.NamespaceName),
141
- new XAttribute(IncludeAttributeName, requiredPackageVersion.Name));
176
+ var newElement = XmlExtensions.CreateSingleLineXmlElementSyntax(PackageReferenceElementName, leadingTrivia: new SyntaxList<SyntaxNode>())
177
+ .WithAttribute(IncludeAttributeName, requiredPackageVersion.Name);
142
178
 
143
179
  // ...add the `<PackageReference>` element if and where appropriate...
144
180
  if (addPackageReferenceElementForPinnedPackages)
145
181
  {
146
182
  addItemGroup();
147
- var lastPriorPackageReference = packageReferencesBeforeNew.LastOrDefault();
148
- if (lastPriorPackageReference is not null)
183
+ var lastPriorElement = elementsBeforeNew.LastOrDefault();
184
+ if (lastPriorElement is not null)
149
185
  {
150
- AddAfterSiblingElement(lastPriorPackageReference, newElement);
186
+ // find line number of last prior element
187
+ // find the offset of the first token on each newline
188
+ var firstOffsetForLine = new List<int>();
189
+ foreach (var tr in filesAndContents[projectRelativePath].DescendantTrivia(descendIntoChildren: _ => true, descendIntoTrivia: true))
190
+ {
191
+ if (tr.Kind == SyntaxKind.EndOfLineTrivia)
192
+ {
193
+ firstOffsetForLine.Add(tr.SpanStart);
194
+ }
195
+
196
+ if (tr.SpanStart >= lastPriorElement.SpanStart)
197
+ {
198
+ break;
199
+ }
200
+ }
201
+
202
+ var lastPriorElementLineNumber = firstOffsetForLine.Count(o => o < lastPriorElement.SpanStart);
203
+ var lastElementAtStartOfLine = lastPriorElement.Parent.ChildNodes
204
+ .First(n => firstOffsetForLine.Count(o => o < n.SpanStart) >= lastPriorElementLineNumber);
205
+ var trivia = lastElementAtStartOfLine.GetLeadingTrivia().ToList();
206
+ var priorEolIndex = trivia.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
207
+ var indentTrivia = trivia
208
+ .Skip(priorEolIndex + 1)
209
+ .Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
210
+ .ToArray();
211
+ var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), .. indentTrivia]);
212
+ newElement = (IXmlElementSyntax)newElement.AsNode.WithLeadingTrivia(newTrivia);
213
+ var replacementParent = lastPriorElement.Parent.InsertNodesAfter(lastPriorElement, [newElement.AsNode]);
214
+ var actualReplacementParent = ReplaceNode(projectRelativePath, lastPriorElement.Parent, replacementParent);
215
+ var insertionIndex = elementsBeforeNew.Length;
216
+ var actualNewElement = ((IXmlElementSyntax)actualReplacementParent).Content[insertionIndex];
217
+ newElement = (IXmlElementSyntax)actualNewElement;
151
218
  }
152
219
  else
153
220
  {
154
221
  // no prior package references; add to the front
155
- var indent = GetIndentXTextFromElement(lastItemGroup, extraIndentationToAdd: " ");
156
- lastItemGroup.AddFirst(indent, newElement);
222
+ var itemGroupTrivia = lastItemGroup.AsNode.GetLeadingTrivia().ToList();
223
+ var priorEolIndex = itemGroupTrivia.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
224
+ var indentTrivia = itemGroupTrivia
225
+ .Skip(priorEolIndex + 1)
226
+ .Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
227
+ .ToArray();
228
+ var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(" "), .. indentTrivia]);
229
+ newElement = (IXmlElementSyntax)newElement.AsNode.WithLeadingTrivia(newTrivia);
230
+ var updatedItemGroup = (IXmlElementSyntax)ReplaceNode(
231
+ projectRelativePath,
232
+ lastItemGroup.AsNode,
233
+ lastItemGroup.InsertChild(newElement, 0).AsNode
234
+ );
235
+ newElement = (IXmlElementSyntax)updatedItemGroup.Content[0];
157
236
  }
158
237
  }
159
238
 
160
239
  // ...find the best place to add the version...
161
- var matchingPackageVersionElement = filesAndContents.Values
162
- .SelectMany(doc => doc.Descendants().Where(e => e.Name.LocalName.Equals(PackageVersionElementName, StringComparison.OrdinalIgnoreCase)))
163
- .FirstOrDefault(e => (e.Attribute(IncludeAttributeName)?.Value ?? string.Empty).Trim().Equals(requiredPackageVersion.Name, StringComparison.OrdinalIgnoreCase));
164
- if (matchingPackageVersionElement is not null)
240
+ var matchingPackageVersionElementsAndPaths = filesAndContents
241
+ .SelectMany(kvp =>
242
+ {
243
+ var path = kvp.Key;
244
+ var doc = kvp.Value;
245
+ var packageVersionElements = doc.Descendants()
246
+ .Where(e => e.Name.Equals(PackageVersionElementName, StringComparison.OrdinalIgnoreCase))
247
+ .Where(element => (element.GetAttributeValue(IncludeAttributeName) ?? string.Empty).Trim().Equals(requiredPackageVersion.Name, StringComparison.OrdinalIgnoreCase))
248
+ .ToArray();
249
+ return packageVersionElements.Select(element => KeyValuePair.Create(element, path));
250
+ })
251
+ .ToArray();
252
+ if (matchingPackageVersionElementsAndPaths.Length > 0)
165
253
  {
166
254
  // found matching `<PackageVersion>` element; if `Version` attribute is appropriate we're done, otherwise set `VersionOverride` attribute on new element
167
- var versionAttribute = matchingPackageVersionElement.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
255
+ var (matchingPackageVersionElement, filePath) = matchingPackageVersionElementsAndPaths.First();
256
+ var versionAttribute = matchingPackageVersionElement.GetAttributeCaseInsensitive(VersionMetadataName);
168
257
  if (versionAttribute is not null &&
169
258
  NuGetVersion.TryParse(versionAttribute.Value, out var existingVersion) &&
170
259
  existingVersion == requiredVersion)
@@ -176,88 +265,152 @@ public class XmlFileWriter : IFileWriter
176
265
  {
177
266
  // version doesn't match; use `VersionOverride` attribute on new element
178
267
  _logger.Info($"Dependency {requiredPackageVersion.Name} set to {requiredVersion}; using `{VersionOverrideMetadataName}` attribute on new element.");
179
- newElement.SetAttributeValue(VersionOverrideMetadataName, requiredVersion.ToString());
268
+ newElement = (IXmlElementSyntax)ReplaceNode(
269
+ projectRelativePath,
270
+ newElement.AsNode,
271
+ newElement.WithAttribute(VersionOverrideMetadataName, requiredVersion.ToString()).AsNode
272
+ );
180
273
  }
181
274
  }
182
275
  else
183
276
  {
184
277
  // no matching `<PackageVersion>` element; either add a new one, or directly set the `Version` attribute on the new element
185
- var allPackageVersionElements = filesAndContents.Values
186
- .SelectMany(doc => doc.Descendants().Where(e => e.Name.LocalName.Equals(PackageVersionElementName, StringComparison.OrdinalIgnoreCase)))
278
+ var allPackageVersionElementsAndPaths = filesAndContents
279
+ .SelectMany(kvp =>
280
+ {
281
+ var path = kvp.Key;
282
+ var doc = kvp.Value;
283
+ return doc.Descendants()
284
+ .Where(e => e.Name.Equals(PackageVersionElementName, StringComparison.OrdinalIgnoreCase))
285
+ .Select(element => KeyValuePair.Create(element, path));
286
+ })
187
287
  .ToArray();
188
- if (allPackageVersionElements.Length > 0)
288
+ if (allPackageVersionElementsAndPaths.Length > 0)
189
289
  {
190
290
  // add a new `<PackageVersion>` element
191
- var newVersionElement = new XElement(XName.Get(PackageVersionElementName, projectDocument.Root.Name.NamespaceName),
192
- new XAttribute(IncludeAttributeName, requiredPackageVersion.Name),
193
- new XAttribute(VersionMetadataName, requiredVersion.ToString()));
194
- var lastPriorPackageVersionElement = allPackageVersionElements
195
- .TakeWhile(e => (e.Attribute(IncludeAttributeName)?.Value ?? string.Empty).Trim().CompareTo(requiredPackageVersion.Name) < 0)
196
- .LastOrDefault();
197
- if (lastPriorPackageVersionElement is not null)
291
+ var newVersionElement = XmlExtensions.CreateSingleLineXmlElementSyntax(PackageVersionElementName)
292
+ .WithAttribute(IncludeAttributeName, requiredPackageVersion.Name)
293
+ .WithAttribute(VersionMetadataName, requiredVersion.ToString());
294
+ var priorPackageVersionElementsAndPaths = allPackageVersionElementsAndPaths
295
+ .TakeWhile(pair => (pair.Key.GetAttributeValue(IncludeAttributeName) ?? string.Empty).Trim().CompareTo(requiredPackageVersion.Name) < 0)
296
+ .ToArray();
297
+ if (priorPackageVersionElementsAndPaths.Length > 0)
198
298
  {
199
299
  _logger.Info($"Adding new `<{PackageVersionElementName}>` element for {requiredPackageVersion.Name} with version {requiredVersion}.");
200
- AddAfterSiblingElement(lastPriorPackageVersionElement, newVersionElement);
300
+ var (lastPriorPackageVersionElement, filePath) = priorPackageVersionElementsAndPaths.Last();
301
+ var trivia = lastPriorPackageVersionElement.AsNode.GetLeadingTrivia().ToList();
302
+ var priorEolIndex = trivia.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
303
+ var indentTrivia = trivia
304
+ .Skip(priorEolIndex + 1)
305
+ .Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
306
+ .ToArray();
307
+ var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), .. indentTrivia]);
308
+ newVersionElement = (IXmlElementSyntax)newVersionElement.AsNode.WithLeadingTrivia(newTrivia).WithoutTrailingTrivia();
309
+ var insertionIndex = lastPriorPackageVersionElement.Parent.Content.IndexOf(lastPriorPackageVersionElement.AsNode) + 1;
310
+ var replacementParent = lastPriorPackageVersionElement.Parent
311
+ .InsertChild(newVersionElement, insertionIndex);
312
+ var actualReplacementParent = ReplaceNode(filePath, lastPriorPackageVersionElement.Parent.AsNode, replacementParent.AsNode);
313
+ var actualNewElement = ((IXmlElementSyntax)actualReplacementParent).Content[insertionIndex];
314
+ newVersionElement = (IXmlElementSyntax)actualNewElement;
201
315
  }
202
316
  else
203
317
  {
204
318
  // no prior package versions; add to the front of the document
205
319
  _logger.Info($"Adding new `<{PackageVersionElementName}>` element for {requiredPackageVersion.Name} with version {requiredVersion} at the start of the document.");
206
- var packageVersionGroup = allPackageVersionElements.First().Parent!;
207
- var indent = GetIndentXTextFromElement(packageVersionGroup, extraIndentationToAdd: " ");
208
- packageVersionGroup.AddFirst(indent, newVersionElement);
320
+ var (packageVersionGroup, filePath) = allPackageVersionElementsAndPaths.First();
321
+ packageVersionGroup = packageVersionGroup.Parent;
322
+ var itemGroupTrivia = packageVersionGroup.AsNode.GetLeadingTrivia().ToList();
323
+ var priorEolIndex = itemGroupTrivia.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
324
+ var indentTrivia = itemGroupTrivia
325
+ .Skip(priorEolIndex + 1)
326
+ .Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
327
+ .ToArray();
328
+ var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(" "), .. indentTrivia]);
329
+ newVersionElement = (IXmlElementSyntax)newVersionElement.AsNode.WithLeadingTrivia(newTrivia).WithoutTrailingTrivia();
330
+ var insertionIndex = 0;
331
+ var replacementPackageVersionGroup = packageVersionGroup
332
+ .InsertChild(newVersionElement, insertionIndex);
333
+ ReplaceNode(
334
+ filePath,
335
+ packageVersionGroup.AsNode,
336
+ replacementPackageVersionGroup.AsNode
337
+ );
209
338
  }
210
339
  }
211
340
  else
212
341
  {
213
342
  // add a direct `Version` attribute
214
- newElement.SetAttributeValue(VersionMetadataName, requiredVersion.ToString());
343
+ var newElementWithVersion = newElement.WithAttribute(VersionMetadataName, requiredVersion.ToString());
344
+ newElement = (IXmlElementSyntax)ReplaceNode(projectRelativePath, newElement.AsNode, newElementWithVersion.AsNode);
215
345
  }
216
346
  }
217
347
  }
218
348
  else
219
349
  {
220
350
  // found matching `<PackageReference>` elements to update
221
- foreach (var packageReferenceElement in packageReferenceElements)
351
+ foreach (var (packageReferenceElement, filePath) in packageReferenceElementsAndPaths)
222
352
  {
223
353
  // first check for matching `Version` attribute
224
- var versionAttribute = packageReferenceElement.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
354
+ var versionAttribute = packageReferenceElement.GetAttribute(VersionMetadataName, StringComparison.OrdinalIgnoreCase);
225
355
  if (versionAttribute is not null)
226
356
  {
227
357
  currentVersionString = versionAttribute.Value;
228
- updateVersionLocation = (version) => versionAttribute.Value = version;
358
+ updateVersionLocation = version =>
359
+ {
360
+ var refoundVersionAttribute = filesAndContents[filePath]
361
+ .DescendantNodes()
362
+ .OfType<XmlAttributeSyntax>()
363
+ .First(a => a.FullSpan.Start == versionAttribute.FullSpan.Start);
364
+ ReplaceNode(filePath, refoundVersionAttribute, refoundVersionAttribute.WithValue(version));
365
+ };
229
366
  goto doVersionUpdate;
230
367
  }
231
368
 
232
369
  // next check for `Version` child element
233
- var versionElement = packageReferenceElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
370
+ var versionElement = packageReferenceElement.Elements.FirstOrDefault(e => e.Name.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
234
371
  if (versionElement is not null)
235
372
  {
236
- currentVersionString = versionElement.Value;
237
- updateVersionLocation = (version) => versionElement.Value = version;
373
+ currentVersionString = versionElement.GetContentValue();
374
+ updateVersionLocation = version =>
375
+ {
376
+ var refoundVersionElement = filesAndContents[filePath]
377
+ .DescendantNodes()
378
+ .OfType<IXmlElementSyntax>()
379
+ .First(e => e.AsNode.FullSpan.Start == versionElement.AsNode.FullSpan.Start);
380
+ ReplaceNode(filePath, refoundVersionElement.AsNode, refoundVersionElement.WithContent(version).AsNode);
381
+ };
238
382
  goto doVersionUpdate;
239
383
  }
240
384
 
241
385
  // check for matching `<PackageVersion>` element
242
- var packageVersionElement = filesAndContents.Values
243
- .SelectMany(doc => doc.Descendants().Where(e => e.Name.LocalName == PackageVersionElementName))
244
- .FirstOrDefault(e => (e.Attribute(IncludeAttributeName)?.Value ?? string.Empty).Trim().Equals(requiredPackageVersion.Name, StringComparison.OrdinalIgnoreCase));
245
- if (packageVersionElement is not null)
386
+ var packageVersionElementsAndPaths = filesAndContents
387
+ .SelectMany(kvp =>
388
+ {
389
+ var path = kvp.Key;
390
+ var doc = kvp.Value;
391
+ return doc.Descendants()
392
+ .Where(e => e.Name.Equals(PackageVersionElementName, StringComparison.OrdinalIgnoreCase))
393
+ .Where(e => (e.GetAttributeValue(IncludeAttributeName) ?? string.Empty).Trim().Equals(requiredPackageVersion.Name, StringComparison.OrdinalIgnoreCase))
394
+ .Select(element => KeyValuePair.Create(element, path));
395
+ })
396
+ .ToArray();
397
+ if (packageVersionElementsAndPaths.Length > 0)
246
398
  {
247
- var packageVersionAttribute = packageVersionElement.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
399
+ var (packageVersionElement, packageVersionFilePath) = packageVersionElementsAndPaths.First();
400
+ var packageVersionAttribute = packageVersionElement.GetAttributeCaseInsensitive(VersionMetadataName);
248
401
  if (packageVersionAttribute is not null)
249
402
  {
250
403
  currentVersionString = packageVersionAttribute.Value;
251
- updateVersionLocation = (version) => packageVersionAttribute.Value = version;
404
+ updateVersionLocation = version => ReplaceNode(packageVersionFilePath, packageVersionAttribute, packageVersionAttribute.WithValue(version));
252
405
  goto doVersionUpdate;
253
406
  }
254
407
  else
255
408
  {
256
- var cpmVersionElement = packageVersionElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals(VersionMetadataName, StringComparison.OrdinalIgnoreCase));
409
+ var cpmVersionElement = packageVersionElement.GetElements(VersionMetadataName, StringComparison.OrdinalIgnoreCase).FirstOrDefault();
257
410
  if (cpmVersionElement is not null)
258
411
  {
259
- currentVersionString = cpmVersionElement.Value;
260
- updateVersionLocation = (version) => cpmVersionElement.Value = version;
412
+ currentVersionString = cpmVersionElement.GetContentValue();
413
+ updateVersionLocation = version => ReplaceNode(packageVersionFilePath, cpmVersionElement.AsNode, cpmVersionElement.WithContent(version).AsNode);
261
414
  goto doVersionUpdate;
262
415
  }
263
416
  }
@@ -345,13 +498,21 @@ public class XmlFileWriter : IFileWriter
345
498
  {
346
499
  // this looks like a property; keep walking backwards with all possible elements
347
500
  var propertyName = propertyMatch.Groups["PropertyName"].Value;
348
- var propertyDefinitions = filesAndContents.Values
349
- .SelectMany(doc => doc.Descendants().Where(e => e.Name.LocalName.Equals(propertyName, StringComparison.OrdinalIgnoreCase)))
350
- .Where(e => e.Parent?.Name.LocalName.Equals(PropertyGroupElementName, StringComparison.OrdinalIgnoreCase) == true)
501
+ var propertyDefinitionsAndPaths = filesAndContents
502
+ .SelectMany(kvp =>
503
+ {
504
+ var path = kvp.Key;
505
+ var doc = kvp.Value;
506
+ return doc.Descendants()
507
+ .Where(e => e.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
508
+ .Where(e => e.Parent?.Name.Equals(PropertyGroupElementName, StringComparison.OrdinalIgnoreCase) == true)
509
+ .Select(element => KeyValuePair.Create(element, path));
510
+ })
351
511
  .ToArray();
352
- foreach (var propertyDefinition in propertyDefinitions)
512
+ foreach (var (propertyDefinition, propertyFilePath) in propertyDefinitionsAndPaths)
353
513
  {
354
- candidateUpdateLocations.Enqueue((propertyDefinition.Value, (version) => propertyDefinition.Value = version));
514
+ var updateAction = new Action<string>(version => ReplaceNode(propertyFilePath, propertyDefinition.AsNode, propertyDefinition.WithContent(version).AsNode));
515
+ candidateUpdateLocations.Enqueue((propertyDefinition.GetContentValue(), updateAction));
355
516
  }
356
517
  }
357
518
  }
@@ -377,73 +538,32 @@ public class XmlFileWriter : IFileWriter
377
538
  return performedAllUpdates;
378
539
  }
379
540
 
380
- private static XText? GetIndentXTextFromElement(XElement element, string extraIndentationToAdd = "")
381
- {
382
- var indentText = (element.PreviousNode as XText)?.Value;
383
- var indent = indentText is not null
384
- ? new XText(indentText + extraIndentationToAdd)
385
- : null;
386
- return indent;
387
- }
388
-
389
- private static void AddAfterSiblingElement(XElement siblingElement, XElement newElement, string extraIndentationToAdd = "")
541
+ private static ImmutableArray<SyntaxNode> GetOrderedElementsBeforeSpecified(IXmlElementSyntax parentElement, string elementName, IEnumerable<string> attributeNamesToCheck, string attributeValue)
390
542
  {
391
- var indent = GetIndentXTextFromElement(siblingElement, extraIndentationToAdd);
392
- XNode nodeToAddAfter = siblingElement;
393
- var done = false;
394
- while (!done && nodeToAddAfter.NextNode is not null)
395
- {
396
- // skip over XText and XComment nodes until we find a newline
397
- switch (nodeToAddAfter.NextNode)
398
- {
399
- case XText text:
400
- if (text.Value.Contains('\n'))
401
- {
402
- done = true;
403
- }
404
- else
405
- {
406
- nodeToAddAfter = nodeToAddAfter.NextNode;
407
- }
408
-
409
- break;
410
- case XComment comment:
411
- if (comment.Value.Contains('\n'))
412
- {
413
- done = true;
414
- }
415
- else
416
- {
417
- nodeToAddAfter = nodeToAddAfter.NextNode;
418
- }
419
-
420
- break;
421
- default:
422
- done = true;
423
- break;
424
- }
425
- }
426
-
427
- nodeToAddAfter.AddAfterSelf(indent, newElement);
543
+ var elementsBeforeNew = parentElement.Content
544
+ .TakeWhile(
545
+ e => e is XmlCommentSyntax ||
546
+ (e is IXmlElementSyntax element &&
547
+ element.Name.Equals(elementName, StringComparison.OrdinalIgnoreCase) &&
548
+ (attributeNamesToCheck.Select(attributeName => element.GetAttributeValue(attributeName)).FirstOrDefault(value => value is not null) ?? string.Empty)
549
+ .CompareTo(attributeValue) < 0))
550
+ .ToImmutableArray();
551
+ return elementsBeforeNew;
428
552
  }
429
553
 
430
- private static async Task<string> ReadFileContentsAsync(DirectoryInfo repoContentsPath, string path)
554
+ private static async Task<XmlDocumentSyntax> ReadFileContentsAsync(DirectoryInfo repoContentsPath, string path)
431
555
  {
432
556
  var fullPath = Path.Join(repoContentsPath.FullName, path);
433
557
  var contents = await File.ReadAllTextAsync(fullPath);
434
- return contents;
558
+ var document = Parser.ParseText(contents);
559
+ return document;
435
560
  }
436
561
 
437
- private static async Task WriteFileContentsAsync(DirectoryInfo repoContentsPath, string path, XDocument document)
562
+ private static async Task WriteFileContentsAsync(DirectoryInfo repoContentsPath, string path, XmlDocumentSyntax document)
438
563
  {
439
564
  var fullPath = Path.Join(repoContentsPath.FullName, path);
440
- var writerSettings = new XmlWriterSettings()
441
- {
442
- Async = true,
443
- OmitXmlDeclaration = document.Declaration is null,
444
- };
445
- using var writer = XmlWriter.Create(fullPath, writerSettings);
446
- await document.SaveAsync(writer, CancellationToken.None);
565
+ var content = document.ToFullString();
566
+ await File.WriteAllTextAsync(fullPath, content);
447
567
  }
448
568
 
449
569
  public static string CreateUpdatedVersionRangeString(VersionRange existingRange, NuGetVersion existingVersion, NuGetVersion requiredVersion)
@@ -1,5 +1,3 @@
1
- using NuGetUpdater.Core.Updater;
2
-
3
1
  namespace NuGetUpdater.Core;
4
2
 
5
3
  internal static class LockFileUpdater
@@ -7,18 +5,13 @@ internal static class LockFileUpdater
7
5
  public static async Task UpdateLockFileAsync(
8
6
  string repoRootPath,
9
7
  string projectPath,
10
- ExperimentsManager experimentsManager,
11
8
  ILogger logger)
12
9
  {
13
10
  var projectDirectory = Path.GetDirectoryName(projectPath)!;
14
- await MSBuildHelper.HandleGlobalJsonAsync(projectDirectory, repoRootPath, experimentsManager, async () =>
11
+ var (exitCode, stdout, stderr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", "--force-evaluate", "-p:EnableWindowsTargeting=true", projectPath], projectDirectory);
12
+ if (exitCode != 0)
15
13
  {
16
- var (exitCode, stdout, stderr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", "--force-evaluate", "-p:EnableWindowsTargeting=true", projectPath], projectDirectory, experimentsManager);
17
- if (exitCode != 0)
18
- {
19
- logger.Error($" Lock file update failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
20
- }
21
- return (exitCode, stdout, stderr);
22
- }, logger, retainMSBuildSdks: true);
14
+ logger.Error($" Lock file update failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
15
+ }
23
16
  }
24
17
  }
@@ -29,7 +29,6 @@ internal static class PackageReferenceUpdater
29
29
  ImmutableArray<Dependency> topLevelDependencies,
30
30
  ImmutableArray<Dependency> requestedUpdates,
31
31
  ImmutableArray<Dependency> resolvedDependencies,
32
- ExperimentsManager experimentsManager,
33
32
  ILogger logger
34
33
  )
35
34
  {
@@ -41,7 +40,7 @@ internal static class PackageReferenceUpdater
41
40
  .Where(d => d.Item2)
42
41
  .ToDictionary(d => d.Item1, d => d.Item3!, StringComparer.OrdinalIgnoreCase);
43
42
 
44
- var (packageParents, packageVersions) = await GetPackageGraphForDependencies(repoRoot, projectPath, targetFramework, resolvedDependencies, experimentsManager, logger);
43
+ var (packageParents, packageVersions) = await GetPackageGraphForDependencies(repoRoot, projectPath, targetFramework, resolvedDependencies, logger);
45
44
  var updateOperations = new List<UpdateOperationBase>();
46
45
  foreach (var (requestedDependencyName, requestedDependencyVersion) in requestedVersions)
47
46
  {
@@ -109,7 +108,7 @@ internal static class PackageReferenceUpdater
109
108
  return [.. updateOperations];
110
109
  }
111
110
 
112
- private static async Task<(Dictionary<string, HashSet<string>> PackageParents, Dictionary<string, NuGetVersion> PackageVersions)> GetPackageGraphForDependencies(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> topLevelDependencies, ExperimentsManager experimentsManager, ILogger logger)
111
+ private static async Task<(Dictionary<string, HashSet<string>> PackageParents, Dictionary<string, NuGetVersion> PackageVersions)> GetPackageGraphForDependencies(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> topLevelDependencies, ILogger logger)
113
112
  {
114
113
  var packageParents = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
115
114
  var packageVersions = new Dictionary<string, NuGetVersion>(StringComparer.OrdinalIgnoreCase);
@@ -118,8 +117,8 @@ internal static class PackageReferenceUpdater
118
117
  {
119
118
  // generate project.assets.json
120
119
  var parsedTargetFramework = NuGetFramework.Parse(targetFramework);
121
- var tempProject = await MSBuildHelper.CreateTempProjectAsync(tempDir, repoRoot, projectPath, targetFramework, topLevelDependencies, experimentsManager, logger, importDependencyTargets: false);
122
- var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["build", tempProject, "/t:_ReportDependencies"], tempDir.FullName, experimentsManager);
120
+ var tempProject = await MSBuildHelper.CreateTempProjectAsync(tempDir, repoRoot, projectPath, targetFramework, topLevelDependencies, logger, importDependencyTargets: false);
121
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["build", tempProject, "/t:_ReportDependencies"], tempDir.FullName);
123
122
  var assetsJsonPath = Path.Join(tempDir.FullName, "obj", "project.assets.json");
124
123
  var assetsJsonContent = await File.ReadAllTextAsync(assetsJsonPath);
125
124
 
@@ -77,7 +77,7 @@ public class UpdaterWorker : IUpdaterWorker
77
77
 
78
78
  var worker = new FileWriterWorker(
79
79
  new DiscoveryWorker(_jobId, _experimentsManager, _logger),
80
- new MSBuildDependencySolver(new DirectoryInfo(repoRootPath), new FileInfo(workspacePath), _experimentsManager, _logger),
80
+ new MSBuildDependencySolver(new DirectoryInfo(repoRootPath), new FileInfo(workspacePath), _logger),
81
81
  new XmlFileWriter(_logger),
82
82
  _logger
83
83
  );
@@ -460,7 +460,7 @@ public class PackageManager
460
460
  string currentVersionString = parent.CurrentVersion;
461
461
  NuGetVersion currentVersionParent = NuGetVersion.Parse(currentVersionString);
462
462
 
463
- var result = await VersionFinder.GetVersionsAsync([projectFramework], parent.PackageName, currentVersionParent, nugetContext, logger, CancellationToken.None);
463
+ var result = await VersionFinder.GetVersionsByNameAsync([projectFramework], parent.PackageName, currentVersionParent, nugetContext, logger, CancellationToken.None);
464
464
  var versions = result.GetVersions();
465
465
  NuGetVersion latestVersion = versions.Where(v => !v.IsPrerelease).Max();
466
466
 
@@ -550,7 +550,7 @@ public class PackageManager
550
550
  NuGetContext nugetContext = new NuGetContext(Path.GetDirectoryName(projectPath));
551
551
  var projectFramework = NuGetFramework.Parse(targetFramework);
552
552
 
553
- var result = await VersionFinder.GetVersionsAsync([projectFramework], possibleParent.PackageName, CurrentVersion, nugetContext, logger, CancellationToken.None);
553
+ var result = await VersionFinder.GetVersionsByNameAsync([projectFramework], possibleParent.PackageName, CurrentVersion, nugetContext, logger, CancellationToken.None);
554
554
  var versions = result.GetVersions();
555
555
 
556
556
  // If there are no versions