dependabot-nuget 0.288.0 → 0.290.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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +19 -17
  3. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +29 -2
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +25 -4
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +33 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +25 -10
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +60 -66
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +11 -3
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +1 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +54 -11
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +1 -2
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +67 -58
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +15 -44
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +2 -10
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +38 -33
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +25 -23
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +18 -17
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +17 -9
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +87 -5
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -5
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +16 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +6 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +143 -36
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +184 -48
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -5
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +32 -10
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +402 -102
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +342 -2
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -14
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  74. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +95 -0
  75. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -7
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +558 -711
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +47 -2
  80. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +4 -2
  81. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  82. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  83. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  84. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  85. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  86. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  87. data/lib/dependabot/nuget/file_fetcher.rb +11 -393
  88. data/lib/dependabot/nuget/file_parser.rb +23 -61
  89. data/lib/dependabot/nuget/file_updater.rb +28 -23
  90. data/lib/dependabot/nuget/native_helpers.rb +14 -5
  91. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  92. data/lib/dependabot/nuget/update_checker.rb +116 -190
  93. metadata +20 -32
  94. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  95. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  96. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  97. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
  98. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  99. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  100. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -129
  101. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -171
  102. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  103. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -82
  104. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  105. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -68
  106. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  107. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -201
  108. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  109. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  110. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  111. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  112. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  113. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  114. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  115. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  116. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  117. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -136,7 +136,7 @@ public class PackageManager
136
136
  }
137
137
 
138
138
  // Method to get the dependencies of a package
139
- public async Task<List<PackageToUpdate>> GetDependenciesAsync(PackageToUpdate package, string targetFramework, string projectDirectory)
139
+ public async Task<List<PackageToUpdate>> GetDependenciesAsync(PackageToUpdate package, string targetFramework, string projectDirectory, ILogger logger)
140
140
  {
141
141
  if (!NuGetVersion.TryParse(package.NewVersion, out var otherVersion))
142
142
  {
@@ -235,24 +235,24 @@ public class PackageManager
235
235
  }
236
236
  else
237
237
  {
238
- Console.WriteLine("No compatible framework found.");
238
+ logger.Info("No compatible framework found.");
239
239
  }
240
240
  }
241
241
  catch (HttpRequestException ex)
242
242
  {
243
- Console.WriteLine($"HTTP error occurred: {ex.Message}");
243
+ logger.Error($"HTTP error occurred: {ex.Message}");
244
244
  }
245
245
  catch (ArgumentNullException ex)
246
246
  {
247
- Console.WriteLine($"Argument is null error: {ex.ParamName}, {ex.Message}");
247
+ logger.Error($"Argument is null error: {ex.ParamName}, {ex.Message}");
248
248
  }
249
249
  catch (InvalidOperationException ex)
250
250
  {
251
- Console.WriteLine($"Invalid operation exception: {ex.Message}");
251
+ logger.Error($"Invalid operation exception: {ex.Message}");
252
252
  }
253
253
  catch (Exception ex)
254
254
  {
255
- Console.WriteLine($"An error occurred: {ex.Message}");
255
+ logger.Error($"An error occurred: {ex.Message}");
256
256
  }
257
257
 
258
258
  return dependencyList;
@@ -287,12 +287,12 @@ public class PackageManager
287
287
  }
288
288
 
289
289
  // Method to get the dependencies of a package and add them as a dependency
290
- public async Task PopulatePackageDependenciesAsync(List<PackageToUpdate> packages, string targetFramework, string projectDirectory)
290
+ public async Task PopulatePackageDependenciesAsync(List<PackageToUpdate> packages, string targetFramework, string projectDirectory, ILogger logger)
291
291
  {
292
292
  // Loop through each package and get their dependencies
293
293
  foreach (PackageToUpdate package in packages)
294
294
  {
295
- List<PackageToUpdate> dependencies = await GetDependenciesAsync(package, targetFramework, projectDirectory);
295
+ List<PackageToUpdate> dependencies = await GetDependenciesAsync(package, targetFramework, projectDirectory, logger);
296
296
 
297
297
  if (dependencies == null)
298
298
  {
@@ -366,7 +366,7 @@ public class PackageManager
366
366
  package.CurrentVersion = package.NewVersion;
367
367
 
368
368
  // Check if the current package has dependencies
369
- List<PackageToUpdate> dependencyList = await GetDependenciesAsync(package, targetFramework, projectDirectory);
369
+ List<PackageToUpdate> dependencyList = await GetDependenciesAsync(package, targetFramework, projectDirectory, logger);
370
370
 
371
371
  // If there are dependencies
372
372
  if (dependencyList != null)
@@ -426,7 +426,7 @@ public class PackageManager
426
426
 
427
427
  foreach (PackageToUpdate parent in parentPackages)
428
428
  {
429
- bool isCompatible = await IsCompatibleAsync(parent, package, targetFramework, projectDirectory);
429
+ bool isCompatible = await IsCompatibleAsync(parent, package, targetFramework, projectDirectory, logger);
430
430
 
431
431
  // If the parent and package are not compatible
432
432
  if (!isCompatible)
@@ -446,7 +446,7 @@ public class PackageManager
446
446
  // If it's compatible and the package you updated wasn't in the existing package, check if the parent's dependencies version is the same as the current version
447
447
  else if (isCompatible == true && inExisting == false)
448
448
  {
449
- List<PackageToUpdate> dependencyListParent = await GetDependenciesAsync(parent, targetFramework, projectDirectory);
449
+ List<PackageToUpdate> dependencyListParent = await GetDependenciesAsync(parent, targetFramework, projectDirectory, logger);
450
450
 
451
451
  PackageToUpdate parentDependency = dependencyListParent.FirstOrDefault(p => string.Compare(p.PackageName, package.PackageName, StringComparison.OrdinalIgnoreCase) == 0);
452
452
 
@@ -478,7 +478,7 @@ public class PackageManager
478
478
  parent.NewVersion = parentVersion;
479
479
 
480
480
  // Check if the parent needs to be updated since the child isn't in the existing package list and the parent can update to a newer version to remove the dependency
481
- List<PackageToUpdate> dependencyListParentTemp = await GetDependenciesAsync(parent, targetFramework, projectDirectory);
481
+ List<PackageToUpdate> dependencyListParentTemp = await GetDependenciesAsync(parent, targetFramework, projectDirectory, logger);
482
482
  PackageToUpdate parentDependencyTemp = dependencyListParentTemp.FirstOrDefault(p => string.Compare(p.PackageName, package.PackageName, StringComparison.OrdinalIgnoreCase) == 0);
483
483
 
484
484
  // If the newer package version of the parent has the same version as the parent's previous dependency, update
@@ -499,7 +499,7 @@ public class PackageManager
499
499
 
500
500
  else
501
501
  {
502
- Console.WriteLine("Current version is >= latest version");
502
+ logger.Info("Current version is >= latest version");
503
503
  }
504
504
  }
505
505
  catch
@@ -511,10 +511,10 @@ public class PackageManager
511
511
  }
512
512
 
513
513
  // Method to determine if a parent and child are compatible with their versions
514
- public async Task<bool> IsCompatibleAsync(PackageToUpdate parent, PackageToUpdate child, string targetFramework, string projectDirectory)
514
+ public async Task<bool> IsCompatibleAsync(PackageToUpdate parent, PackageToUpdate child, string targetFramework, string projectDirectory, ILogger logger)
515
515
  {
516
516
  // Get the dependencies of the parent
517
- List<PackageToUpdate> dependencies = await GetDependenciesAsync(parent, targetFramework, projectDirectory);
517
+ List<PackageToUpdate> dependencies = await GetDependenciesAsync(parent, targetFramework, projectDirectory, logger);
518
518
 
519
519
  foreach (PackageToUpdate dependency in dependencies)
520
520
  {
@@ -613,7 +613,7 @@ public class PackageManager
613
613
  }
614
614
 
615
615
  // Check if there's compatibility with parent and dependency
616
- if (await IsCompatibleAsync(possibleParent, possibleDependency, targetFramework, nugetContext.CurrentDirectory))
616
+ if (await IsCompatibleAsync(possibleParent, possibleDependency, targetFramework, nugetContext.CurrentDirectory, logger))
617
617
  {
618
618
  // Check if parents are compatible, recursively
619
619
  if (await AreAllParentsCompatibleAsync(existingPackages, possibleParent, targetFramework, nugetContext.CurrentDirectory, logger))
@@ -641,7 +641,7 @@ public class PackageManager
641
641
  foreach (PackageToUpdate parent in parentPackages)
642
642
  {
643
643
  // Check compatibility between the possibleParent and current parent
644
- bool isCompatible = await IsCompatibleAsync(parent, possibleParent, targetFramework, projectDirectory);
644
+ bool isCompatible = await IsCompatibleAsync(parent, possibleParent, targetFramework, projectDirectory, logger);
645
645
 
646
646
  // If the possibleParent and parent are not compatible
647
647
  if (!isCompatible)
@@ -668,7 +668,7 @@ public class PackageManager
668
668
  }
669
669
 
670
670
  // Method to update the existing packages with new version of the desired packages to update
671
- public void UpdateExistingPackagesWithNewVersions(List<PackageToUpdate> existingPackages, List<PackageToUpdate> packagesToUpdate)
671
+ public void UpdateExistingPackagesWithNewVersions(List<PackageToUpdate> existingPackages, List<PackageToUpdate> packagesToUpdate, ILogger logger)
672
672
  {
673
673
  foreach (PackageToUpdate packageToUpdate in packagesToUpdate)
674
674
  {
@@ -680,7 +680,7 @@ public class PackageManager
680
680
  }
681
681
  else
682
682
  {
683
- Console.WriteLine($"Package {packageToUpdate.PackageName} not found in existing packages");
683
+ logger.Info($"Package {packageToUpdate.PackageName} not found in existing packages");
684
684
  }
685
685
  }
686
686
  }
@@ -2,5 +2,15 @@ namespace NuGetUpdater.Core;
2
2
 
3
3
  public interface ILogger
4
4
  {
5
- void Log(string message);
5
+ void LogRaw(string message);
6
+ }
7
+
8
+ public static class LoggerExtensions
9
+ {
10
+ public static void Info(this ILogger logger, string message) => logger.LogWithLevel("INFO", message);
11
+ public static void Warn(this ILogger logger, string message) => logger.LogWithLevel("WARN", message);
12
+ public static void Error(this ILogger logger, string message) => logger.LogWithLevel("ERROR", message);
13
+
14
+ private static void LogWithLevel(this ILogger logger, string level, string message) => logger.LogRaw($"{GetCurrentTimestamp()} {level} {message}");
15
+ private static string GetCurrentTimestamp() => DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss");
6
16
  }
@@ -11,6 +11,7 @@ namespace NuGetUpdater.Core.Utilities
11
11
  public static JsonDocumentOptions DocumentOptions { get; } = new JsonDocumentOptions
12
12
  {
13
13
  CommentHandling = JsonCommentHandling.Skip,
14
+ AllowTrailingCommas = true,
14
15
  };
15
16
 
16
17
  public static JsonNode? ParseNode(string content)
@@ -24,6 +25,7 @@ namespace NuGetUpdater.Core.Utilities
24
25
  var readerOptions = new JsonReaderOptions
25
26
  {
26
27
  CommentHandling = JsonCommentHandling.Allow,
28
+ AllowTrailingCommas = true,
27
29
  };
28
30
  var bytes = Encoding.UTF8.GetBytes(json);
29
31
  var reader = new Utf8JsonReader(bytes, readerOptions);
@@ -51,7 +51,7 @@ internal static partial class MSBuildHelper
51
51
  var globalJsonPaths = candidateDirectories.Select(d => Path.Combine(d, "global.json")).Where(File.Exists).Select(p => (p, p + Guid.NewGuid().ToString())).ToArray();
52
52
  foreach (var (globalJsonPath, tempGlobalJsonPath) in globalJsonPaths)
53
53
  {
54
- logger.Log($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}`{(retainMSBuildSdks ? " and retaining MSBuild SDK declarations" : string.Empty)}.");
54
+ logger.Info($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}`{(retainMSBuildSdks ? " and retaining MSBuild SDK declarations" : string.Empty)}.");
55
55
  File.Move(globalJsonPath, tempGlobalJsonPath);
56
56
  if (retainMSBuildSdks)
57
57
  {
@@ -80,7 +80,7 @@ internal static partial class MSBuildHelper
80
80
  {
81
81
  foreach (var (globalJsonpath, tempGlobalJsonPath) in globalJsonPaths)
82
82
  {
83
- logger.Log($"Restoring `global.json` to `{Path.GetDirectoryName(globalJsonpath)}`.");
83
+ logger.Info($"Restoring `global.json` to `{Path.GetDirectoryName(globalJsonpath)}`.");
84
84
  File.Move(tempGlobalJsonPath, globalJsonpath, overwrite: retainMSBuildSdks);
85
85
  }
86
86
  }
@@ -327,7 +327,7 @@ internal static partial class MSBuildHelper
327
327
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
328
328
  try
329
329
  {
330
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
330
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
331
331
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
332
332
 
333
333
  // NU1608: Detected package version outside of dependency constraint
@@ -347,7 +347,7 @@ internal static partial class MSBuildHelper
347
347
 
348
348
  try
349
349
  {
350
- string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
350
+ string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
351
351
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
352
352
 
353
353
  // Add Dependency[] packages to List<PackageToUpdate> existingPackages
@@ -398,10 +398,10 @@ internal static partial class MSBuildHelper
398
398
  if (added == true)
399
399
  {
400
400
  // Add existing versions to existing list
401
- packageManager.UpdateExistingPackagesWithNewVersions(existingDuplicate, packagesToUpdate);
401
+ packageManager.UpdateExistingPackagesWithNewVersions(existingDuplicate, packagesToUpdate, logger);
402
402
 
403
403
  // Make relationships
404
- await packageManager.PopulatePackageDependenciesAsync(existingDuplicate, targetFramework, Path.GetDirectoryName(projectPath));
404
+ await packageManager.PopulatePackageDependenciesAsync(existingDuplicate, targetFramework, Path.GetDirectoryName(projectPath), logger);
405
405
 
406
406
  // Update all to new versions
407
407
  foreach (var package in existingDuplicate)
@@ -414,10 +414,10 @@ internal static partial class MSBuildHelper
414
414
  else
415
415
  {
416
416
  // Add existing versions to existing list
417
- packageManager.UpdateExistingPackagesWithNewVersions(existingPackages, packagesToUpdate);
417
+ packageManager.UpdateExistingPackagesWithNewVersions(existingPackages, packagesToUpdate, logger);
418
418
 
419
419
  // Make relationships
420
- await packageManager.PopulatePackageDependenciesAsync(existingPackages, targetFramework, Path.GetDirectoryName(projectPath));
420
+ await packageManager.PopulatePackageDependenciesAsync(existingPackages, targetFramework, Path.GetDirectoryName(projectPath), logger);
421
421
 
422
422
  // Update all to new versions
423
423
  foreach (var package in existingPackages)
@@ -503,7 +503,7 @@ internal static partial class MSBuildHelper
503
503
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
504
504
  try
505
505
  {
506
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
506
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
507
507
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
508
508
  ThrowOnUnauthenticatedFeed(stdOut);
509
509
 
@@ -627,7 +627,7 @@ internal static partial class MSBuildHelper
627
627
  return projectRoot;
628
628
  }
629
629
 
630
- private static IEnumerable<PackageSource>? LoadPackageSources(string nugetConfigPath)
630
+ private static IEnumerable<PackageSource>? LoadPackageSources(string nugetConfigPath, ILogger logger)
631
631
  {
632
632
  try
633
633
  {
@@ -638,8 +638,8 @@ internal static partial class MSBuildHelper
638
638
  }
639
639
  catch (NuGetConfigurationException ex)
640
640
  {
641
- Console.WriteLine("Error while parsing NuGet.config");
642
- Console.WriteLine(ex.Message);
641
+ logger.Warn("Error while parsing NuGet.config");
642
+ logger.Warn(ex.Message);
643
643
 
644
644
  // Nuget.config is invalid. Won't be able to do anything with specific sources.
645
645
  return null;
@@ -652,6 +652,7 @@ internal static partial class MSBuildHelper
652
652
  string projectPath,
653
653
  string targetFramework,
654
654
  IReadOnlyCollection<Dependency> packages,
655
+ ILogger logger,
655
656
  bool usePackageDownload = false)
656
657
  {
657
658
  var projectDirectory = Path.GetDirectoryName(projectPath);
@@ -664,7 +665,7 @@ internal static partial class MSBuildHelper
664
665
  File.Copy(nugetConfigPath, Path.Combine(tempDir.FullName, "NuGet.Config"));
665
666
  var nugetConfigDir = Path.GetDirectoryName(nugetConfigPath);
666
667
 
667
- var packageSources = LoadPackageSources(nugetConfigPath);
668
+ var packageSources = LoadPackageSources(nugetConfigPath, logger);
668
669
  if (packageSources is not null)
669
670
  {
670
671
  // We need to copy local package sources from the NuGet.Config file to the temp directory
@@ -761,7 +762,7 @@ internal static partial class MSBuildHelper
761
762
  ThrowOnUnauthenticatedFeed(stdOut);
762
763
  if (exitCode != 0)
763
764
  {
764
- logger.Log($"Error determining target frameworks.\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
765
+ logger.Warn($"Error determining target frameworks.\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
765
766
  }
766
767
 
767
768
  // There are 3 return values, all uses slightly differently. Only one will be set, the others will be blank
@@ -805,13 +806,13 @@ internal static partial class MSBuildHelper
805
806
  string projectPath,
806
807
  string targetFramework,
807
808
  IReadOnlyCollection<Dependency> packages,
808
- ILogger? logger = null)
809
+ ILogger logger)
809
810
  {
810
811
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-resolution_");
811
812
  try
812
813
  {
813
814
  var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
814
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
815
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
815
816
 
816
817
  var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", ["build", tempProjectPath, "/t:_ReportDependencies"], workingDirectory: tempDirectory.FullName);
817
818
  ThrowOnUnauthenticatedFeed(stdout);
@@ -836,7 +837,7 @@ internal static partial class MSBuildHelper
836
837
  }
837
838
  else
838
839
  {
839
- logger?.Log($"dotnet build in {nameof(GetAllPackageDependenciesAsync)} failed. STDOUT: {stdout} STDERR: {stderr}");
840
+ logger?.Warn($"dotnet build in {nameof(GetAllPackageDependenciesAsync)} failed. STDOUT: {stdout} STDERR: {stderr}");
840
841
  return [];
841
842
  }
842
843
  }
@@ -4,28 +4,12 @@ namespace NuGetUpdater.Core;
4
4
 
5
5
  internal static class NuGetHelper
6
6
  {
7
- internal const string PackagesConfigFileName = "packages.config";
8
-
9
- public static bool TryGetPackagesConfigFile(string projectPath, [NotNullWhen(returnValue: true)] out string? packagesConfigPath)
10
- {
11
- var projectDirectory = Path.GetDirectoryName(projectPath);
12
-
13
- packagesConfigPath = PathHelper.JoinPath(projectDirectory, PackagesConfigFileName);
14
- if (File.Exists(packagesConfigPath))
15
- {
16
- return true;
17
- }
18
-
19
- packagesConfigPath = null;
20
- return false;
21
- }
22
-
23
7
  internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ILogger logger)
24
8
  {
25
9
  var tempDirectory = Directory.CreateTempSubdirectory("msbuild_sdk_restore_");
26
10
  try
27
11
  {
28
- var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, usePackageDownload: true);
12
+ var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, logger, usePackageDownload: true);
29
13
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath]);
30
14
 
31
15
  return exitCode == 0;
@@ -105,7 +105,7 @@ internal static class PathHelper
105
105
  /// </summary>
106
106
  /// <param name="filePath">The file path to resolve.</param>
107
107
  /// <param name="repoRootPath">The root path of the repository.</param>
108
- public static string? ResolveCaseInsensitivePathInsideRepoRoot(string filePath, string repoRootPath)
108
+ public static List<string>? ResolveCaseInsensitivePathsInsideRepoRoot(string filePath, string repoRootPath)
109
109
  {
110
110
  if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(repoRootPath))
111
111
  {
@@ -123,7 +123,7 @@ internal static class PathHelper
123
123
  }
124
124
 
125
125
  // Start resolving from the root path
126
- var currentPath = normalizedRepoRoot;
126
+ var currentPaths = new List<string> { normalizedRepoRoot };
127
127
  var relativePath = normalizedFilePath.Substring(normalizedRepoRoot.Length).TrimStart('/');
128
128
 
129
129
  foreach (var part in relativePath.Split('/'))
@@ -133,20 +133,28 @@ internal static class PathHelper
133
133
  continue;
134
134
  }
135
135
 
136
- // Enumerate the current directory to find a case-insensitive match
137
- var nextPath = Directory
138
- .EnumerateFileSystemEntries(currentPath)
139
- .FirstOrDefault(entry => string.Equals(Path.GetFileName(entry), part, StringComparison.OrdinalIgnoreCase));
136
+ var nextPaths = new List<string>();
140
137
 
141
- if (nextPath == null)
138
+ // Iterate through all current paths to find matches for the current part
139
+ foreach (var currentPath in currentPaths)
140
+ {
141
+ var matches = Directory
142
+ .EnumerateFileSystemEntries(currentPath)
143
+ .Where(entry => string.Equals(Path.GetFileName(entry), part, StringComparison.OrdinalIgnoreCase));
144
+
145
+ nextPaths.AddRange(matches);
146
+ }
147
+
148
+ if (!nextPaths.Any())
142
149
  {
143
150
  return null; // Part of the path does not exist
144
151
  }
145
152
 
146
- currentPath = nextPath;
153
+ currentPaths = nextPaths;
147
154
  }
148
155
 
149
- return currentPath.NormalizePathToUnix(); // Fully resolved path with correct casing
156
+ // Normalize all resulting paths to Unix format
157
+ return currentPaths.Select(path => path.NormalizePathToUnix()).ToList();
150
158
  }
151
159
 
152
160
  /// <summary>
@@ -0,0 +1,96 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using Microsoft.Build.Construction;
4
+
5
+ namespace NuGetUpdater.Core.Utilities;
6
+
7
+ internal static class ProjectHelper
8
+ {
9
+ public const string PackagesConfigFileName = "packages.config";
10
+ public const string AppConfigFileName = "app.config";
11
+ public const string WebConfigFileName = "web.config";
12
+ public const string PackagesLockJsonFileName = "packages.lock.json";
13
+
14
+ public enum PathFormat
15
+ {
16
+ Relative,
17
+ Full,
18
+ }
19
+
20
+ public static ImmutableArray<string> GetAllAdditionalFilesFromProject(string fullProjectPath, PathFormat pathFormat)
21
+ {
22
+ return GetAdditionalFilesFromProjectContent(fullProjectPath, pathFormat)
23
+ .AddRange(GetAdditionalFilesFromProjectLocation(fullProjectPath, pathFormat));
24
+ }
25
+
26
+ public static ImmutableArray<string> GetAdditionalFilesFromProjectContent(string fullProjectPath, PathFormat pathFormat)
27
+ {
28
+ var projectRootElement = ProjectRootElement.Open(fullProjectPath);
29
+ var additionalFilesWithFullPaths = new[]
30
+ {
31
+ projectRootElement.GetItemPathWithFileName(PackagesConfigFileName),
32
+ projectRootElement.GetItemPathWithFileName(AppConfigFileName),
33
+ projectRootElement.GetItemPathWithFileName(WebConfigFileName),
34
+ }.Where(p => p is not null).Cast<string>().ToImmutableArray();
35
+
36
+ var additionalFiles = additionalFilesWithFullPaths
37
+ .Select(p => MakePathAppropriateFormat(fullProjectPath, p, pathFormat))
38
+ .ToImmutableArray();
39
+ return additionalFiles;
40
+ }
41
+
42
+ public static ImmutableArray<string> GetAdditionalFilesFromProjectLocation(string fullProjectPath, PathFormat pathFormat)
43
+ {
44
+ var additionalFilesWithFullPaths = new[]
45
+ {
46
+ GetPathWithRegardsToProjectFile(fullProjectPath, PackagesLockJsonFileName),
47
+ }.Where(p => p is not null).Cast<string>().ToImmutableArray();
48
+
49
+ var additionalFiles = additionalFilesWithFullPaths
50
+ .Select(p => MakePathAppropriateFormat(fullProjectPath, p, pathFormat))
51
+ .ToImmutableArray();
52
+ return additionalFiles;
53
+ }
54
+
55
+ public static string? GetPackagesConfigPathFromProject(string fullProjectPath, PathFormat pathFormat)
56
+ {
57
+ var additionalFiles = GetAdditionalFilesFromProjectContent(fullProjectPath, pathFormat);
58
+ var packagesConfigFile = additionalFiles.FirstOrDefault(p => Path.GetFileName(p).Equals(PackagesConfigFileName, StringComparison.Ordinal));
59
+ return packagesConfigFile;
60
+ }
61
+
62
+ private static string MakePathAppropriateFormat(string fullProjectPath, string fullFilePath, PathFormat pathFormat)
63
+ {
64
+ var projectDirectory = Path.GetDirectoryName(fullProjectPath)!;
65
+ var updatedPath = pathFormat switch
66
+ {
67
+ PathFormat.Full => fullFilePath,
68
+ PathFormat.Relative => Path.GetRelativePath(projectDirectory, fullFilePath),
69
+ _ => throw new NotSupportedException(),
70
+ };
71
+ return updatedPath.NormalizePathToUnix();
72
+ }
73
+
74
+ private static string? GetItemPathWithFileName(this ProjectRootElement projectRootElement, string itemFileName)
75
+ {
76
+ var projectDirectory = Path.GetDirectoryName(projectRootElement.FullPath)!;
77
+ var itemPath = projectRootElement.Items
78
+ .Where(i => i.ElementName.Equals("None", StringComparison.OrdinalIgnoreCase) ||
79
+ i.ElementName.Equals("Content", StringComparison.OrdinalIgnoreCase))
80
+ .Where(i => Path.GetFileName(i.Include).Equals(itemFileName, StringComparison.OrdinalIgnoreCase))
81
+ .Select(i => Path.GetFullPath(Path.Combine(projectDirectory, i.Include)))
82
+ .Where(File.Exists)
83
+ .FirstOrDefault()
84
+ ?.NormalizePathToUnix();
85
+ return itemPath;
86
+ }
87
+
88
+ private static string? GetPathWithRegardsToProjectFile(string fullProjectPath, string fileName)
89
+ {
90
+ var projectDirectory = Path.GetDirectoryName(fullProjectPath)!;
91
+ var filePath = Directory.EnumerateFiles(projectDirectory)
92
+ .Where(p => Path.GetFileName(p).Equals(fileName, StringComparison.Ordinal))
93
+ .FirstOrDefault();
94
+ return filePath;
95
+ }
96
+ }
@@ -19,7 +19,9 @@ public class AnalyzeWorkerTestBase
19
19
  DependencyInfo dependencyInfo,
20
20
  ExpectedAnalysisResult expectedResult,
21
21
  MockNuGetPackage[]? packages = null,
22
- TestFile[]? extraFiles = null)
22
+ TestFile[]? extraFiles = null,
23
+ ExperimentsManager? experimentsManager = null
24
+ )
23
25
  {
24
26
  var relativeDependencyPath = $"./dependabot/dependency/{dependencyInfo.Name}.json";
25
27
 
@@ -28,6 +30,7 @@ public class AnalyzeWorkerTestBase
28
30
  (relativeDependencyPath, JsonSerializer.Serialize(dependencyInfo, AnalyzeWorker.SerializerOptions)),
29
31
  ];
30
32
 
33
+ experimentsManager ??= new ExperimentsManager();
31
34
  var allFiles = files.Concat(extraFiles ?? []).ToArray();
32
35
  var actualResult = await RunAnalyzerAsync(dependencyInfo.Name, allFiles, async directoryPath =>
33
36
  {
@@ -36,7 +39,7 @@ public class AnalyzeWorkerTestBase
36
39
  var discoveryPath = Path.GetFullPath(DiscoveryWorker.DiscoveryResultFileName, directoryPath);
37
40
  var dependencyPath = Path.GetFullPath(relativeDependencyPath, directoryPath);
38
41
 
39
- var worker = new AnalyzeWorker(new TestLogger());
42
+ var worker = new AnalyzeWorker(experimentsManager, new TestLogger());
40
43
  var result = await worker.RunWithErrorHandlingAsync(directoryPath, discoveryPath, dependencyPath);
41
44
  return result;
42
45
  });