dependabot-nuget 0.289.0 → 0.291.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +26 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +2 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +1 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +6 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -9
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +2 -0
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +17 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +44 -5
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +19 -11
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +1 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +24 -4
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +2 -1
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -2
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +43 -18
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +13 -12
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +40 -14
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +2 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +45 -7
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +2 -2
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +0 -4
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +41 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -0
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -1
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +2 -1
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +7 -31
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +340 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +0 -12
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +55 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -6
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +785 -755
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +2 -2
  61. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +1 -1
  62. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  63. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  64. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  65. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  66. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  67. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  68. data/lib/dependabot/nuget/file_fetcher.rb +3 -3
  69. data/lib/dependabot/nuget/file_parser.rb +92 -3
  70. data/lib/dependabot/nuget/file_updater.rb +13 -13
  71. data/lib/dependabot/nuget/language.rb +82 -0
  72. data/lib/dependabot/nuget/native_helpers.rb +37 -5
  73. data/lib/dependabot/nuget/package_manager.rb +51 -0
  74. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  75. data/lib/dependabot/nuget/update_checker.rb +116 -190
  76. metadata +20 -29
  77. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  78. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  79. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  80. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -122
  81. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -277
  82. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  83. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -104
  84. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  85. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -61
  86. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  87. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -214
  88. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  89. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  90. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  91. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  92. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  93. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  94. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  95. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  96. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  97. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -4,13 +4,13 @@ namespace NuGetUpdater.Core;
4
4
 
5
5
  internal static class NuGetHelper
6
6
  {
7
- internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ILogger logger)
7
+ internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ExperimentsManager experimentsManager, ILogger logger)
8
8
  {
9
9
  var tempDirectory = Directory.CreateTempSubdirectory("msbuild_sdk_restore_");
10
10
  try
11
11
  {
12
12
  var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, logger, usePackageDownload: true);
13
- var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath]);
13
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName, experimentsManager);
14
14
 
15
15
  return exitCode == 0;
16
16
  }
@@ -5,19 +5,57 @@ namespace NuGetUpdater.Core;
5
5
 
6
6
  public static class ProcessEx
7
7
  {
8
- public static Task<(int ExitCode, string Output, string Error)> RunAsync(string fileName, IEnumerable<string>? arguments = null, string? workingDirectory = null)
8
+ /// <summary>
9
+ /// Run the `dotnet` command with the given values. This will exclude all `MSBuild*` environment variables from the execution.
10
+ /// </summary>
11
+ public static Task<(int ExitCode, string Output, string Error)> RunDotnetWithoutMSBuildEnvironmentVariablesAsync(IEnumerable<string> arguments, string workingDirectory, ExperimentsManager experimentsManager)
12
+ {
13
+ var environmentVariablesToUnset = new List<string>();
14
+ if (experimentsManager.InstallDotnetSdks)
15
+ {
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
+ }
26
+
27
+ var environmentVariableOverrides = environmentVariablesToUnset.Select(name => (name, (string?)null));
28
+ return RunAsync("dotnet",
29
+ arguments,
30
+ workingDirectory,
31
+ environmentVariableOverrides
32
+ );
33
+ }
34
+
35
+ public static Task<(int ExitCode, string Output, string Error)> RunAsync(
36
+ string fileName,
37
+ IEnumerable<string>? arguments = null,
38
+ string? workingDirectory = null,
39
+ IEnumerable<(string Name, string? Value)>? environmentVariableOverrides = null
40
+ )
9
41
  {
10
42
  var tcs = new TaskCompletionSource<(int, string, string)>();
11
43
 
12
44
  var redirectInitiated = new ManualResetEventSlim();
45
+ var psi = new ProcessStartInfo(fileName, arguments ?? [])
46
+ {
47
+ UseShellExecute = false, // required to redirect output and set environment variables
48
+ RedirectStandardOutput = true,
49
+ RedirectStandardError = true,
50
+ };
51
+ foreach (var (name, value) in environmentVariableOverrides ?? [])
52
+ {
53
+ psi.EnvironmentVariables[name] = value;
54
+ }
55
+
13
56
  var process = new Process
14
57
  {
15
- StartInfo = new ProcessStartInfo(fileName, arguments ?? [])
16
- {
17
- UseShellExecute = false, // required to redirect output
18
- RedirectStandardOutput = true,
19
- RedirectStandardError = true,
20
- },
58
+ StartInfo = psi,
21
59
  EnableRaisingEvents = true
22
60
  };
23
61
 
@@ -74,7 +74,7 @@ internal static class ProjectHelper
74
74
  private static string? GetItemPathWithFileName(this ProjectRootElement projectRootElement, string itemFileName)
75
75
  {
76
76
  var projectDirectory = Path.GetDirectoryName(projectRootElement.FullPath)!;
77
- var packagesConfigPath = projectRootElement.Items
77
+ var itemPath = projectRootElement.Items
78
78
  .Where(i => i.ElementName.Equals("None", StringComparison.OrdinalIgnoreCase) ||
79
79
  i.ElementName.Equals("Content", StringComparison.OrdinalIgnoreCase))
80
80
  .Where(i => Path.GetFileName(i.Include).Equals(itemFileName, StringComparison.OrdinalIgnoreCase))
@@ -82,7 +82,7 @@ internal static class ProjectHelper
82
82
  .Where(File.Exists)
83
83
  .FirstOrDefault()
84
84
  ?.NormalizePathToUnix();
85
- return packagesConfigPath;
85
+ return itemPath;
86
86
  }
87
87
 
88
88
  private static string? GetPathWithRegardsToProjectFile(string fullProjectPath, string fileName)
@@ -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
  });
@@ -50,6 +50,50 @@ public partial class DiscoveryWorkerTests
50
50
  );
51
51
  }
52
52
 
53
+ [Fact]
54
+ public async Task DiscoversDependenciesTrailingComma()
55
+ {
56
+ await TestDiscoveryAsync(
57
+ packages: [],
58
+ workspacePath: "",
59
+ files: [
60
+ (".config/dotnet-tools.json", """
61
+ {
62
+ "version": 1,
63
+ "isRoot": true,
64
+ "tools": {
65
+ "botsay": {
66
+ "version": "1.0.0",
67
+ "commands": [
68
+ "botsay"
69
+ ],
70
+ },
71
+ "dotnetsay": {
72
+ "version": "1.0.0",
73
+ "commands": [
74
+ "dotnetsay"
75
+ ],
76
+ }
77
+ }
78
+ }
79
+ """),
80
+ ],
81
+ expectedResult: new()
82
+ {
83
+ Path = "",
84
+ DotNetToolsJson = new()
85
+ {
86
+ FilePath = ".config/dotnet-tools.json",
87
+ Dependencies = [
88
+ new("botsay", "1.0.0", DependencyType.DotNetTool),
89
+ new("dotnetsay", "1.0.0", DependencyType.DotNetTool),
90
+ ]
91
+ },
92
+ ExpectedProjectCount = 0,
93
+ }
94
+ );
95
+ }
96
+
53
97
  [Fact]
54
98
  public async Task ReportsFailure()
55
99
  {
@@ -74,7 +118,7 @@ public partial class DiscoveryWorkerTests
74
118
  "dotnetsay"
75
119
  ]
76
120
  }
77
- }
121
+ } INVALID JSON
78
122
  }
79
123
  """),
80
124
  ],
@@ -40,6 +40,40 @@ public partial class DiscoveryWorkerTests
40
40
  );
41
41
  }
42
42
 
43
+ [Fact]
44
+ public async Task DiscoversDependencies_HandlesTrailingComma()
45
+ {
46
+ await TestDiscoveryAsync(
47
+ packages: [],
48
+ workspacePath: "",
49
+ files: [
50
+ ("global.json", """
51
+ {
52
+ "sdk": {
53
+ "version": "2.2.104"
54
+ },
55
+ "msbuild-sdks": {
56
+ "Microsoft.Build.Traversal": "1.0.45"
57
+ },
58
+ }
59
+ """),
60
+ ],
61
+ expectedResult: new()
62
+ {
63
+ Path = "",
64
+ GlobalJson = new()
65
+ {
66
+ FilePath = "global.json",
67
+ Dependencies = [
68
+ new("Microsoft.NET.Sdk", "2.2.104", DependencyType.MSBuildSdk),
69
+ new("Microsoft.Build.Traversal", "1.0.45", DependencyType.MSBuildSdk),
70
+ ]
71
+ },
72
+ ExpectedProjectCount = 0,
73
+ }
74
+ );
75
+ }
76
+
43
77
  [Fact]
44
78
  public async Task ReportsFailure()
45
79
  {
@@ -50,7 +84,7 @@ public partial class DiscoveryWorkerTests
50
84
  ("global.json", """
51
85
  {
52
86
  "sdk": {
53
- "version": "2.2.104",
87
+ "version": "2.2.104", INVALID JSON
54
88
  },
55
89
  "msbuild-sdks": {
56
90
  "Microsoft.Build.Traversal": "1.0.45"
@@ -441,8 +441,6 @@ public partial class DiscoveryWorkerTests
441
441
  ReferencedProjectPaths = [],
442
442
  ImportedFiles = [
443
443
  "Directory.Build.targets",
444
- "NUGET_PACKAGES/microsoft.build.centralpackageversions/2.1.3/Sdk/Sdk.props", // this is an artifact of the package cache existing next to the csproj
445
- "NUGET_PACKAGES/microsoft.build.centralpackageversions/2.1.3/Sdk/Sdk.targets", // this is an artifact of the package cache existing next to the csproj
446
444
  "Packages.props",
447
445
  ],
448
446
  AdditionalFiles = [],
@@ -513,8 +511,6 @@ public partial class DiscoveryWorkerTests
513
511
  ReferencedProjectPaths = [],
514
512
  ImportedFiles = [
515
513
  "Directory.Build.targets",
516
- "NUGET_PACKAGES/microsoft.build.centralpackageversions/2.1.3/Sdk/Sdk.props", // this is an artifact of the package cache existing next to the csproj
517
- "NUGET_PACKAGES/microsoft.build.centralpackageversions/2.1.3/Sdk/Sdk.targets", // this is an artifact of the package cache existing next to the csproj
518
514
  "Packages.props",
519
515
  ],
520
516
  AdditionalFiles = [],
@@ -1094,6 +1094,47 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
1094
1094
  );
1095
1095
  }
1096
1096
 
1097
+ [Theory]
1098
+ [InlineData(true)]
1099
+ [InlineData(false)]
1100
+ public async Task DiscoveryReportsDependencyFileNotParseable(bool useDirectDiscovery)
1101
+ {
1102
+ var experimentsManager = new ExperimentsManager() { UseDirectDiscovery = useDirectDiscovery };
1103
+ await TestDiscoveryAsync(
1104
+ experimentsManager: experimentsManager,
1105
+ workspacePath: "",
1106
+ files:
1107
+ [
1108
+ ("project.csproj", """
1109
+ <Project Sdk="Microsoft.NET.Sdk">
1110
+ <PropertyGroup>
1111
+ <TargetFramework>net8.0</TargetFramework>
1112
+ </PropertyGroup>
1113
+ <ItemGroup>
1114
+ <PackageReference Include="Some.Package" Version="1.2.3" />
1115
+ </ItemGroup>
1116
+ </Project>
1117
+ """),
1118
+ ("project2.csproj", """
1119
+ <Project Sdk="Microsoft.NET.Sdk">
1120
+ <PropertyGroup>
1121
+ <TargetFramework>net8.0</TargetFramework>
1122
+ </PropertyGroup>
1123
+ <ItemGroup>
1124
+ <PackageReference: Include="Some.Package2" Version="1.2.3" />
1125
+ </ItemGroup>
1126
+ </Project>
1127
+ """),
1128
+ ],
1129
+ expectedResult: new()
1130
+ {
1131
+ Path = "",
1132
+ Projects = [],
1133
+ ErrorType = ErrorType.DependencyFileNotParseable,
1134
+ ErrorDetails = "project2.csproj",
1135
+ });
1136
+ }
1137
+
1097
1138
  [Fact]
1098
1139
  public async Task ResultFileHasCorrectShapeForAuthenticationFailure()
1099
1140
  {
@@ -21,6 +21,7 @@ public record ExpectedSdkProjectDiscoveryResult : ExpectedDependencyDiscoveryRes
21
21
  public required ImmutableArray<string> ReferencedProjectPaths { get; init; }
22
22
  public required ImmutableArray<string> ImportedFiles { get; init; }
23
23
  public required ImmutableArray<string> AdditionalFiles { get; init; }
24
+ public string? ErrorDetails { get; init; }
24
25
  }
25
26
 
26
27
  public record ExpectedDependencyDiscoveryResult : IDiscoveryResultWithDependencies
@@ -488,7 +488,7 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
488
488
  var logger = new TestLogger();
489
489
  var fullProjectPath = Path.Combine(testDirectory.DirectoryPath, projectPath);
490
490
  var experimentsManager = new ExperimentsManager() { UseDirectDiscovery = true }; // the following method is direct discovery; this just makes the call to Validate... happy
491
- var projectDiscovery = await SdkProjectDiscovery.DiscoverWithBinLogAsync(testDirectory.DirectoryPath, Path.GetDirectoryName(fullProjectPath)!, fullProjectPath, logger);
491
+ var projectDiscovery = await SdkProjectDiscovery.DiscoverWithBinLogAsync(testDirectory.DirectoryPath, Path.GetDirectoryName(fullProjectPath)!, fullProjectPath, experimentsManager, logger);
492
492
  ValidateProjectResults(expectedProjects, projectDiscovery, experimentsManager);
493
493
  }
494
494
  }
@@ -318,7 +318,8 @@ namespace NuGetUpdater.Core.Test
318
318
  </Project>
319
319
  """
320
320
  );
321
- var (exitCode, stdout, stderr) = ProcessEx.RunAsync("dotnet", ["msbuild", projectPath, "/t:_ReportCurrentSdkVersion"]).Result;
321
+ var experimentsManager = new ExperimentsManager();
322
+ var (exitCode, stdout, stderr) = ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["msbuild", projectPath, "/t:_ReportCurrentSdkVersion"], projectDir.FullName, experimentsManager).Result;
322
323
  if (exitCode != 0)
323
324
  {
324
325
  throw new Exception($"Failed to report the current SDK version:\n{stdout}\n{stderr}");
@@ -0,0 +1,85 @@
1
+ using NuGet.Versioning;
2
+
3
+ using NuGetUpdater.Core.Analyze;
4
+ using NuGetUpdater.Core.Run;
5
+ using NuGetUpdater.Core.Run.ApiModel;
6
+
7
+ using Xunit;
8
+
9
+ namespace NuGetUpdater.Core.Test.Run;
10
+
11
+ public class MiscellaneousTests
12
+ {
13
+ [Theory]
14
+ [MemberData(nameof(RequirementsFromIgnoredVersionsData))]
15
+ public void RequirementsFromIgnoredVersions(string dependencyName, Condition[] ignoreConditions, Requirement[] expectedRequirements)
16
+ {
17
+ var job = new Job()
18
+ {
19
+ Source = new()
20
+ {
21
+ Provider = "github",
22
+ Repo = "some/repo"
23
+ },
24
+ IgnoreConditions = ignoreConditions
25
+ };
26
+ var actualRequirements = RunWorker.GetIgnoredRequirementsForDependency(job, dependencyName);
27
+ var actualRequirementsStrings = string.Join("|", actualRequirements.Select(r => r.ToString()));
28
+ var expectedRequirementsStrings = string.Join("|", expectedRequirements.Select(r => r.ToString()));
29
+ Assert.Equal(expectedRequirementsStrings, actualRequirementsStrings);
30
+ }
31
+
32
+ public static IEnumerable<object?[]> RequirementsFromIgnoredVersionsData()
33
+ {
34
+ yield return
35
+ [
36
+ // dependencyName
37
+ "Some.Package",
38
+ // ignoredConditions
39
+ new Condition[]
40
+ {
41
+ new()
42
+ {
43
+ DependencyName = "SOME.PACKAGE",
44
+ VersionRequirement = Requirement.Parse("> 1.2.3")
45
+ },
46
+ new()
47
+ {
48
+ DependencyName = "some.package",
49
+ VersionRequirement = Requirement.Parse("<= 2.0.0")
50
+ },
51
+ new()
52
+ {
53
+ DependencyName = "Unrelated.Package",
54
+ VersionRequirement = Requirement.Parse("= 3.4.5")
55
+ }
56
+ },
57
+ // expectedRequirements
58
+ new Requirement[]
59
+ {
60
+ new IndividualRequirement(">", NuGetVersion.Parse("1.2.3")),
61
+ new IndividualRequirement("<=", NuGetVersion.Parse("2.0.0")),
62
+ }
63
+ ];
64
+
65
+ // version requirement is null => ignore all
66
+ yield return
67
+ [
68
+ // dependencyName
69
+ "Some.Package",
70
+ // ignoredConditions
71
+ new Condition[]
72
+ {
73
+ new()
74
+ {
75
+ DependencyName = "Some.Package"
76
+ }
77
+ },
78
+ // expectedRequirements
79
+ new Requirement[]
80
+ {
81
+ new IndividualRequirement(">", NuGetVersion.Parse("0.0.0"))
82
+ }
83
+ ];
84
+ }
85
+ }
@@ -30,11 +30,7 @@ public class RunWorkerTests
30
30
  Provider = "github",
31
31
  Repo = "test/repo",
32
32
  Directory = "some-dir",
33
- },
34
- AllowedUpdates =
35
- [
36
- new() { UpdateType = "all" }
37
- ]
33
+ }
38
34
  },
39
35
  files:
40
36
  [
@@ -237,11 +233,7 @@ public class RunWorkerTests
237
233
  Provider = "github",
238
234
  Repo = "test/repo",
239
235
  Directory = "some-dir",
240
- },
241
- AllowedUpdates =
242
- [
243
- new() { UpdateType = "all" }
244
- ]
236
+ }
245
237
  },
246
238
  files:
247
239
  [
@@ -483,11 +475,7 @@ public class RunWorkerTests
483
475
  Provider = "github",
484
476
  Repo = "test/repo",
485
477
  Directory = "/",
486
- },
487
- AllowedUpdates =
488
- [
489
- new() { UpdateType = "all" }
490
- ]
478
+ }
491
479
  },
492
480
  files:
493
481
  [
@@ -550,11 +538,7 @@ public class RunWorkerTests
550
538
  Provider = "github",
551
539
  Repo = "test/repo",
552
540
  Directory = "some-dir",
553
- },
554
- AllowedUpdates =
555
- [
556
- new() { UpdateType = "all" }
557
- ]
541
+ }
558
542
  },
559
543
  files:
560
544
  [
@@ -886,11 +870,7 @@ public class RunWorkerTests
886
870
  Provider = "github",
887
871
  Repo = "test/repo",
888
872
  Directory = "some-dir/ProjectA",
889
- },
890
- AllowedUpdates =
891
- [
892
- new() { UpdateType = "all" }
893
- ]
873
+ }
894
874
  },
895
875
  files:
896
876
  [
@@ -1438,11 +1418,7 @@ public class RunWorkerTests
1438
1418
  Provider = "github",
1439
1419
  Repo = "test/repo",
1440
1420
  Directory = "/",
1441
- },
1442
- AllowedUpdates =
1443
- [
1444
- new() { UpdateType = "all" }
1445
- ]
1421
+ }
1446
1422
  },
1447
1423
  packages:
1448
1424
  [
@@ -1754,7 +1730,7 @@ public class RunWorkerTests
1754
1730
  var testApiHandler = new TestApiHandler();
1755
1731
  var logger = new TestLogger();
1756
1732
  discoveryWorker ??= new DiscoveryWorker(experimentsManager, logger);
1757
- analyzeWorker ??= new AnalyzeWorker(logger);
1733
+ analyzeWorker ??= new AnalyzeWorker(experimentsManager, logger);
1758
1734
  updaterWorker ??= new UpdaterWorker(experimentsManager, logger);
1759
1735
 
1760
1736
  var worker = new RunWorker(testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);