dependabot-nuget 0.321.2 → 0.322.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +22 -22
  3. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageMapper.cs +9 -0
  4. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +21 -7
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +19 -11
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +19 -9
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +21 -14
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +8 -5
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +29 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +20 -19
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +2 -1
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscoveryTargetingPacks.props +2 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/IDependencySolver.cs +8 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/MSBuildDependencySolver.cs +32 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +1 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +10 -1
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +6 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +5 -13
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/PrivateSourceTimedOutException.cs +12 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceTimedOut.cs +10 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +1 -1
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +1 -1
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +1 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +1 -1
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +6 -3
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +376 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/IFileWriter.cs +14 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +477 -0
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +9 -5
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +18 -7
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +26 -1
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +15 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +633 -0
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +0 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -2
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +49 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +0 -1
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +484 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +21 -22
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +1 -1
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +8 -0
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/DotNetToolsJsonUpdaterTests.cs +181 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterTestsBase.cs +61 -0
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +917 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests_MiscellaneousTests.cs +154 -0
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/TestFileWriterReturnsConstantResult.cs +20 -0
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +1620 -0
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests_CreateUpdatedVersionRangeTests.cs +25 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/GlobalJsonUpdaterTests.cs +139 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +1961 -1
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateOperationResultTests.cs +116 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +16 -1043
  60. data/helpers/lib/NuGetUpdater/global.json +1 -1
  61. metadata +21 -10
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +0 -375
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +0 -296
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.LockFile.cs +0 -251
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +0 -201
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +0 -3821
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -2706
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3f4db8a08db9553a5639509f415ea04832273007e65bded633cee126cd0b5a4
4
- data.tar.gz: be1476e3b56bfa67e803fb9d70eb4ec82113af256995d0e44d7fd5dd0335331b
3
+ metadata.gz: 3960b8e460b0caef38e1a302c8245e51708c19e3070be3dcd6de9ac708174c48
4
+ data.tar.gz: 9de84a12311aa75b8f838e1413052d4c37a06e74887c3e9d16d050e7e463f096
5
5
  SHA512:
6
- metadata.gz: f60d45606facd245fd353b29ffda952034469a15b32975fd1cb840903fd1a2c638806823ad6e9fafa3a11a27f0f12629e31e8a4452d6df2a558a4851378e73e2
7
- data.tar.gz: 5233059c5c248a2f54b39ca1f8819f96ddc7b4d81701135a98403f7965000aeffbd8407680d582bf7449bb543df38568f21cb45d1a895f2d220177cdea1b5b0b
6
+ metadata.gz: 390a5e049399bf2d135915b3aa37c9c3977139193f3a46c41b09ea20568a7b417a96235fd32751f9d0b14efa8ad56c54187a0096d760676a728d8c61166225a3
7
+ data.tar.gz: bc2cabf452264a3df4f02e8531bfc8905c379072982f8ff31048d1fb3dbb4ededd221112eb3914bc0a6b56e87c0eff739ef5cebad1d12e7564264714463f94ec
@@ -3,42 +3,42 @@
3
3
  <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4
4
  </PropertyGroup>
5
5
  <PropertyGroup>
6
- <MSBuildPackageVersion>17.12.6</MSBuildPackageVersion>
6
+ <MSBuildPackageVersion>17.14.8</MSBuildPackageVersion>
7
7
  </PropertyGroup>
8
8
  <ItemGroup>
9
- <PackageVersion Include="DiffPlex" Version="1.7.2" />
9
+ <PackageVersion Include="DiffPlex" Version="1.8.0" />
10
10
  <PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.93" />
11
- <PackageVersion Include="Microsoft.Build.Locator" Version="1.7.8" />
11
+ <PackageVersion Include="Microsoft.Build.Locator" Version="1.9.1" />
12
12
  <PackageVersion Include="Microsoft.Build" Version="$(MSBuildPackageVersion)" />
13
13
  <PackageVersion Include="Microsoft.Build.Framework" Version="$(MSBuildPackageVersion)" />
14
14
  <PackageVersion Include="Microsoft.Build.Tasks.Core" Version="$(MSBuildPackageVersion)" />
15
15
  <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MSBuildPackageVersion)" />
16
- <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
16
+ <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
17
17
  <PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
18
- <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="9.0.0" />
19
- <PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="9.0.3" />
20
- <PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.3" />
21
- <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
22
- <PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.12.2149" />
18
+ <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="9.0.7" />
19
+ <PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="9.0.7" />
20
+ <PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.7" />
21
+ <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
22
+ <PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.14.2075" />
23
23
  <PackageVersion Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.52" />
24
- <PackageVersion Include="Microsoft.Web.Xdt" Version="3.1.0" />
25
- <PackageVersion Include="MSBuild.StructuredLogger" Version="2.2.386" />
24
+ <PackageVersion Include="Microsoft.Web.Xdt" Version="3.2.0" />
25
+ <PackageVersion Include="MSBuild.StructuredLogger" Version="2.3.17" />
26
26
  <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
27
27
  <PackageVersion Include="NuGet.Core" Version="2.14.0" Aliases="CoreV2" />
28
- <PackageVersion Include="OpenTelemetry" Version="1.11.2" />
29
- <PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.11.2" />
30
- <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.2" />
28
+ <PackageVersion Include="OpenTelemetry" Version="1.12.0" />
29
+ <PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.12.0" />
30
+ <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
31
31
  <PackageVersion Include="Semver" Version="3.0.0" />
32
- <PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
33
- <PackageVersion Include="System.ComponentModel.Composition" Version="9.0.3" />
32
+ <PackageVersion Include="System.CommandLine" Version="2.0.0-beta6.25358.103" />
33
+ <PackageVersion Include="System.ComponentModel.Composition" Version="9.0.7" />
34
34
  <PackageVersion Include="System.Net.Http" Version="4.3.4" />
35
35
  <PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
36
- <PackageVersion Include="System.Security.Cryptography.Pkcs" Version="9.0.0" />
37
- <PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.0" />
38
- <PackageVersion Include="System.Text.Json" Version="9.0.3" />
36
+ <PackageVersion Include="System.Security.Cryptography.Pkcs" Version="9.0.7" />
37
+ <PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.7" />
38
+ <PackageVersion Include="System.Text.Json" Version="9.0.7" />
39
39
  <PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
40
- <PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.3" />
41
- <PackageVersion Include="xunit.v3" Version="2.0.1" />
42
- <PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
40
+ <PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.7" />
41
+ <PackageVersion Include="xunit.v3" Version="3.0.0" />
42
+ <PackageVersion Include="xunit.runner.visualstudio" Version="3.1.2" />
43
43
  </ItemGroup>
44
44
  </Project>
@@ -46,6 +46,15 @@ public class PackageMapper
46
46
  return null;
47
47
  }
48
48
 
49
+ public bool IsSdkReplacementPackage(string packageName)
50
+ {
51
+ var isSdkReplacementPackage = RuntimePackages.Runtimes.Any(r =>
52
+ {
53
+ return r.Value.Packages.Any(p => packageName.Equals(p.Key, StringComparison.Ordinal));
54
+ });
55
+ return isSdkReplacementPackage;
56
+ }
57
+
49
58
  private SemVersion? GetRuntimeVersionFromPackage(string packageName, SemVersion packageVersion)
50
59
  {
51
60
  // TODO: linear search is slow
@@ -9,24 +9,38 @@ public class Program
9
9
  {
10
10
  public static async Task<int> Main(string[] args)
11
11
  {
12
- var coreLocationOption = new Option<DirectoryInfo>("--core-location", "The location of the .NET Core source code.") { IsRequired = true };
13
- var outputOption = new Option<FileInfo>("--output", "The location to write the result.") { IsRequired = true };
12
+ var coreLocationOption = new Option<DirectoryInfo>("--core-location")
13
+ {
14
+ Description = "The location of the .NET Core source code.",
15
+ Required = true
16
+ };
17
+ var outputOption = new Option<FileInfo>("--output")
18
+ {
19
+ Description = "The location to write the result.",
20
+ Required = true
21
+ };
14
22
  var command = new Command("build")
15
23
  {
16
24
  coreLocationOption,
17
25
  outputOption,
18
26
  };
19
27
  command.TreatUnmatchedTokensAsErrors = true;
20
- command.SetHandler(async (coreLocationDirectory, output) =>
28
+ command.SetAction(async (parseResult, cancellationToken) =>
21
29
  {
30
+ var coreLocationDirectory = parseResult.GetValue(coreLocationOption);
31
+ var output = parseResult.GetValue(outputOption);
32
+
22
33
  // the tool is expected to be given the path to the .NET Core repository, but the correlator only needs a specific subdirectory
23
- var releaseNotesDirectory = new DirectoryInfo(Path.Combine(coreLocationDirectory.FullName, "release-notes"));
34
+ var releaseNotesDirectory = new DirectoryInfo(Path.Combine(coreLocationDirectory!.FullName, "release-notes"));
24
35
  var correlator = new Correlator(releaseNotesDirectory);
25
36
  var (sdkPackages, _warnings) = await correlator.RunAsync();
26
37
  var json = JsonSerializer.Serialize(sdkPackages, Correlator.SerializerOptions);
27
- await File.WriteAllTextAsync(output.FullName, json);
28
- }, coreLocationOption, outputOption);
29
- var exitCode = await command.InvokeAsync(args);
38
+ await File.WriteAllTextAsync(output!.FullName, json, cancellationToken);
39
+
40
+ return 0;
41
+ });
42
+ var parseResult = command.Parse(args);
43
+ var exitCode = await parseResult.InvokeAsync();
30
44
  return exitCode;
31
45
  }
32
46
  }
@@ -7,12 +7,12 @@ namespace NuGetUpdater.Cli.Commands;
7
7
 
8
8
  internal static class AnalyzeCommand
9
9
  {
10
- internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
11
- internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
12
- internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { IsRequired = true };
13
- internal static readonly Option<FileInfo> DependencyFilePathOption = new("--dependency-file-path") { IsRequired = true };
14
- internal static readonly Option<FileInfo> DiscoveryFilePathOption = new("--discovery-file-path") { IsRequired = true };
15
- internal static readonly Option<DirectoryInfo> AnalysisFolderOption = new("--analysis-folder-path") { IsRequired = true };
10
+ internal static readonly Option<string> JobIdOption = new("--job-id") { Required = true };
11
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { Required = true };
12
+ internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { Required = true };
13
+ internal static readonly Option<FileInfo> DependencyFilePathOption = new("--dependency-file-path") { Required = true };
14
+ internal static readonly Option<FileInfo> DiscoveryFilePathOption = new("--discovery-file-path") { Required = true };
15
+ internal static readonly Option<DirectoryInfo> AnalysisFolderOption = new("--analysis-folder-path") { Required = true };
16
16
 
17
17
  internal static Command GetCommand(Action<int> setExitCode)
18
18
  {
@@ -28,13 +28,21 @@ internal static class AnalyzeCommand
28
28
 
29
29
  command.TreatUnmatchedTokensAsErrors = true;
30
30
 
31
- command.SetHandler(async (jobId, jobPath, repoRoot, discoveryPath, dependencyPath, analysisDirectory) =>
31
+ command.SetAction(async (parseResult, cancellationToken) =>
32
32
  {
33
+ var jobId = parseResult.GetValue(JobIdOption);
34
+ var jobPath = parseResult.GetValue(JobPathOption);
35
+ var repoRoot = parseResult.GetValue(RepoRootOption);
36
+ var discoveryPath = parseResult.GetValue(DiscoveryFilePathOption);
37
+ var dependencyPath = parseResult.GetValue(DependencyFilePathOption);
38
+ var analysisDirectory = parseResult.GetValue(AnalysisFolderOption);
39
+
33
40
  var logger = new OpenTelemetryLogger();
34
- var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
35
- var worker = new AnalyzeWorker(jobId, experimentsManager, logger);
36
- await worker.RunAsync(repoRoot.FullName, discoveryPath.FullName, dependencyPath.FullName, analysisDirectory.FullName);
37
- }, JobIdOption, JobPathOption, RepoRootOption, DiscoveryFilePathOption, DependencyFilePathOption, AnalysisFolderOption);
41
+ var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId!, jobPath!.FullName);
42
+ var worker = new AnalyzeWorker(jobId!, experimentsManager, logger);
43
+ await worker.RunAsync(repoRoot!.FullName, discoveryPath!.FullName, dependencyPath!.FullName, analysisDirectory!.FullName);
44
+ return 0;
45
+ });
38
46
 
39
47
  return command;
40
48
  }
@@ -8,10 +8,14 @@ namespace NuGetUpdater.Cli.Commands;
8
8
 
9
9
  internal static class CloneCommand
10
10
  {
11
- internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
12
- internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { IsRequired = true };
13
- internal static readonly Option<Uri> ApiUrlOption = new("--api-url") { IsRequired = true };
14
- internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
11
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { Required = true };
12
+ internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { Required = true };
13
+ internal static readonly Option<Uri> ApiUrlOption = new("--api-url")
14
+ {
15
+ Required = true,
16
+ CustomParser = (argumentResult) => Uri.TryCreate(argumentResult.Tokens.Single().Value, UriKind.Absolute, out var uri) ? uri : throw new ArgumentException("Invalid API URL format.")
17
+ };
18
+ internal static readonly Option<string> JobIdOption = new("--job-id") { Required = true };
15
19
 
16
20
  internal static Command GetCommand(Action<int> setExitCode)
17
21
  {
@@ -25,15 +29,21 @@ internal static class CloneCommand
25
29
 
26
30
  command.TreatUnmatchedTokensAsErrors = true;
27
31
 
28
- command.SetHandler(async (jobPath, repoContentsPath, apiUrl, jobId) =>
32
+ command.SetAction(async (parseResult, cancellationToken) =>
29
33
  {
30
- var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
34
+ var jobPath = parseResult.GetValue(JobPathOption);
35
+ var repoContentsPath = parseResult.GetValue(RepoContentsPathOption);
36
+ var apiUrl = parseResult.GetValue(ApiUrlOption);
37
+ var jobId = parseResult.GetValue(JobIdOption);
38
+
39
+ var apiHandler = new HttpApiHandler(apiUrl!.ToString(), jobId!);
31
40
  var logger = new OpenTelemetryLogger();
32
41
  var gitCommandHandler = new ShellGitCommandHandler(logger);
33
- var worker = new CloneWorker(jobId, apiHandler, gitCommandHandler, logger);
34
- var exitCode = await worker.RunAsync(jobPath, repoContentsPath);
42
+ var worker = new CloneWorker(jobId!, apiHandler, gitCommandHandler, logger);
43
+ var exitCode = await worker.RunAsync(jobPath!, repoContentsPath!);
35
44
  setExitCode(exitCode);
36
- }, JobPathOption, RepoContentsPathOption, ApiUrlOption, JobIdOption);
45
+ return exitCode;
46
+ });
37
47
 
38
48
  return command;
39
49
  }
@@ -7,11 +7,11 @@ namespace NuGetUpdater.Cli.Commands;
7
7
 
8
8
  internal static class DiscoverCommand
9
9
  {
10
- internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
11
- internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
12
- internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { IsRequired = true };
13
- internal static readonly Option<string> WorkspaceOption = new("--workspace") { IsRequired = true };
14
- internal static readonly Option<FileInfo> OutputOption = new("--output") { IsRequired = true };
10
+ internal static readonly Option<string> JobIdOption = new("--job-id") { Required = true };
11
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { Required = true };
12
+ internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { Required = true };
13
+ internal static readonly Option<string> WorkspaceOption = new("--workspace") { Required = true };
14
+ internal static readonly Option<FileInfo> OutputOption = new("--output") { Required = true };
15
15
 
16
16
  internal static Command GetCommand(Action<int> setExitCode)
17
17
  {
@@ -26,27 +26,34 @@ internal static class DiscoverCommand
26
26
 
27
27
  command.TreatUnmatchedTokensAsErrors = true;
28
28
 
29
- command.SetHandler(async (jobId, jobPath, repoRoot, workspace, outputPath) =>
29
+ command.SetAction(async (parseResult, cancellationToken) =>
30
30
  {
31
+ var jobId = parseResult.GetValue(JobIdOption);
32
+ var jobPath = parseResult.GetValue(JobPathOption);
33
+ var repoRoot = parseResult.GetValue(RepoRootOption);
34
+ var workspace = parseResult.GetValue(WorkspaceOption);
35
+ var outputPath = parseResult.GetValue(OutputOption);
36
+
31
37
  var logger = new OpenTelemetryLogger();
32
- MSBuildHelper.RegisterMSBuild(repoRoot.FullName, repoRoot.FullName, logger);
33
- var (experimentsManager, error) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
38
+ MSBuildHelper.RegisterMSBuild(repoRoot!.FullName, repoRoot.FullName, logger);
39
+ var (experimentsManager, error) = await ExperimentsManager.FromJobFileAsync(jobId!, jobPath!.FullName);
34
40
  if (error is not null)
35
41
  {
36
42
  // to make testing easier, this should be a `WorkspaceDiscoveryResult` object
37
43
  var discoveryErrorResult = new WorkspaceDiscoveryResult
38
44
  {
39
45
  Error = error,
40
- Path = workspace,
46
+ Path = workspace!,
41
47
  Projects = [],
42
48
  };
43
- await DiscoveryWorker.WriteResultsAsync(repoRoot.FullName, outputPath.FullName, discoveryErrorResult);
44
- return;
49
+ await DiscoveryWorker.WriteResultsAsync(repoRoot.FullName, outputPath!.FullName, discoveryErrorResult);
50
+ return 0;
45
51
  }
46
52
 
47
- var worker = new DiscoveryWorker(jobId, experimentsManager, logger);
48
- await worker.RunAsync(repoRoot.FullName, workspace, outputPath.FullName);
49
- }, JobIdOption, JobPathOption, RepoRootOption, WorkspaceOption, OutputOption);
53
+ var worker = new DiscoveryWorker(jobId!, experimentsManager, logger);
54
+ await worker.RunAsync(repoRoot.FullName, workspace!, outputPath!.FullName);
55
+ return 0;
56
+ });
50
57
 
51
58
  return command;
52
59
  }
@@ -7,8 +7,8 @@ namespace NuGetUpdater.Cli.Commands;
7
7
 
8
8
  internal static class FrameworkCheckCommand
9
9
  {
10
- internal static readonly Option<string[]> ProjectTfmsOption = new("--project-tfms") { IsRequired = true, AllowMultipleArgumentsPerToken = true };
11
- internal static readonly Option<string[]> PackageTfmsOption = new("--package-tfms") { IsRequired = true, AllowMultipleArgumentsPerToken = true };
10
+ internal static readonly Option<string[]> ProjectTfmsOption = new("--project-tfms") { Required = true, AllowMultipleArgumentsPerToken = true };
11
+ internal static readonly Option<string[]> PackageTfmsOption = new("--package-tfms") { Required = true, AllowMultipleArgumentsPerToken = true };
12
12
 
13
13
  internal static Command GetCommand(Action<int> setExitCode)
14
14
  {
@@ -20,12 +20,15 @@ internal static class FrameworkCheckCommand
20
20
 
21
21
  command.TreatUnmatchedTokensAsErrors = true;
22
22
 
23
- command.SetHandler((projectTfms, packageTfms) =>
23
+ command.SetAction((parseResult) =>
24
24
  {
25
- setExitCode(CompatibilityChecker.IsCompatible(projectTfms, packageTfms, new ConsoleLogger())
25
+ var projectTfms = parseResult.GetValue(ProjectTfmsOption);
26
+ var packageTfms = parseResult.GetValue(PackageTfmsOption);
27
+
28
+ setExitCode(CompatibilityChecker.IsCompatible(projectTfms!, packageTfms!, new ConsoleLogger())
26
29
  ? 0
27
30
  : 1);
28
- }, ProjectTfmsOption, PackageTfmsOption);
31
+ });
29
32
 
30
33
  return command;
31
34
  }
@@ -9,13 +9,17 @@ namespace NuGetUpdater.Cli.Commands;
9
9
 
10
10
  internal static class RunCommand
11
11
  {
12
- internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
13
- internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { IsRequired = true };
14
- internal static readonly Option<DirectoryInfo?> CaseInsensitiveRepoContentsPathOption = new("--case-insensitive-repo-contents-path") { IsRequired = false };
15
- internal static readonly Option<Uri> ApiUrlOption = new("--api-url") { IsRequired = true };
16
- internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
17
- internal static readonly Option<FileInfo> OutputPathOption = new("--output-path") { IsRequired = true };
18
- internal static readonly Option<string> BaseCommitShaOption = new("--base-commit-sha") { IsRequired = true };
12
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { Required = true };
13
+ internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { Required = true };
14
+ internal static readonly Option<DirectoryInfo?> CaseInsensitiveRepoContentsPathOption = new("--case-insensitive-repo-contents-path") { Required = false };
15
+ internal static readonly Option<Uri> ApiUrlOption = new("--api-url")
16
+ {
17
+ Required = true,
18
+ CustomParser = (argumentResult) => Uri.TryCreate(argumentResult.Tokens.Single().Value, UriKind.Absolute, out var uri) ? uri : throw new ArgumentException("Invalid API URL format.")
19
+ };
20
+ internal static readonly Option<string> JobIdOption = new("--job-id") { Required = true };
21
+ internal static readonly Option<FileInfo> OutputPathOption = new("--output-path") { Required = true };
22
+ internal static readonly Option<string> BaseCommitShaOption = new("--base-commit-sha") { Required = true };
19
23
 
20
24
  internal static Command GetCommand(Action<int> setExitCode)
21
25
  {
@@ -32,17 +36,26 @@ internal static class RunCommand
32
36
 
33
37
  command.TreatUnmatchedTokensAsErrors = true;
34
38
 
35
- command.SetHandler(async (jobPath, repoContentsPath, caseInsensitiveRepoContentsPath, apiUrl, jobId, outputPath, baseCommitSha) =>
39
+ command.SetAction(async (parseResult, cancellationToken) =>
36
40
  {
37
- var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
38
- var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
41
+ var jobPath = parseResult.GetValue(JobPathOption);
42
+ var repoContentsPath = parseResult.GetValue(RepoContentsPathOption);
43
+ var caseInsensitiveRepoContentsPath = parseResult.GetValue(CaseInsensitiveRepoContentsPathOption);
44
+ var apiUrl = parseResult.GetValue(ApiUrlOption);
45
+ var jobId = parseResult.GetValue(JobIdOption);
46
+ var outputPath = parseResult.GetValue(OutputPathOption);
47
+ var baseCommitSha = parseResult.GetValue(BaseCommitShaOption);
48
+
49
+ var apiHandler = new HttpApiHandler(apiUrl!.ToString(), jobId!);
50
+ var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId!, jobPath!.FullName);
39
51
  var logger = new OpenTelemetryLogger();
40
- var discoverWorker = new DiscoveryWorker(jobId, experimentsManager, logger);
41
- var analyzeWorker = new AnalyzeWorker(jobId, experimentsManager, logger);
42
- var updateWorker = new UpdaterWorker(jobId, experimentsManager, logger);
43
- var worker = new RunWorker(jobId, apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
44
- await worker.RunAsync(jobPath, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, outputPath);
45
- }, JobPathOption, RepoContentsPathOption, CaseInsensitiveRepoContentsPathOption, ApiUrlOption, JobIdOption, OutputPathOption, BaseCommitShaOption);
52
+ var discoverWorker = new DiscoveryWorker(jobId!, experimentsManager, logger);
53
+ var analyzeWorker = new AnalyzeWorker(jobId!, experimentsManager, logger);
54
+ var updateWorker = new UpdaterWorker(jobId!, experimentsManager, logger);
55
+ var worker = new RunWorker(jobId!, apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
56
+ await worker.RunAsync(jobPath!, repoContentsPath!, caseInsensitiveRepoContentsPath, baseCommitSha!, outputPath!);
57
+ return 0;
58
+ });
46
59
 
47
60
  return command;
48
61
  }
@@ -6,15 +6,15 @@ namespace NuGetUpdater.Cli.Commands;
6
6
 
7
7
  internal static class UpdateCommand
8
8
  {
9
- internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
10
- internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
11
- internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root", () => new DirectoryInfo(Environment.CurrentDirectory)) { IsRequired = false };
12
- internal static readonly Option<FileInfo> SolutionOrProjectFileOption = new("--solution-or-project") { IsRequired = true };
13
- internal static readonly Option<string> DependencyNameOption = new("--dependency") { IsRequired = true };
14
- internal static readonly Option<string> NewVersionOption = new("--new-version") { IsRequired = true };
15
- internal static readonly Option<string> PreviousVersionOption = new("--previous-version") { IsRequired = true };
16
- internal static readonly Option<bool> IsTransitiveOption = new("--transitive", getDefaultValue: () => false);
17
- internal static readonly Option<string?> ResultOutputPathOption = new("--result-output-path", getDefaultValue: () => null);
9
+ internal static readonly Option<string> JobIdOption = new("--job-id") { Required = true };
10
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { Required = true };
11
+ internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { DefaultValueFactory = _ => new DirectoryInfo(Environment.CurrentDirectory), Required = false };
12
+ internal static readonly Option<FileInfo> SolutionOrProjectFileOption = new("--solution-or-project") { Required = true };
13
+ internal static readonly Option<string> DependencyNameOption = new("--dependency") { Required = true };
14
+ internal static readonly Option<string> NewVersionOption = new("--new-version") { Required = true };
15
+ internal static readonly Option<string> PreviousVersionOption = new("--previous-version") { Required = true };
16
+ internal static readonly Option<bool> IsTransitiveOption = new("--transitive") { DefaultValueFactory = _ => false };
17
+ internal static readonly Option<string?> ResultOutputPathOption = new("--result-output-path") { DefaultValueFactory = _ => null };
18
18
 
19
19
  internal static Command GetCommand(Action<int> setExitCode)
20
20
  {
@@ -32,24 +32,25 @@ internal static class UpdateCommand
32
32
  };
33
33
 
34
34
  command.TreatUnmatchedTokensAsErrors = true;
35
- command.SetHandler(async (context) =>
35
+ command.SetAction(async (parseResult, cancellationToken) =>
36
36
  {
37
37
  // since we have more than 8 arguments, we have to pull them out manually
38
- var jobId = context.ParseResult.GetValueForOption(JobIdOption)!;
39
- var jobPath = context.ParseResult.GetValueForOption(JobPathOption)!;
40
- var repoRoot = context.ParseResult.GetValueForOption(RepoRootOption)!;
41
- var solutionOrProjectFile = context.ParseResult.GetValueForOption(SolutionOrProjectFileOption)!;
42
- var dependencyName = context.ParseResult.GetValueForOption(DependencyNameOption)!;
43
- var newVersion = context.ParseResult.GetValueForOption(NewVersionOption)!;
44
- var previousVersion = context.ParseResult.GetValueForOption(PreviousVersionOption)!;
45
- var isTransitive = context.ParseResult.GetValueForOption(IsTransitiveOption);
46
- var resultOutputPath = context.ParseResult.GetValueForOption(ResultOutputPathOption);
38
+ var jobId = parseResult.GetValue(JobIdOption)!;
39
+ var jobPath = parseResult.GetValue(JobPathOption)!;
40
+ var repoRoot = parseResult.GetValue(RepoRootOption)!;
41
+ var solutionOrProjectFile = parseResult.GetValue(SolutionOrProjectFileOption)!;
42
+ var dependencyName = parseResult.GetValue(DependencyNameOption)!;
43
+ var newVersion = parseResult.GetValue(NewVersionOption)!;
44
+ var previousVersion = parseResult.GetValue(PreviousVersionOption)!;
45
+ var isTransitive = parseResult.GetValue(IsTransitiveOption);
46
+ var resultOutputPath = parseResult.GetValue(ResultOutputPathOption);
47
47
 
48
48
  var (experimentsManager, _error) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
49
49
  var logger = new OpenTelemetryLogger();
50
50
  var worker = new UpdaterWorker(jobId, experimentsManager, logger);
51
51
  await worker.RunAsync(repoRoot.FullName, solutionOrProjectFile.FullName, dependencyName, previousVersion, newVersion, isTransitive, resultOutputPath);
52
52
  setExitCode(0);
53
+ return 0;
53
54
  });
54
55
 
55
56
  return command;
@@ -27,7 +27,8 @@ internal sealed class Program
27
27
  };
28
28
  command.TreatUnmatchedTokensAsErrors = true;
29
29
 
30
- var result = await command.InvokeAsync(args);
30
+ var parseResult = command.Parse(args);
31
+ var result = await parseResult.InvokeAsync();
31
32
 
32
33
  return result == 0
33
34
  ? exitCode
@@ -6,5 +6,7 @@
6
6
  because that's irrelevant to dependency discovery.
7
7
  -->
8
8
  <NoWarn>$(NoWarn);MSB3644</NoWarn>
9
+ <!-- A package downgrade warning shouldn't be lifted to an error because that would prevent discovery. -->
10
+ <NoWarn>$(NoWarn);NU1605</NoWarn>
9
11
  </PropertyGroup>
10
12
  </Project>
@@ -0,0 +1,8 @@
1
+ using System.Collections.Immutable;
2
+
3
+ namespace NuGetUpdater.Core.DependencySolver;
4
+
5
+ public interface IDependencySolver
6
+ {
7
+ Task<ImmutableArray<Dependency>?> SolveAsync(ImmutableArray<Dependency> existingTopLevelDependencies, ImmutableArray<Dependency> desiredDependencies, string targetFramework);
8
+ }
@@ -0,0 +1,32 @@
1
+ using System.Collections.Immutable;
2
+
3
+ namespace NuGetUpdater.Core.DependencySolver;
4
+
5
+ public class MSBuildDependencySolver : IDependencySolver
6
+ {
7
+ private readonly DirectoryInfo _repoContentsPath;
8
+ private readonly FileInfo _projectPath;
9
+ private readonly ExperimentsManager _experimentsManager;
10
+ private readonly ILogger _logger;
11
+
12
+ public MSBuildDependencySolver(DirectoryInfo repoContentsPath, FileInfo projectPath, ExperimentsManager experimentsManager, ILogger logger)
13
+ {
14
+ _repoContentsPath = repoContentsPath;
15
+ _projectPath = projectPath;
16
+ _experimentsManager = experimentsManager;
17
+ _logger = logger;
18
+ }
19
+
20
+ public async Task<ImmutableArray<Dependency>?> SolveAsync(ImmutableArray<Dependency> existingTopLevelDependencies, ImmutableArray<Dependency> desiredDependencies, string targetFramework)
21
+ {
22
+ var result = await MSBuildHelper.ResolveDependencyConflicts(
23
+ _repoContentsPath.FullName,
24
+ _projectPath.FullName,
25
+ targetFramework,
26
+ existingTopLevelDependencies,
27
+ desiredDependencies,
28
+ _experimentsManager,
29
+ _logger);
30
+ return result;
31
+ }
32
+ }
@@ -15,4 +15,5 @@ public record ProjectDiscoveryResult : IDiscoveryResultWithDependencies
15
15
  public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
16
16
  public required ImmutableArray<string> ImportedFiles { get; init; }
17
17
  public required ImmutableArray<string> AdditionalFiles { get; init; }
18
+ public bool CentralPackageTransitivePinningEnabled { get; init; } = false;
18
19
  }
@@ -526,7 +526,8 @@ internal static class SdkProjectDiscovery
526
526
  .ToImmutableArray();
527
527
 
528
528
  // others
529
- var properties = resolvedProperties[projectPath]
529
+ var projectProperties = resolvedProperties[projectPath];
530
+ var properties = projectProperties
530
531
  .Where(pkvp => projectPropertyNames.Contains(pkvp.Key))
531
532
  .Select(pkvp => new Property(pkvp.Key, pkvp.Value, Path.GetRelativePath(repoRootPath, projectPath).NormalizePathToUnix()))
532
533
  .OrderBy(p => p.Name)
@@ -547,6 +548,13 @@ internal static class SdkProjectDiscovery
547
548
  .Select(p => p.NormalizePathToUnix())
548
549
  .OrderBy(p => p)
549
550
  .ToImmutableArray();
551
+ var useCpmTransitivePinning =
552
+ projectProperties.TryGetValue("ManagePackageVersionsCentrally", out var useCpmString) &&
553
+ bool.TryParse(useCpmString, out var useCpm) &&
554
+ useCpm &&
555
+ projectProperties.TryGetValue("CentralPackageTransitivePinningEnabled", out var useTransitivePinningString) &&
556
+ bool.TryParse(useTransitivePinningString, out var useTransitivePinning) &&
557
+ useTransitivePinning;
550
558
 
551
559
  var projectDiscoveryResult = new ProjectDiscoveryResult()
552
560
  {
@@ -557,6 +565,7 @@ internal static class SdkProjectDiscovery
557
565
  ReferencedProjectPaths = referenced,
558
566
  ImportedFiles = imported,
559
567
  AdditionalFiles = additional,
568
+ CentralPackageTransitivePinningEnabled = useCpmTransitivePinning,
560
569
  };
561
570
  projectDiscoveryResults.Add(projectDiscoveryResult);
562
571
  }
@@ -15,4 +15,10 @@ public sealed record WorkspaceDiscoveryResult : NativeResult
15
15
  var projectDiscovery = Projects.FirstOrDefault(p => System.IO.Path.Join(Path, p.FilePath).FullyNormalizedRootedPath().Equals(repoPath, StringComparison.OrdinalIgnoreCase));
16
16
  return projectDiscovery;
17
17
  }
18
+
19
+ public ProjectDiscoveryResult? GetProjectDiscoveryFromFullPath(DirectoryInfo repoContentsPath, FileInfo projectPath)
20
+ {
21
+ var projectDiscovery = Projects.FirstOrDefault(p => System.IO.Path.Join(repoContentsPath.FullName, Path, p.FilePath).FullyNormalizedRootedPath().Equals(projectPath.FullName.FullyNormalizedRootedPath(), StringComparison.OrdinalIgnoreCase));
22
+ return projectDiscovery;
23
+ }
18
24
  }
@@ -12,6 +12,7 @@ public record ExperimentsManager
12
12
  public bool UseLegacyDependencySolver { get; init; } = false;
13
13
  public bool UseLegacyUpdateHandler { get; init; } = false;
14
14
  public bool UseDirectDiscovery { get; init; } = false;
15
+ public bool UseNewFileUpdater { get; init; } = false;
15
16
 
16
17
  public Dictionary<string, object> ToDictionary()
17
18
  {
@@ -22,6 +23,7 @@ public record ExperimentsManager
22
23
  ["nuget_legacy_dependency_solver"] = UseLegacyDependencySolver,
23
24
  ["nuget_use_legacy_update_handler"] = UseLegacyUpdateHandler,
24
25
  ["nuget_use_direct_discovery"] = UseDirectDiscovery,
26
+ ["nuget_use_new_file_updater"] = UseNewFileUpdater,
25
27
  };
26
28
  }
27
29
 
@@ -34,6 +36,7 @@ public record ExperimentsManager
34
36
  UseLegacyDependencySolver = IsEnabled(experiments, "nuget_legacy_dependency_solver"),
35
37
  UseLegacyUpdateHandler = IsEnabled(experiments, "nuget_use_legacy_update_handler"),
36
38
  UseDirectDiscovery = IsEnabled(experiments, "nuget_use_direct_discovery"),
39
+ UseNewFileUpdater = IsEnabled(experiments, "nuget_use_new_file_updater"),
37
40
  };
38
41
  }
39
42