dependabot-nuget 0.252.0 → 0.254.0

Sign up to get free protection for your applications and to get access to all the features.
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