dependabot-nuget 0.288.0 → 0.290.0

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