dependabot-nuget 0.252.0 → 0.254.0

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +27 -9
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +1 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +66 -65
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +21 -5
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +44 -6
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +4 -3
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +181 -93
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +18 -13
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +24 -6
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +18 -10
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +25 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +10 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +1 -8
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +1 -1
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +0 -5
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +0 -5
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +0 -5
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +0 -5
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +55 -4
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +30 -23
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/JsonHelperTests.cs +57 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +44 -9
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/SdkPackageUpdaterHelperTests.cs +1 -1
  26. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +0 -2
  27. data/lib/dependabot/nuget/file_parser.rb +14 -6
  28. metadata +16 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6658fe5d81acc16548fe2d8fa0aa6ad631e0699588a4595e6b8de2f382a163d8
4
- data.tar.gz: 3ced8b77f453319a715b76ccff47787a8798cb92366fe6a86d6894b855a984bf
3
+ metadata.gz: c86cede5ca7a7c4b299c2ec8562eedac9a80f12b3d3087be4270b37f21a41861
4
+ data.tar.gz: 8ea3c1c970f4606fed97261c70ebd493645037bdd635ab4368e38956ab1d17f9
5
5
  SHA512:
6
- metadata.gz: 958fba1507fdc26ec2e0bc3978702b9103543558552c79188e7cca93b85248f46c1d485686da353076fbab234ea150cc1bb7e11231a1765e87071cf068b2e95c
7
- data.tar.gz: 5262c02eeff331fbf8c1399ec2d8fc49bd8942f83f2c1d67a4c9f48a3c7515b0f52710cb5e9f1409c23b025719cbb68d6c43ea2db44f15fe9aa353d80a5b1bd8
6
+ metadata.gz: 26ee476b689434e34f322153afc7f825e15555bf7c7061014e4b58bdb5962699226942ac64797d436d38b5aed780d4e57d818bd7ef64f6ed6e1961984129139e
7
+ data.tar.gz: 28e0103dbcb88c4fabb9352a51891f0f69a0533959c7fe052c8b3396c00fcabfe33ae1d3cb28347ffc44f01464c8517397a11783c0c88a66e4bd04fd9f5b37e3
@@ -293,22 +293,30 @@ public partial class EntryPointTests
293
293
  );
294
294
  }
295
295
 
296
- [Fact]
297
- public async Task UpdaterDoesNotUseRepoGlobalJsonForMSBuildTasks()
296
+ [Theory]
297
+ [InlineData(null)]
298
+ [InlineData("src")]
299
+ public async Task UpdaterDoesNotUseRepoGlobalJsonForMSBuildTasks(string? workingDirectoryPath)
298
300
  {
299
301
  // This is a _very_ specific scenario where the `NuGetUpdater.Cli` tool might pick up a `global.json` from
300
302
  // the root of the repo under test and use it's `sdk` property when trying to locate MSBuild. To properly
301
303
  // test this, it must be tested in a new process where MSBuild has not been loaded yet and the runner tool
302
304
  // must be started with its working directory at the test repo's root.
303
305
  using var tempDir = new TemporaryDirectory();
304
- await File.WriteAllTextAsync(Path.Join(tempDir.DirectoryPath, "global.json"), """
306
+ var globalJsonPath = Path.Join(tempDir.DirectoryPath, "global.json");
307
+ var srcGlobalJsonPath = Path.Join(tempDir.DirectoryPath, "src", "global.json");
308
+ string globalJsonContent = """
305
309
  {
306
310
  "sdk": {
307
311
  "version": "99.99.99"
308
312
  }
309
313
  }
310
- """);
311
- await File.WriteAllTextAsync(Path.Join(tempDir.DirectoryPath, "project.csproj"), """
314
+ """;
315
+ await File.WriteAllTextAsync(globalJsonPath, globalJsonContent);
316
+ Directory.CreateDirectory(Path.Join(tempDir.DirectoryPath, "src"));
317
+ await File.WriteAllTextAsync(srcGlobalJsonPath, globalJsonContent);
318
+ var projectPath = Path.Join(tempDir.DirectoryPath, "src", "project.csproj");
319
+ await File.WriteAllTextAsync(projectPath, """
312
320
  <Project Sdk="Microsoft.NET.Sdk">
313
321
  <PropertyGroup>
314
322
  <TargetFramework>net8.0</TargetFramework>
@@ -325,7 +333,7 @@ public partial class EntryPointTests
325
333
  "--repo-root",
326
334
  tempDir.DirectoryPath,
327
335
  "--solution-or-project",
328
- Path.Join(tempDir.DirectoryPath, "project.csproj"),
336
+ projectPath,
329
337
  "--dependency",
330
338
  "Newtonsoft.Json",
331
339
  "--new-version",
@@ -336,15 +344,25 @@ public partial class EntryPointTests
336
344
  ]);
337
345
 
338
346
  // verify base run
339
- var (exitCode, output, error) = await ProcessEx.RunAsync(executableName, executableArgs, workingDirectory: tempDir.DirectoryPath);
347
+ var workingDirectory = tempDir.DirectoryPath;
348
+ if (workingDirectoryPath is not null)
349
+ {
350
+ workingDirectory = Path.Join(workingDirectory, workingDirectoryPath);
351
+ }
352
+
353
+ var (exitCode, output, error) = await ProcessEx.RunAsync(executableName, executableArgs, workingDirectory: workingDirectory);
340
354
  Assert.True(exitCode == 0, $"Error running update on unsupported SDK.\nSTDOUT:\n{output}\nSTDERR:\n{error}");
341
355
 
342
356
  // verify project update
343
- var updatedProjectContents = await File.ReadAllTextAsync(Path.Join(tempDir.DirectoryPath, "project.csproj"));
357
+ var updatedProjectContents = await File.ReadAllTextAsync(projectPath);
344
358
  Assert.Contains("13.0.1", updatedProjectContents);
345
359
 
346
360
  // verify `global.json` untouched
347
- var updatedGlobalJsonContents = await File.ReadAllTextAsync(Path.Join(tempDir.DirectoryPath, "global.json"));
361
+ var updatedGlobalJsonContents = await File.ReadAllTextAsync(globalJsonPath);
362
+ Assert.Contains("99.99.99", updatedGlobalJsonContents);
363
+
364
+ // verify `src/global.json` untouched
365
+ var updatedSrcGlobalJsonContents = await File.ReadAllTextAsync(srcGlobalJsonPath);
348
366
  Assert.Contains("99.99.99", updatedGlobalJsonContents);
349
367
  }
350
368
 
@@ -26,7 +26,7 @@ public partial class DiscoveryWorker
26
26
 
27
27
  public async Task RunAsync(string repoRootPath, string workspacePath, string outputPath)
28
28
  {
29
- MSBuildHelper.RegisterMSBuild();
29
+ MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, repoRootPath);
30
30
 
31
31
  // When running under unit tests, the workspace path may not be rooted.
32
32
  if (!Path.IsPathRooted(workspacePath) || !Directory.Exists(workspacePath))
@@ -9,86 +9,87 @@ internal static class SdkProjectDiscovery
9
9
  public static async Task<ImmutableArray<ProjectDiscoveryResult>> DiscoverAsync(string repoRootPath, string workspacePath, string projectPath, Logger logger)
10
10
  {
11
11
  // Determine which targets and props files contribute to the build.
12
- var buildFiles = await MSBuildHelper.LoadBuildFilesAsync(repoRootPath, projectPath, includeSdkPropsAndTargets: true);
12
+ var (buildFiles, projectTargetFrameworks) = await MSBuildHelper.LoadBuildFilesAndTargetFrameworksAsync(repoRootPath, projectPath);
13
+ var tfms = projectTargetFrameworks.Order().ToImmutableArray();
13
14
 
14
15
  // Get all the dependencies which are directly referenced from the project file or indirectly referenced from
15
16
  // targets and props files.
16
17
  var topLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles);
17
18
 
18
19
  var results = ImmutableArray.CreateBuilder<ProjectDiscoveryResult>();
19
- foreach (var buildFile in buildFiles)
20
+ if (tfms.Length > 0)
20
21
  {
21
- // Only include build files that exist beneath the RepoRootPath.
22
- if (buildFile.IsOutsideBasePath)
22
+ foreach (var buildFile in buildFiles)
23
23
  {
24
- continue;
25
- }
26
-
27
- // The build file dependencies have the correct DependencyType and the TopLevelDependencies have the evaluated version.
28
- // Combine them to have the set of dependencies that are directly referenced from the build file.
29
- var fileDependencies = BuildFile.GetDependencies(buildFile)
30
- .ToDictionary(d => d.Name, StringComparer.OrdinalIgnoreCase);
31
- var sdkDependencies = fileDependencies.Values
32
- .Where(d => d.Type == DependencyType.MSBuildSdk)
33
- .ToImmutableArray();
34
- var indirectDependencies = topLevelDependencies
35
- .Where(d => !fileDependencies.ContainsKey(d.Name))
36
- .ToImmutableArray();
37
- var directDependencies = topLevelDependencies
38
- .Where(d => fileDependencies.ContainsKey(d.Name))
39
- .Select(d =>
24
+ // Only include build files that exist beneath the RepoRootPath.
25
+ if (buildFile.IsOutsideBasePath)
40
26
  {
41
- var dependency = fileDependencies[d.Name];
42
- return d with
43
- {
44
- Type = dependency.Type,
45
- IsDirect = true
46
- };
47
- }).ToImmutableArray();
48
-
49
- if (buildFile.GetFileType() == ProjectBuildFileType.Project)
50
- {
51
- // Collect information that is specific to the project file.
52
- var tfms = MSBuildHelper.GetTargetFrameworkMonikers(buildFiles)
53
- .OrderBy(tfm => tfm)
54
- .ToImmutableArray();
55
- var properties = MSBuildHelper.GetProperties(buildFiles).Values
56
- .Where(p => !p.SourceFilePath.StartsWith(".."))
57
- .OrderBy(p => p.Name)
58
- .ToImmutableArray();
59
- var referencedProjectPaths = MSBuildHelper.GetProjectPathsFromProject(projectPath)
60
- .Select(path => Path.GetRelativePath(workspacePath, path))
61
- .OrderBy(p => p)
62
- .ToImmutableArray();
27
+ continue;
28
+ }
63
29
 
64
- // Get the complete set of dependencies including transitive dependencies.
65
- var dependencies = indirectDependencies.Concat(directDependencies).ToImmutableArray();
66
- dependencies = dependencies
67
- .Select(d => d with { TargetFrameworks = tfms })
30
+ // The build file dependencies have the correct DependencyType and the TopLevelDependencies have the evaluated version.
31
+ // Combine them to have the set of dependencies that are directly referenced from the build file.
32
+ var fileDependencies = BuildFile.GetDependencies(buildFile)
33
+ .ToDictionary(d => d.Name, StringComparer.OrdinalIgnoreCase);
34
+ var sdkDependencies = fileDependencies.Values
35
+ .Where(d => d.Type == DependencyType.MSBuildSdk)
68
36
  .ToImmutableArray();
69
- var transitiveDependencies = await GetTransitiveDependencies(repoRootPath, projectPath, tfms, dependencies, logger);
70
- ImmutableArray<Dependency> allDependencies = dependencies.Concat(transitiveDependencies).Concat(sdkDependencies)
71
- .OrderBy(d => d.Name)
37
+ var indirectDependencies = topLevelDependencies
38
+ .Where(d => !fileDependencies.ContainsKey(d.Name))
72
39
  .ToImmutableArray();
40
+ var directDependencies = topLevelDependencies
41
+ .Where(d => fileDependencies.ContainsKey(d.Name))
42
+ .Select(d =>
43
+ {
44
+ var dependency = fileDependencies[d.Name];
45
+ return d with
46
+ {
47
+ Type = dependency.Type,
48
+ IsDirect = true
49
+ };
50
+ }).ToImmutableArray();
73
51
 
74
- results.Add(new()
52
+ if (buildFile.GetFileType() == ProjectBuildFileType.Project)
75
53
  {
76
- FilePath = Path.GetRelativePath(workspacePath, buildFile.Path),
77
- Properties = properties,
78
- TargetFrameworks = tfms,
79
- ReferencedProjectPaths = referencedProjectPaths,
80
- Dependencies = allDependencies,
81
- });
82
- }
83
- else
84
- {
85
- results.Add(new()
86
- {
87
- FilePath = Path.GetRelativePath(workspacePath, buildFile.Path),
88
- Dependencies = directDependencies.Concat(sdkDependencies)
54
+ // Collect information that is specific to the project file.
55
+ var properties = MSBuildHelper.GetProperties(buildFiles).Values
56
+ .Where(p => !p.SourceFilePath.StartsWith(".."))
57
+ .OrderBy(p => p.Name)
58
+ .ToImmutableArray();
59
+ var referencedProjectPaths = MSBuildHelper.GetProjectPathsFromProject(projectPath)
60
+ .Select(path => Path.GetRelativePath(workspacePath, path))
61
+ .OrderBy(p => p)
62
+ .ToImmutableArray();
63
+
64
+ // Get the complete set of dependencies including transitive dependencies.
65
+ var dependencies = indirectDependencies.Concat(directDependencies).ToImmutableArray();
66
+ dependencies = dependencies
67
+ .Select(d => d with { TargetFrameworks = tfms })
68
+ .ToImmutableArray();
69
+ var transitiveDependencies = await GetTransitiveDependencies(repoRootPath, projectPath, tfms, dependencies, logger);
70
+ ImmutableArray<Dependency> allDependencies = dependencies.Concat(transitiveDependencies).Concat(sdkDependencies)
89
71
  .OrderBy(d => d.Name)
90
- .ToImmutableArray(),
91
- });
72
+ .ToImmutableArray();
73
+
74
+ results.Add(new()
75
+ {
76
+ FilePath = Path.GetRelativePath(workspacePath, buildFile.Path),
77
+ Properties = properties,
78
+ TargetFrameworks = tfms,
79
+ ReferencedProjectPaths = referencedProjectPaths,
80
+ Dependencies = allDependencies,
81
+ });
82
+ }
83
+ else
84
+ {
85
+ results.Add(new()
86
+ {
87
+ FilePath = Path.GetRelativePath(workspacePath, buildFile.Path),
88
+ Dependencies = directDependencies.Concat(sdkDependencies)
89
+ .OrderBy(d => d.Name)
90
+ .ToImmutableArray(),
91
+ });
92
+ }
92
93
  }
93
94
  }
94
95
 
@@ -174,11 +174,7 @@ internal static class PackagesConfigUpdater
174
174
  var hintPathSubString = $"{dependencyName}.{dependencyVersion}";
175
175
 
176
176
  string? partialPathMatch = null;
177
- var hintPathNodes = projectBuildFile.Contents.Descendants()
178
- .Where(e =>
179
- e.Name.Equals("HintPath", StringComparison.OrdinalIgnoreCase) &&
180
- e.Parent.Name.Equals("Reference", StringComparison.OrdinalIgnoreCase) &&
181
- e.Parent.GetAttributeValue("Include", StringComparison.OrdinalIgnoreCase)?.StartsWith($"{dependencyName},", StringComparison.OrdinalIgnoreCase) == true);
177
+ var hintPathNodes = projectBuildFile.Contents.Descendants().Where(e => e.IsHintPathNodeForDependency(dependencyName));
182
178
  foreach (var hintPathNode in hintPathNodes)
183
179
  {
184
180
  var hintPath = hintPathNode.GetContentValue();
@@ -210,6 +206,26 @@ internal static class PackagesConfigUpdater
210
206
  return partialPathMatch;
211
207
  }
212
208
 
209
+ private static bool IsHintPathNodeForDependency(this IXmlElementSyntax element, string dependencyName)
210
+ {
211
+ if (element.Name.Equals("HintPath", StringComparison.OrdinalIgnoreCase) &&
212
+ element.Parent.Name.Equals("Reference", StringComparison.OrdinalIgnoreCase))
213
+ {
214
+ // the include attribute will look like one of the following:
215
+ // <Reference Include="Some.Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcd">
216
+ // or
217
+ // <Reference Include="Some.Dependency">
218
+ string includeAttributeValue = element.Parent.GetAttributeValue("Include", StringComparison.OrdinalIgnoreCase);
219
+ if (includeAttributeValue.Equals(dependencyName, StringComparison.OrdinalIgnoreCase) ||
220
+ includeAttributeValue.StartsWith($"{dependencyName},", StringComparison.OrdinalIgnoreCase))
221
+ {
222
+ return true;
223
+ }
224
+ }
225
+
226
+ return false;
227
+ }
228
+
213
229
  private static string GetUpToIndexWithoutTrailingDirectorySeparator(string path, int index)
214
230
  {
215
231
  var subpath = path[..index];
@@ -20,8 +20,7 @@ internal static class SdkPackageUpdater
20
20
  // SDK-style project, modify the XML directly
21
21
  logger.Log(" Running for SDK-style project");
22
22
 
23
- var buildFiles = await MSBuildHelper.LoadBuildFilesAsync(repoRootPath, projectPath);
24
- var tfms = MSBuildHelper.GetTargetFrameworkMonikers(buildFiles);
23
+ (ImmutableArray<ProjectBuildFile> buildFiles, string[] tfms) = await MSBuildHelper.LoadBuildFilesAndTargetFrameworksAsync(repoRootPath, projectPath);
25
24
 
26
25
  // Get the set of all top-level dependencies in the current project
27
26
  var topLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles).ToArray();
@@ -42,7 +41,7 @@ internal static class SdkPackageUpdater
42
41
  return;
43
42
  }
44
43
 
45
- UpdateTopLevelDepdendency(buildFiles, dependencyName, previousDependencyVersion, newDependencyVersion, peerDependencies, logger);
44
+ await UpdateTopLevelDepdendency(repoRootPath, buildFiles, tfms, dependencyName, previousDependencyVersion, newDependencyVersion, peerDependencies, logger);
46
45
  }
47
46
 
48
47
  if (!await AreDependenciesCoherentAsync(repoRootPath, projectPath, dependencyName, logger, buildFiles, tfms))
@@ -226,10 +225,10 @@ internal static class SdkPackageUpdater
226
225
  logger.Log($" Adding [{dependencyName}/{newDependencyVersion}] as a top-level package reference.");
227
226
 
228
227
  // see https://learn.microsoft.com/nuget/consume-packages/install-use-packages-dotnet-cli
229
- var (exitCode, _, _) = await ProcessEx.RunAsync("dotnet", $"add {projectPath} package {dependencyName} --version {newDependencyVersion}", workingDirectory: Path.GetDirectoryName(projectPath));
228
+ var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", $"add {projectPath} package {dependencyName} --version {newDependencyVersion}", workingDirectory: Path.GetDirectoryName(projectPath));
230
229
  if (exitCode != 0)
231
230
  {
232
- logger.Log($" Transitive dependency [{dependencyName}/{newDependencyVersion}] was not added.");
231
+ logger.Log($" Transitive dependency [{dependencyName}/{newDependencyVersion}] was not added.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
233
232
  }
234
233
  }
235
234
 
@@ -288,8 +287,10 @@ internal static class SdkPackageUpdater
288
287
  return packagesAndVersions;
289
288
  }
290
289
 
291
- private static void UpdateTopLevelDepdendency(
290
+ private static async Task UpdateTopLevelDepdendency(
291
+ string repoRootPath,
292
292
  ImmutableArray<ProjectBuildFile> buildFiles,
293
+ string[] targetFrameworks,
293
294
  string dependencyName,
294
295
  string previousDependencyVersion,
295
296
  string newDependencyVersion,
@@ -307,6 +308,43 @@ internal static class SdkPackageUpdater
307
308
  {
308
309
  TryUpdateDependencyVersion(buildFiles, packageName, previousDependencyVersion: null, newDependencyVersion: packageVersion, logger);
309
310
  }
311
+
312
+ // now make all dependency requirements coherent
313
+ Dependency[] updatedTopLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles).ToArray();
314
+ foreach (ProjectBuildFile projectFile in buildFiles)
315
+ {
316
+ foreach (string tfm in targetFrameworks)
317
+ {
318
+ Dependency[]? resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRootPath, projectFile.Path, tfm, updatedTopLevelDependencies, logger);
319
+ if (resolvedDependencies is null)
320
+ {
321
+ logger.Log($" Unable to resolve dependency conflicts for {projectFile.Path}.");
322
+ continue;
323
+ }
324
+
325
+ // ensure the originally requested dependency was resolved to the correct version
326
+ var specificResolvedDependency = resolvedDependencies.Where(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
327
+ if (specificResolvedDependency is null)
328
+ {
329
+ logger.Log($" Unable resolve requested dependency for {dependencyName} in {projectFile.Path}.");
330
+ continue;
331
+ }
332
+
333
+ if (!newDependencyVersion.Equals(specificResolvedDependency.Version, StringComparison.OrdinalIgnoreCase))
334
+ {
335
+ logger.Log($" Inconsistent resolution for {dependencyName}; attempted upgrade to {newDependencyVersion} but resolved {specificResolvedDependency.Version}.");
336
+ continue;
337
+ }
338
+
339
+ // update all other dependencies
340
+ foreach (Dependency resolvedDependency in resolvedDependencies
341
+ .Where(d => !d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase))
342
+ .Where(d => d.Version is not null))
343
+ {
344
+ TryUpdateDependencyVersion(buildFiles, resolvedDependency.Name, previousDependencyVersion: null, newDependencyVersion: resolvedDependency.Version!, logger);
345
+ }
346
+ }
347
+ }
310
348
  }
311
349
 
312
350
  private static UpdateResult TryUpdateDependencyVersion(
@@ -12,7 +12,7 @@ public class UpdaterWorker
12
12
 
13
13
  public async Task RunAsync(string repoRootPath, string workspacePath, string dependencyName, string previousDependencyVersion, string newDependencyVersion, bool isTransitive)
14
14
  {
15
- MSBuildHelper.RegisterMSBuild();
15
+ MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, repoRootPath);
16
16
 
17
17
  if (!Path.IsPathRooted(workspacePath) || !File.Exists(workspacePath))
18
18
  {
@@ -145,13 +145,14 @@ namespace NuGetUpdater.Core.Utilities
145
145
 
146
146
  // single line comments might have had a trailing comma appended by the property writer that we can't
147
147
  // control, so we have to manually correct for it
148
- var originalJsonLines = json.Split('\n').Select(l => l.TrimEnd('\r')).ToArray();
148
+ var originalJsonLines = json.Split('\n').Select(l => l.TrimEnd('\r')).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray();
149
149
  var updatedJsonLines = resultJson.Split('\n').Select(l => l.TrimEnd('\r')).ToArray();
150
150
  for (int i = 0; i < Math.Min(originalJsonLines.Length, updatedJsonLines.Length); i++)
151
151
  {
152
- if (updatedJsonLines[i].EndsWith(",") && !originalJsonLines[i].EndsWith(","))
152
+ var updatedLine = updatedJsonLines[i];
153
+ if (updatedLine.EndsWith(',') && updatedLine.Contains("//", StringComparison.Ordinal) && !originalJsonLines[i].EndsWith(','))
153
154
  {
154
- updatedJsonLines[i] = updatedJsonLines[i][..^1];
155
+ updatedJsonLines[i] = updatedLine[..^1];
155
156
  }
156
157
  }
157
158