dependabot-nuget 0.322.2 → 0.325.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +0 -4
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +1 -31
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +0 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyInfo.cs +1 -0
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +64 -10
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/MSBuildDependencySolver.cs +10 -4
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +4 -4
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +31 -41
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -6
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Cooldown.cs +83 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +2 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +9 -1
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGenerator.cs +6 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +8 -1
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +79 -67
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +1 -1
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +1 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +1 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +10 -7
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +245 -125
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +4 -11
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +4 -5
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +2 -2
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +14 -31
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +3 -5
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +12 -13
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/XmlExtensions.cs +3 -3
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +78 -2
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +126 -3
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +14 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +1 -2
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -2
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +1 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -6
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +2 -3
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +1 -2
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/CooldownTests.cs +99 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +168 -4
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGeneratorTests.cs +71 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +71 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +70 -39
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +43 -30
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +76 -3
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +0 -2
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +11 -27
  51. data/lib/dependabot/nuget.rb +3 -11
  52. metadata +8 -54
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +0 -49
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +0 -60
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +0 -35
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +0 -58
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +0 -380
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +0 -557
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.FrameworkCheck.cs +0 -37
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +0 -226
  61. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +0 -65
  62. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +0 -66
  63. data/lib/dependabot/nuget/cache_manager.rb +0 -29
  64. data/lib/dependabot/nuget/discovery/dependency_details.rb +0 -102
  65. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +0 -122
  66. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +0 -266
  67. data/lib/dependabot/nuget/discovery/evaluation_details.rb +0 -63
  68. data/lib/dependabot/nuget/discovery/project_discovery.rb +0 -104
  69. data/lib/dependabot/nuget/discovery/property_details.rb +0 -43
  70. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +0 -61
  71. data/lib/dependabot/nuget/file_fetcher.rb +0 -46
  72. data/lib/dependabot/nuget/file_parser.rb +0 -153
  73. data/lib/dependabot/nuget/file_updater.rb +0 -256
  74. data/lib/dependabot/nuget/language.rb +0 -98
  75. data/lib/dependabot/nuget/metadata_finder.rb +0 -197
  76. data/lib/dependabot/nuget/native_helpers.rb +0 -364
  77. data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +0 -88
  78. data/lib/dependabot/nuget/package_manager.rb +0 -51
  79. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +0 -105
  80. data/lib/dependabot/nuget/update_checker.rb +0 -210
@@ -30,8 +30,7 @@ internal static partial class MSBuildHelper
30
30
  // Ensure MSBuild types are registered before calling a method that loads the types
31
31
  if (!IsMSBuildRegistered)
32
32
  {
33
- var experimentsManager = new ExperimentsManager() { InstallDotnetSdks = false }; // `global.json` definitely needs to be moved for this operation
34
- HandleGlobalJsonAsync(currentDirectory, rootDirectory, experimentsManager, () =>
33
+ HandleGlobalJsonAsync(currentDirectory, rootDirectory, () =>
35
34
  {
36
35
  var defaultInstance = MSBuildLocator.QueryVisualStudioInstances().First();
37
36
  MSBuildPath = defaultInstance.MSBuildPath;
@@ -44,19 +43,11 @@ internal static partial class MSBuildHelper
44
43
  public static async Task<T> HandleGlobalJsonAsync<T>(
45
44
  string currentDirectory,
46
45
  string rootDirectory,
47
- ExperimentsManager experimentsManager,
48
46
  Func<Task<T>> action,
49
47
  ILogger logger,
50
48
  bool retainMSBuildSdks = false
51
49
  )
52
50
  {
53
- if (experimentsManager.InstallDotnetSdks)
54
- {
55
- logger.Info($"{nameof(ExperimentsManager.InstallDotnetSdks)} == true; retaining `global.json` contents.");
56
- var result = await action();
57
- return result;
58
- }
59
-
60
51
  var candidateDirectories = PathHelper.GetAllDirectoriesToRoot(currentDirectory, rootDirectory);
61
52
  var globalJsonPaths = candidateDirectories.Select(d => Path.Combine(d, "global.json")).Where(File.Exists).Select(p => (p, p + Guid.NewGuid().ToString())).ToArray();
62
53
  foreach (var (globalJsonPath, tempGlobalJsonPath) in globalJsonPaths)
@@ -96,15 +87,15 @@ internal static partial class MSBuildHelper
96
87
  }
97
88
  }
98
89
 
99
- internal static async Task<ImmutableArray<Dependency>?> ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> packages, ImmutableArray<Dependency> update, ExperimentsManager experimentsManager, ILogger logger)
90
+ internal static async Task<ImmutableArray<Dependency>?> ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> packages, ImmutableArray<Dependency> update, ILogger logger)
100
91
  {
101
92
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
102
93
  PackageManager packageManager = new PackageManager(repoRoot, projectPath);
103
94
 
104
95
  try
105
96
  {
106
- string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger);
107
- var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName, experimentsManager);
97
+ string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
98
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName);
108
99
 
109
100
  // Add Dependency[] packages to List<PackageToUpdate> existingPackages
110
101
  List<PackageToUpdate> existingPackages = packages
@@ -287,11 +278,10 @@ internal static partial class MSBuildHelper
287
278
  string projectPath,
288
279
  string targetFramework,
289
280
  IReadOnlyCollection<Dependency> packages,
290
- ExperimentsManager experimentsManager,
291
281
  ILogger logger,
292
282
  bool usePackageDownload = false,
293
283
  bool importDependencyTargets = true
294
- ) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFramework", targetFramework), packages, experimentsManager, logger, usePackageDownload, importDependencyTargets);
284
+ ) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFramework", targetFramework), packages, logger, usePackageDownload, importDependencyTargets);
295
285
 
296
286
  internal static Task<string> CreateTempProjectAsync(
297
287
  DirectoryInfo tempDir,
@@ -299,11 +289,10 @@ internal static partial class MSBuildHelper
299
289
  string projectPath,
300
290
  ImmutableArray<string> targetFrameworks,
301
291
  IReadOnlyCollection<Dependency> packages,
302
- ExperimentsManager experimentsManager,
303
292
  ILogger logger,
304
293
  bool usePackageDownload = false,
305
294
  bool importDependencyTargets = true
306
- ) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFrameworks", string.Join(";", targetFrameworks)), packages, experimentsManager, logger, usePackageDownload, importDependencyTargets);
295
+ ) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFrameworks", string.Join(";", targetFrameworks)), packages, logger, usePackageDownload, importDependencyTargets);
307
296
 
308
297
  private static async Task<string> CreateTempProjectAsync(
309
298
  DirectoryInfo tempDir,
@@ -311,7 +300,6 @@ internal static partial class MSBuildHelper
311
300
  string projectPath,
312
301
  XElement targetFrameworkElement,
313
302
  IReadOnlyCollection<Dependency> packages,
314
- ExperimentsManager experimentsManager,
315
303
  ILogger logger,
316
304
  bool usePackageDownload,
317
305
  bool importDependencyTargets)
@@ -319,13 +307,10 @@ internal static partial class MSBuildHelper
319
307
  var projectDirectory = Path.GetDirectoryName(projectPath);
320
308
  projectDirectory ??= repoRoot;
321
309
 
322
- if (experimentsManager.InstallDotnetSdks)
310
+ var globalJsonPath = PathHelper.GetFileInDirectoryOrParent(projectPath, repoRoot, "global.json", caseSensitive: true);
311
+ if (globalJsonPath is not null)
323
312
  {
324
- var globalJsonPath = PathHelper.GetFileInDirectoryOrParent(projectPath, repoRoot, "global.json", caseSensitive: true);
325
- if (globalJsonPath is not null)
326
- {
327
- File.Copy(globalJsonPath, Path.Combine(tempDir.FullName, "global.json"));
328
- }
313
+ File.Copy(globalJsonPath, Path.Combine(tempDir.FullName, "global.json"));
329
314
  }
330
315
 
331
316
  var nugetConfigPath = PathHelper.GetFileInDirectoryOrParent(projectPath, repoRoot, "NuGet.Config", caseSensitive: false);
@@ -417,10 +402,10 @@ internal static partial class MSBuildHelper
417
402
  return tempProjectPath;
418
403
  }
419
404
 
420
- internal static async Task<ImmutableArray<string>> GetTargetFrameworkValuesFromProject(string repoRoot, string projectPath, ExperimentsManager experimentsManager, ILogger logger)
405
+ internal static async Task<ImmutableArray<string>> GetTargetFrameworkValuesFromProject(string repoRoot, string projectPath, ILogger logger)
421
406
  {
422
407
  var projectDirectory = Path.GetDirectoryName(projectPath)!;
423
- var (exitCode, stdOut, stdErr) = await HandleGlobalJsonAsync(projectDirectory, repoRoot, experimentsManager, async () =>
408
+ var (exitCode, stdOut, stdErr) = await HandleGlobalJsonAsync(projectDirectory, repoRoot, async () =>
424
409
  {
425
410
  var targetsHelperPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "TargetFrameworkReporter.targets");
426
411
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(
@@ -431,8 +416,7 @@ internal static partial class MSBuildHelper
431
416
  $"/p:CustomAfterMicrosoftCommonCrossTargetingTargets={targetsHelperPath}",
432
417
  $"/p:CustomAfterMicrosoftCommonTargets={targetsHelperPath}",
433
418
  ],
434
- projectDirectory,
435
- experimentsManager
419
+ projectDirectory
436
420
  );
437
421
  return (exitCode, stdOut, stdErr);
438
422
  }, logger);
@@ -500,7 +484,6 @@ internal static partial class MSBuildHelper
500
484
  string projectPath,
501
485
  string targetFramework,
502
486
  IReadOnlyCollection<Dependency> packages,
503
- ExperimentsManager experimentsManager,
504
487
  ILogger logger
505
488
  )
506
489
  {
@@ -508,9 +491,9 @@ internal static partial class MSBuildHelper
508
491
  try
509
492
  {
510
493
  var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
511
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger, importDependencyTargets: false);
494
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger, importDependencyTargets: false);
512
495
 
513
- var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(repoRoot, tempDirectory.FullName, tempProjectPath, experimentsManager, logger);
496
+ var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(repoRoot, tempDirectory.FullName, tempProjectPath, logger);
514
497
  var allDependencies = projectDiscovery
515
498
  .Where(p => p.FilePath == Path.GetFileName(tempProjectPath))
516
499
  .FirstOrDefault()
@@ -1,16 +1,14 @@
1
- using System.Diagnostics.CodeAnalysis;
2
-
3
1
  namespace NuGetUpdater.Core;
4
2
 
5
3
  internal static class NuGetHelper
6
4
  {
7
- internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ExperimentsManager experimentsManager, ILogger logger)
5
+ internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ILogger logger)
8
6
  {
9
7
  var tempDirectory = Directory.CreateTempSubdirectory("msbuild_sdk_restore_");
10
8
  try
11
9
  {
12
- var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, experimentsManager, logger, usePackageDownload: true);
13
- var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName, experimentsManager);
10
+ var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, logger, usePackageDownload: true);
11
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName);
14
12
 
15
13
  return exitCode == 0;
16
14
  }
@@ -8,21 +8,20 @@ public static class ProcessEx
8
8
  /// <summary>
9
9
  /// Run the `dotnet` command with the given values. This will exclude all `MSBuild*` environment variables from the execution.
10
10
  /// </summary>
11
- public static Task<(int ExitCode, string Output, string Error)> RunDotnetWithoutMSBuildEnvironmentVariablesAsync(IEnumerable<string> arguments, string workingDirectory, ExperimentsManager experimentsManager)
11
+ public static Task<(int ExitCode, string Output, string Error)> RunDotnetWithoutMSBuildEnvironmentVariablesAsync(IEnumerable<string> arguments, string workingDirectory)
12
12
  {
13
- var environmentVariablesToUnset = new List<string>();
14
- if (experimentsManager.InstallDotnetSdks)
13
+ // When using the SDK specified by a `global.json` file, these environment variables need to be unset to
14
+ // allow the new process to discover the correct MSBuild binaries to load, and not load the ones that
15
+ // this process is using.
16
+ var environmentVariablesToUnset = new List<string>
15
17
  {
16
- // If using the SDK specified by a `global.json` file, these environment variables need to be unset to
17
- // allow the new process to discover the correct MSBuild binaries to load, and not load the ones that
18
- // this process is using.
19
- environmentVariablesToUnset.Add("MSBuildExtensionsPath");
20
- environmentVariablesToUnset.Add("MSBuildLoadMicrosoftTargetsReadOnly");
21
- environmentVariablesToUnset.Add("MSBUILDLOGIMPORTS");
22
- environmentVariablesToUnset.Add("MSBuildSDKsPath");
23
- environmentVariablesToUnset.Add("MSBUILDTARGETOUTPUTLOGGING");
24
- environmentVariablesToUnset.Add("MSBUILD_EXE_PATH");
25
- }
18
+ "MSBuildExtensionsPath",
19
+ "MSBuildLoadMicrosoftTargetsReadOnly",
20
+ "MSBUILDLOGIMPORTS",
21
+ "MSBuildSDKsPath",
22
+ "MSBUILDTARGETOUTPUTLOGGING",
23
+ "MSBUILD_EXE_PATH"
24
+ };
26
25
 
27
26
  var environmentVariableOverrides = environmentVariablesToUnset.Select(name => (name, (string?)null));
28
27
  return RunAsync("dotnet",
@@ -83,16 +83,16 @@ public static class XmlExtensions
83
83
  return CreateOpenCloseXmlElementSyntax(name, new SyntaxList<SyntaxNode>(leadingTrivia));
84
84
  }
85
85
 
86
- public static XmlElementSyntax CreateOpenCloseXmlElementSyntax(string name, SyntaxList<SyntaxNode> leadingTrivia)
86
+ public static XmlElementSyntax CreateOpenCloseXmlElementSyntax(string name, SyntaxList<SyntaxNode> leadingTrivia, bool insertIntermediateNewline = true)
87
87
  {
88
- var newlineTrivia = SyntaxFactory.WhitespaceTrivia(Environment.NewLine);
88
+ var newlineTrivia = SyntaxFactory.EndOfLineTrivia(Environment.NewLine);
89
89
 
90
90
  return SyntaxFactory.XmlElement(
91
91
  SyntaxFactory.XmlElementStartTag(
92
92
  SyntaxFactory.Punctuation(SyntaxKind.LessThanToken, "<", leadingTrivia, default),
93
93
  SyntaxFactory.XmlName(null, SyntaxFactory.XmlNameToken(name, null, null)),
94
94
  new SyntaxList<XmlAttributeSyntax>(),
95
- SyntaxFactory.Punctuation(SyntaxKind.GreaterThanToken, ">", null, newlineTrivia)),
95
+ SyntaxFactory.Punctuation(SyntaxKind.GreaterThanToken, ">", null, insertIntermediateNewline ? newlineTrivia : null)),
96
96
  new SyntaxList<SyntaxNode>(),
97
97
  SyntaxFactory.XmlElementEndTag(
98
98
  SyntaxFactory.Punctuation(SyntaxKind.LessThanSlashToken, "</", leadingTrivia, default),
@@ -546,6 +546,8 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
546
546
  _ => (404, Encoding.UTF8.GetBytes("{}")), // nothing else is found
547
547
  };
548
548
  }
549
+ var aspNetCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.AspNetCore.App", "net8.0");
550
+ var netCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.NETCore.App", "net8.0");
549
551
  var desktopAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net8.0");
550
552
  (int, byte[]) TestHttpHandler2(string uriString)
551
553
  {
@@ -610,6 +612,46 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
610
612
  return (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0").GetZipStream().ReadAllBytes());
611
613
  case "/api/v2/package/Some.Package/1.2.3":
612
614
  return (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.3", "net8.0").GetZipStream().ReadAllBytes());
615
+ case "/api/v2/FindPackagesById()?id='Microsoft.AspNetCore.App.Ref'&semVerLevel=2.0.0":
616
+ return (200, Encoding.UTF8.GetBytes($"""
617
+ <feed xml:base="{baseUrl}/api/v2" xmlns="http://www.w3.org/2005/Atom"
618
+ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
619
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
620
+ xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
621
+ <m:count>1</m:count>
622
+ <id>http://schemas.datacontract.org/2004/07/</id>
623
+ <title />
624
+ <updated>{DateTime.UtcNow:O}</updated>
625
+ <link rel="self" href="{baseUrl}/api/v2/Packages" />
626
+ <entry>
627
+ <id>{baseUrl}/api/v2/Packages(Id='Microsoft.AspNetCore.App.Ref',Version='{aspNetCoreAppRefPackage.Version}')</id>
628
+ <content type="application/zip" src="{baseUrl}/api/v2/package/Microsoft.AspNetCore.App.Ref/{aspNetCoreAppRefPackage.Version}" />
629
+ <m:properties>
630
+ <d:Version>{aspNetCoreAppRefPackage.Version}</d:Version>
631
+ </m:properties>
632
+ </entry>
633
+ </feed>
634
+ """));
635
+ case "/api/v2/FindPackagesById()?id='Microsoft.NETCore.App.Ref'&semVerLevel=2.0.0":
636
+ return (200, Encoding.UTF8.GetBytes($"""
637
+ <feed xml:base="{baseUrl}/api/v2" xmlns="http://www.w3.org/2005/Atom"
638
+ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
639
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
640
+ xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
641
+ <m:count>1</m:count>
642
+ <id>http://schemas.datacontract.org/2004/07/</id>
643
+ <title />
644
+ <updated>{DateTime.UtcNow:O}</updated>
645
+ <link rel="self" href="{baseUrl}/api/v2/Packages" />
646
+ <entry>
647
+ <id>{baseUrl}/api/v2/Packages(Id='Microsoft.NETCore.App.Ref',Version='{netCoreAppRefPackage.Version}')</id>
648
+ <content type="application/zip" src="{baseUrl}/api/v2/package/Microsoft.NETCore.App.Ref/{netCoreAppRefPackage.Version}" />
649
+ <m:properties>
650
+ <d:Version>{netCoreAppRefPackage.Version}</d:Version>
651
+ </m:properties>
652
+ </entry>
653
+ </feed>
654
+ """));
613
655
  case "/api/v2/FindPackagesById()?id='Microsoft.WindowsDesktop.App.Ref'&semVerLevel=2.0.0":
614
656
  return (200, Encoding.UTF8.GetBytes($"""
615
657
  <feed xml:base="{baseUrl}/api/v2" xmlns="http://www.w3.org/2005/Atom"
@@ -631,7 +673,15 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
631
673
  </feed>
632
674
  """));
633
675
  default:
634
- if (uri.PathAndQuery == $"/api/v2/package/Microsoft.WindowsDesktop.App.Ref/{desktopAppRefPackage.Version}")
676
+ if (uri.PathAndQuery == $"/api/v2/package/Microsoft.AspNetCore.App.Ref/{aspNetCoreAppRefPackage.Version}")
677
+ {
678
+ return (200, aspNetCoreAppRefPackage.GetZipStream().ReadAllBytes());
679
+ }
680
+ else if (uri.PathAndQuery == $"/api/v2/package/Microsoft.NETCore.App.Ref/{netCoreAppRefPackage.Version}")
681
+ {
682
+ return (200, netCoreAppRefPackage.GetZipStream().ReadAllBytes());
683
+ }
684
+ else if (uri.PathAndQuery == $"/api/v2/package/Microsoft.WindowsDesktop.App.Ref/{desktopAppRefPackage.Version}")
635
685
  {
636
686
  return (200, desktopAppRefPackage.GetZipStream().ReadAllBytes());
637
687
  }
@@ -727,6 +777,8 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
727
777
  _ => (404, Encoding.UTF8.GetBytes("{}")), // nothing else is found
728
778
  };
729
779
  }
780
+ var aspNetCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.AspNetCore.App", "net8.0");
781
+ var netCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.NETCore.App", "net8.0");
730
782
  var desktopAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net8.0");
731
783
  (int, byte[]) TestHttpHandler2(string uriString)
732
784
  {
@@ -790,6 +842,22 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
790
842
  ]
791
843
  }
792
844
  """));
845
+ case "/download/microsoft.aspnetcore.app.ref/index.json":
846
+ return (200, Encoding.UTF8.GetBytes($$"""
847
+ {
848
+ "versions": [
849
+ "{{aspNetCoreAppRefPackage.Version}}"
850
+ ]
851
+ }
852
+ """));
853
+ case "/download/microsoft.netcore.app.ref/index.json":
854
+ return (200, Encoding.UTF8.GetBytes($$"""
855
+ {
856
+ "versions": [
857
+ "{{netCoreAppRefPackage.Version}}"
858
+ ]
859
+ }
860
+ """));
793
861
  case "/download/microsoft.windowsdesktop.app.ref/index.json":
794
862
  return (200, Encoding.UTF8.GetBytes($$"""
795
863
  {
@@ -803,7 +871,15 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
803
871
  case "/download/some.package/1.2.3/some.package.1.2.3.nupkg":
804
872
  return (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.3", "net8.0").GetZipStream().ReadAllBytes());
805
873
  default:
806
- if (uri.PathAndQuery == $"/download/microsoft.windowsdesktop.app.ref/{desktopAppRefPackage.Version}/microsoft.windowsdesktop.app.ref.{desktopAppRefPackage.Version}.nupkg")
874
+ if (uri.PathAndQuery == $"/download/microsoft.aspnetcore.app.ref/{aspNetCoreAppRefPackage.Version}/microsoft.aspnetcore.app.ref.{aspNetCoreAppRefPackage.Version}.nupkg")
875
+ {
876
+ return (200, aspNetCoreAppRefPackage.GetZipStream().ReadAllBytes());
877
+ }
878
+ else if (uri.PathAndQuery == $"/download/microsoft.netcore.app.ref/{netCoreAppRefPackage.Version}/microsoft.netcore.app.ref.{netCoreAppRefPackage.Version}.nupkg")
879
+ {
880
+ return (200, netCoreAppRefPackage.GetZipStream().ReadAllBytes());
881
+ }
882
+ else if (uri.PathAndQuery == $"/download/microsoft.windowsdesktop.app.ref/{desktopAppRefPackage.Version}/microsoft.windowsdesktop.app.ref.{desktopAppRefPackage.Version}.nupkg")
807
883
  {
808
884
  return (200, desktopAppRefPackage.GetZipStream().ReadAllBytes());
809
885
  }
@@ -1,6 +1,8 @@
1
1
  using System.Collections.Immutable;
2
+ using System.Text;
2
3
  using System.Text.Json;
3
4
 
5
+ using NuGet;
4
6
  using NuGet.Frameworks;
5
7
  using NuGet.Versioning;
6
8
 
@@ -218,7 +220,7 @@ public class VersionFinderTests : TestBase
218
220
  var currentVersion = NuGetVersion.Parse("1.0.0");
219
221
  var logger = new TestLogger();
220
222
  var nugetContext = new NuGetContext(tempDir.DirectoryPath);
221
- var versionResult = await VersionFinder.GetVersionsAsync(projectTfms, packageId, currentVersion, nugetContext, logger, CancellationToken.None);
223
+ var versionResult = await VersionFinder.GetVersionsByNameAsync(projectTfms, packageId, currentVersion, nugetContext, logger, CancellationToken.None);
222
224
  var versions = versionResult.GetVersions();
223
225
 
224
226
  // assert
@@ -286,7 +288,7 @@ public class VersionFinderTests : TestBase
286
288
  var nugetContext = new NuGetContext(tempDir.DirectoryPath);
287
289
  var exception = await Assert.ThrowsAsync<BadResponseException>(async () =>
288
290
  {
289
- await VersionFinder.GetVersionsAsync([tfm], dependencyInfo, nugetContext, logger, CancellationToken.None);
291
+ await VersionFinder.GetVersionsAsync([tfm], dependencyInfo, DateTimeOffset.UtcNow, nugetContext, logger, CancellationToken.None);
290
292
  });
291
293
  var error = JobErrorBase.ErrorFromException(exception, "TEST-JOB-ID", tempDir.DirectoryPath);
292
294
 
@@ -328,11 +330,132 @@ public class VersionFinderTests : TestBase
328
330
  var nugetContext = new NuGetContext(tempDir.DirectoryPath);
329
331
 
330
332
  // act
331
- var versionResult = await VersionFinder.GetVersionsAsync([tfm], dependencyInfo, nugetContext, logger, CancellationToken.None);
333
+ var versionResult = await VersionFinder.GetVersionsAsync([tfm], dependencyInfo, DateTimeOffset.UtcNow, nugetContext, logger, CancellationToken.None);
332
334
  var versions = versionResult.GetVersions();
333
335
 
334
336
  // assert
335
337
  var actualVersions = versions.Select(v => v.ToString()).OrderBy(v => v).ToArray();
336
338
  AssertEx.Equal(expectedVersions, actualVersions);
337
339
  }
340
+
341
+ [Fact]
342
+ public async Task CooldownValuesAreHonored()
343
+ {
344
+ // updating from version 1.0.0 only to 1.2.0 because the cooldown settings prohibit major updates
345
+
346
+ // arrange
347
+ var tfm = "net8.0";
348
+ var packageVersionsAndDates = new[]
349
+ {
350
+ // major = month, minor = day, patch = hour
351
+ ("1.1.0", "\"2025-01-01T00:00:00.00+00:00\""),
352
+ ("1.1.1", "\"2025-01-01T01:00:00.00+00:00\""),
353
+ ("1.2.0", "\"2025-01-02T00:00:00.00+00:00\""),
354
+ ("1.3.0", "null"),
355
+ ("2.1.0", "\"2025-02-01T00:00:00.00+00:00\""),
356
+ };
357
+ var cooldown = new Cooldown()
358
+ {
359
+ DefaultDays = 1,
360
+ SemVerMajorDays = 10,
361
+ SemVerMinorDays = 1,
362
+ SemVerPatchDays = 1,
363
+ Include = ["Some.Package"],
364
+ };
365
+ // can only update a major version if 10 days have passed since the publish date, but it's currently only 7 days after the publish date
366
+ var currentTime = DateTimeOffset.Parse(packageVersionsAndDates.Last().Item2.Trim('"')).AddDays(7);
367
+ using var http = TestHttpServer.CreateTestServer(url =>
368
+ {
369
+ var uri = new Uri(url, UriKind.Absolute);
370
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
371
+ return uri.PathAndQuery switch
372
+ {
373
+ "/index.json" => (200, Encoding.UTF8.GetBytes($$"""
374
+ {
375
+ "version": "3.0.0",
376
+ "resources": [
377
+ {
378
+ "@id": "{{baseUrl}}/base",
379
+ "@type": "PackageBaseAddress/3.0.0"
380
+ },
381
+ {
382
+ "@id": "{{baseUrl}}/query",
383
+ "@type": "SearchQueryService"
384
+ },
385
+ {
386
+ "@id": "{{baseUrl}}/registrations",
387
+ "@type": "RegistrationsBaseUrl/3.6.0"
388
+ }
389
+ ]
390
+ }
391
+ """)),
392
+ "/base/some.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
393
+ {
394
+ "versions": [{{string.Join(", ", packageVersionsAndDates.Select(d => $"\"{d.Item1}\""))}}]
395
+ }
396
+ """)),
397
+ "/base/some.package/1.1.0/some.package.1.1.0.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", tfm).GetZipStream().ReadAllBytes()),
398
+ "/base/some.package/1.1.1/some.package.1.1.1.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.1", tfm).GetZipStream().ReadAllBytes()),
399
+ "/base/some.package/1.2.0/some.package.1.2.0.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.0", tfm).GetZipStream().ReadAllBytes()),
400
+ "/base/some.package/1.3.0/some.package.1.3.0.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.3.0", tfm).GetZipStream().ReadAllBytes()),
401
+ "/base/some.package/2.1.0/some.package.2.1.0.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "2.1.0", tfm).GetZipStream().ReadAllBytes()),
402
+ "/registrations/some.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
403
+ {
404
+ "count": 1,
405
+ "items": [
406
+ {
407
+ "count": {{packageVersionsAndDates.Length}},
408
+ "lower": "{{packageVersionsAndDates.First().Item1}}",
409
+ "upper": "{{packageVersionsAndDates.Last().Item1}}",
410
+ "items": [
411
+ {{string.Join(", ", packageVersionsAndDates.Select(d => $$"""
412
+ {
413
+ "catalogEntry": {
414
+ "id": "Some.Package",
415
+ "version": "{{d.Item1}}",
416
+ "published": {{d.Item2}}
417
+ }
418
+ }
419
+ """))}}
420
+ ]
421
+ }
422
+ ]
423
+ }
424
+ """)),
425
+ _ => (404, Encoding.UTF8.GetBytes("{}"))
426
+ };
427
+ });
428
+ var feedUrl = $"{http.BaseUrl.TrimEnd('/')}/index.json";
429
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
430
+ ("NuGet.Config", $"""
431
+ <configuration>
432
+ <packageSources>
433
+ <clear />
434
+ <add key="private_feed" value="{feedUrl}" allowInsecureConnections="true" />
435
+ </packageSources>
436
+ </configuration>
437
+ """)
438
+ );
439
+
440
+ // act
441
+ var currentVersion = NuGetVersion.Parse("1.0.0");
442
+ var dependencyInfo = new DependencyInfo()
443
+ {
444
+ Name = "Some.Package",
445
+ Version = currentVersion.ToString(),
446
+ IsVulnerable = false,
447
+ Cooldown = cooldown,
448
+ };
449
+ var logger = new TestLogger();
450
+ var nugetContext = new NuGetContext(tempDir.DirectoryPath);
451
+ var versionResult = await VersionFinder.GetVersionsAsync([NuGetFramework.Parse(tfm)], dependencyInfo, currentVersion, currentTime, nugetContext, logger, CancellationToken.None);
452
+ var versions = versionResult.GetVersions();
453
+
454
+ // assert
455
+ // including 1.3.0 because the publish date was null
456
+ // not including 2.1.0 because the major update isn't allowed yet
457
+ var expected = new[] { "1.1.0", "1.1.1", "1.2.0", "1.3.0" };
458
+ var actual = versions.Select(v => v.ToString()).ToArray();
459
+ AssertEx.Equal(expected, actual);
460
+ }
338
461
  }
@@ -50,6 +50,20 @@ public class CloneWorkerTests
50
50
  );
51
51
  }
52
52
 
53
+ [Fact]
54
+ public void GheOnPremCloneCommandsAreGenerated()
55
+ {
56
+ TestCommands(
57
+ provider: "github",
58
+ hostname: "ghe-onprem-url.example.com",
59
+ repoMoniker: "OwnerName/RepoName",
60
+ expectedCommands:
61
+ [
62
+ (["clone", "--no-tags", "--depth", "1", "--recurse-submodules", "--shallow-submodules", "https://ghe-onprem-url.example.com/OwnerName/RepoName", TestRepoPath], null)
63
+ ]
64
+ );
65
+ }
66
+
53
67
  [Fact]
54
68
  public void CloneCommandsAreGeneratedWhenBranchIsSpecified()
55
69
  {
@@ -614,9 +614,8 @@ public class MSBuildDependencySolverTests : TestBase
614
614
  await Update.UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDir.DirectoryPath);
615
615
  var repoContentsPath = new DirectoryInfo(tempDir.DirectoryPath);
616
616
  var projectPath = new FileInfo(Path.Combine(repoContentsPath.FullName, projectName));
617
- var experimentsManager = new ExperimentsManager();
618
617
  var logger = new TestLogger();
619
- var msbuildDepSolver = new MSBuildDependencySolver(repoContentsPath, projectPath, experimentsManager, logger);
618
+ var msbuildDepSolver = new MSBuildDependencySolver(repoContentsPath, projectPath, logger);
620
619
 
621
620
  // act
622
621
  var resolvedDependencies = await msbuildDepSolver.SolveAsync(
@@ -41,7 +41,7 @@ public class DiscoveryWorkerTestBase : TestBase
41
41
  Assert.Equal(expectedResult.Path.NormalizePathToUnix(), actualResult.Path.NormalizePathToUnix());
42
42
  ValidateResultWithDependencies(expectedResult.GlobalJson, actualResult.GlobalJson);
43
43
  ValidateResultWithDependencies(expectedResult.DotNetToolsJson, actualResult.DotNetToolsJson);
44
- ValidateProjectResults(expectedResult.Projects, actualResult.Projects, experimentsManager);
44
+ ValidateProjectResults(expectedResult.Projects, actualResult.Projects);
45
45
  Assert.Equal(expectedResult.ExpectedProjectCount ?? expectedResult.Projects.Length, actualResult.Projects.Length);
46
46
  ValidateDiscoveryOperationResult(expectedResult, actualResult);
47
47
 
@@ -81,7 +81,7 @@ public class DiscoveryWorkerTestBase : TestBase
81
81
  }
82
82
  }
83
83
 
84
- internal static void ValidateProjectResults(ImmutableArray<ExpectedSdkProjectDiscoveryResult> expectedProjects, ImmutableArray<ProjectDiscoveryResult> actualProjects, ExperimentsManager experimentsManager)
84
+ internal static void ValidateProjectResults(ImmutableArray<ExpectedSdkProjectDiscoveryResult> expectedProjects, ImmutableArray<ProjectDiscoveryResult> actualProjects)
85
85
  {
86
86
  if (expectedProjects.IsDefaultOrEmpty)
87
87
  {
@@ -55,7 +55,7 @@ public partial class DiscoveryWorkerTests
55
55
  Properties = [
56
56
  new("TargetFrameworks", "net7.0;net8.0", "myproj.csproj"),
57
57
  ],
58
- TargetFrameworks = ["net7.0"], // net8.0 has no packages and is not reported
58
+ TargetFrameworks = ["net7.0", "net8.0"],
59
59
  ReferencedProjectPaths = [],
60
60
  ImportedFiles = [
61
61
  "Directory.Build.props",
@@ -786,7 +786,6 @@ public partial class DiscoveryWorkerTests
786
786
  // `@(References)` item group in the `_HandlePackageFileConflicts` target. Since we don't want to involve
787
787
  // the real SDK, we fake some required targets.
788
788
  await TestDiscoveryAsync(
789
- experimentsManager: new ExperimentsManager() { InstallDotnetSdks = true },
790
789
  packages: [],
791
790
  workspacePath: "",
792
791
  files:
@@ -548,10 +548,6 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
548
548
  """),
549
549
  ("global.json", """
550
550
  {
551
- "sdk": {
552
- "version": "6.0.405",
553
- "rollForward": "latestPatch"
554
- },
555
551
  "msbuild-sdks": {
556
552
  "My.Custom.Sdk": "5.0.0",
557
553
  "My.Other.Sdk": "1.0.0-beta"
@@ -1216,7 +1212,6 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
1216
1212
  // this test mimics a package feed that doesn't have the common Microsoft.Windows.App.Ref package; common in Azure DevOps
1217
1213
  // Windows machines always have the package, so this test only makes sense on Linux
1218
1214
  await TestDiscoveryAsync(
1219
- experimentsManager: new ExperimentsManager() { InstallDotnetSdks = true },
1220
1215
  includeCommonPackages: false,
1221
1216
  packages: [
1222
1217
  MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.3", "net8.0"),
@@ -1321,7 +1316,6 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
1321
1316
  {
1322
1317
  await TestDiscoveryAsync(
1323
1318
  packages: [],
1324
- experimentsManager: new ExperimentsManager() { InstallDotnetSdks = true },
1325
1319
  workspacePath: "",
1326
1320
  files: [
1327
1321
  ("project.csproj", """
@@ -637,8 +637,7 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
637
637
 
638
638
  var logger = new TestLogger();
639
639
  var fullProjectPath = Path.Combine(testDirectory.DirectoryPath, projectPath);
640
- var experimentsManager = new ExperimentsManager();
641
- var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(testDirectory.DirectoryPath, Path.GetDirectoryName(fullProjectPath)!, fullProjectPath, experimentsManager, logger);
642
- ValidateProjectResults(expectedProjects, projectDiscovery, experimentsManager);
640
+ var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(testDirectory.DirectoryPath, Path.GetDirectoryName(fullProjectPath)!, fullProjectPath, logger);
641
+ ValidateProjectResults(expectedProjects, projectDiscovery);
643
642
  }
644
643
  }
@@ -318,8 +318,7 @@ namespace NuGetUpdater.Core.Test
318
318
  </Project>
319
319
  """
320
320
  );
321
- var experimentsManager = new ExperimentsManager();
322
- var (exitCode, stdout, stderr) = ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["msbuild", projectPath, "/t:_ReportCurrentSdkVersion"], projectDir.FullName, experimentsManager).Result;
321
+ var (exitCode, stdout, stderr) = ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["msbuild", projectPath, "/t:_ReportCurrentSdkVersion"], projectDir.FullName).Result;
323
322
  if (exitCode != 0)
324
323
  {
325
324
  throw new Exception($"Failed to report the current SDK version:\n{stdout}\n{stderr}");