dependabot-nuget 0.288.0 → 0.290.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +19 -17
  3. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +29 -2
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +25 -4
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +33 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +25 -10
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +60 -66
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +11 -3
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +1 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +54 -11
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +1 -2
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +67 -58
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +15 -44
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +2 -10
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +38 -33
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +25 -23
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +18 -17
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +17 -9
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +87 -5
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -5
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +16 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +6 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +143 -36
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +184 -48
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -5
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +32 -10
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +402 -102
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +342 -2
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -14
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  74. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +95 -0
  75. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -7
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +558 -711
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +47 -2
  80. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +4 -2
  81. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  82. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  83. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  84. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  85. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  86. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  87. data/lib/dependabot/nuget/file_fetcher.rb +11 -393
  88. data/lib/dependabot/nuget/file_parser.rb +23 -61
  89. data/lib/dependabot/nuget/file_updater.rb +28 -23
  90. data/lib/dependabot/nuget/native_helpers.rb +14 -5
  91. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  92. data/lib/dependabot/nuget/update_checker.rb +116 -190
  93. metadata +20 -32
  94. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  95. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  96. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  97. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
  98. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  99. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  100. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -129
  101. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -171
  102. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  103. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -82
  104. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  105. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -68
  106. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  107. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -201
  108. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  109. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  110. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  111. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  112. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  113. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  114. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  115. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  116. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  117. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -18,7 +18,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
18
18
 
19
19
  private readonly ExperimentsManager _experimentsManager;
20
20
  private readonly ILogger _logger;
21
- private readonly HashSet<string> _processedProjectPaths = new(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> _restoredMSBuildSdks = new(StringComparer.OrdinalIgnoreCase);
21
+ private readonly HashSet<string> _processedProjectPaths = new(StringComparer.Ordinal); private readonly HashSet<string> _restoredMSBuildSdks = new(StringComparer.OrdinalIgnoreCase);
22
22
 
23
23
  internal static readonly JsonSerializerOptions SerializerOptions = new()
24
24
  {
@@ -54,7 +54,6 @@ public partial class DiscoveryWorker : IDiscoveryWorker
54
54
  ErrorDetails = "(" + string.Join("|", NuGetContext.GetPackageSourceUrls(PathHelper.JoinPath(repoRootPath, workspacePath))) + ")",
55
55
  Path = workspacePath,
56
56
  Projects = [],
57
- ImportedFiles = [],
58
57
  };
59
58
  }
60
59
 
@@ -83,7 +82,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
83
82
 
84
83
  if (Directory.Exists(workspacePath))
85
84
  {
86
- _logger.Log($"Discovering build files in workspace [{workspacePath}].");
85
+ _logger.Info($"Discovering build files in workspace [{workspacePath}].");
87
86
 
88
87
  dotNetToolsJsonDiscovery = DotNetToolsJsonDiscovery.Discover(repoRootPath, workspacePath, _logger);
89
88
  globalJsonDiscovery = GlobalJsonDiscovery.Discover(repoRootPath, workspacePath, _logger);
@@ -98,18 +97,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
98
97
  }
99
98
  else
100
99
  {
101
- _logger.Log($"Workspace path [{workspacePath}] does not exist.");
102
- }
103
-
104
- var importedFiles = new HashSet<string>(PathComparer.Instance);
105
- foreach (var project in projectResults)
106
- {
107
- // imported files are relative to the project and need to be converted to be relative to the repo root
108
- var repoRootRelativeImportedFiles = project.ImportedFiles
109
- .Select(p => Path.Join(Path.GetDirectoryName(project.FilePath) ?? "", p))
110
- .Select(p => p.NormalizePathToUnix().NormalizeUnixPathParts())
111
- .ToArray();
112
- importedFiles.AddRange(repoRootRelativeImportedFiles);
100
+ _logger.Info($"Workspace path [{workspacePath}] does not exist.");
113
101
  }
114
102
 
115
103
  result = new WorkspaceDiscoveryResult
@@ -118,10 +106,9 @@ public partial class DiscoveryWorker : IDiscoveryWorker
118
106
  DotNetToolsJson = dotNetToolsJsonDiscovery,
119
107
  GlobalJson = globalJsonDiscovery,
120
108
  Projects = projectResults.OrderBy(p => p.FilePath).ToImmutableArray(),
121
- ImportedFiles = importedFiles.ToImmutableArray(),
122
109
  };
123
110
 
124
- _logger.Log("Discovery complete.");
111
+ _logger.Info("Discovery complete.");
125
112
  _processedProjectPaths.Clear();
126
113
 
127
114
  return result;
@@ -148,19 +135,19 @@ public partial class DiscoveryWorker : IDiscoveryWorker
148
135
 
149
136
  _restoredMSBuildSdks.AddRange(keys);
150
137
 
151
- _logger.Log($" Restoring MSBuild SDKs: {string.Join(", ", keys)}");
138
+ _logger.Info($" Restoring MSBuild SDKs: {string.Join(", ", keys)}");
152
139
 
153
140
  return await NuGetHelper.DownloadNuGetPackagesAsync(repoRootPath, workspacePath, msbuildSdks, logger);
154
141
  }
155
142
 
156
143
  private async Task<ImmutableArray<ProjectDiscoveryResult>> RunForDirectoryAsnyc(string repoRootPath, string workspacePath)
157
144
  {
158
- _logger.Log($" Discovering projects beneath [{Path.GetRelativePath(repoRootPath, workspacePath)}].");
145
+ _logger.Info($" Discovering projects beneath [{Path.GetRelativePath(repoRootPath, workspacePath)}].");
159
146
  var entryPoints = FindEntryPoints(workspacePath);
160
147
  var projects = ExpandEntryPointsIntoProjects(entryPoints);
161
148
  if (projects.IsEmpty)
162
149
  {
163
- _logger.Log(" No project files found.");
150
+ _logger.Info(" No project files found.");
164
151
  return [];
165
152
  }
166
153
 
@@ -277,74 +264,81 @@ public partial class DiscoveryWorker : IDiscoveryWorker
277
264
 
278
265
  private async Task<ImmutableArray<ProjectDiscoveryResult>> RunForProjectPathsAsync(string repoRootPath, string workspacePath, IEnumerable<string> projectPaths)
279
266
  {
280
- var results = new Dictionary<string, ProjectDiscoveryResult>(StringComparer.OrdinalIgnoreCase);
267
+ var results = new Dictionary<string, ProjectDiscoveryResult>(StringComparer.Ordinal);
281
268
  foreach (var projectPath in projectPaths)
282
269
  {
283
270
  // If there is some MSBuild logic that needs to run to fully resolve the path skip the project
284
271
  // Ensure file existence is checked case-insensitively
285
- var actualProjectPath = PathHelper.ResolveCaseInsensitivePathInsideRepoRoot(projectPath, repoRootPath);
286
- if (actualProjectPath == null)
287
- {
288
- continue;
289
- }
272
+ var actualProjectPaths = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(projectPath, repoRootPath);
290
273
 
291
- if (_processedProjectPaths.Contains(actualProjectPath))
274
+ if (actualProjectPaths == null)
292
275
  {
293
276
  continue;
294
277
  }
295
- _processedProjectPaths.Add(actualProjectPath);
296
278
 
297
- var relativeProjectPath = Path.GetRelativePath(workspacePath, actualProjectPath).NormalizePathToUnix();
298
- var packagesConfigResult = await PackagesConfigDiscovery.Discover(repoRootPath, workspacePath, actualProjectPath, _logger);
299
- var projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
300
-
301
- // Determine if there were unrestored MSBuildSdks
302
- var msbuildSdks = projectResults.SelectMany(p => p.Dependencies.Where(d => d.Type == DependencyType.MSBuildSdk)).ToImmutableArray();
303
- if (msbuildSdks.Length > 0)
279
+ foreach (var actualProjectPath in actualProjectPaths)
304
280
  {
305
- // If new SDKs were restored, then we need to rerun SdkProjectDiscovery.
306
- if (await TryRestoreMSBuildSdksAsync(repoRootPath, workspacePath, msbuildSdks, _logger))
281
+ if (_processedProjectPaths.Contains(actualProjectPath))
307
282
  {
308
- projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
283
+ continue;
309
284
  }
310
- }
311
285
 
312
- foreach (var projectResult in projectResults)
313
- {
314
- if (results.ContainsKey(projectResult.FilePath))
286
+ _processedProjectPaths.Add(actualProjectPath);
287
+
288
+ var relativeProjectPath = Path.GetRelativePath(workspacePath, actualProjectPath).NormalizePathToUnix();
289
+ var packagesConfigResult = await PackagesConfigDiscovery.Discover(repoRootPath, workspacePath, actualProjectPath, _logger);
290
+ var projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
291
+
292
+ // Determine if there were unrestored MSBuildSdks
293
+ var msbuildSdks = projectResults.SelectMany(p => p.Dependencies.Where(d => d.Type == DependencyType.MSBuildSdk)).ToImmutableArray();
294
+ if (msbuildSdks.Length > 0)
315
295
  {
316
- continue;
296
+ // If new SDKs were restored, then we need to rerun SdkProjectDiscovery.
297
+ if (await TryRestoreMSBuildSdksAsync(repoRootPath, workspacePath, msbuildSdks, _logger))
298
+ {
299
+ projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
300
+ }
317
301
  }
318
302
 
319
- // If we had packages.config dependencies, merge them with the project dependencies
320
- if (projectResult.FilePath == relativeProjectPath && packagesConfigResult is not null)
303
+ foreach (var projectResult in projectResults)
321
304
  {
322
- var packagesConfigDependencies = packagesConfigResult.Dependencies
323
- .Select(d => d with { TargetFrameworks = projectResult.TargetFrameworks })
324
- .ToImmutableArray();
305
+ if (results.ContainsKey(projectResult.FilePath))
306
+ {
307
+ continue;
308
+ }
325
309
 
326
- results[projectResult.FilePath] = projectResult with
310
+ // If we had packages.config dependencies, merge them with the project dependencies
311
+ if (projectResult.FilePath == relativeProjectPath && packagesConfigResult is not null)
327
312
  {
328
- Dependencies = [.. projectResult.Dependencies, .. packagesConfigDependencies],
329
- };
330
- }
331
- else
332
- {
333
- results[projectResult.FilePath] = projectResult;
313
+ var packagesConfigDependencies = packagesConfigResult.Dependencies
314
+ .Select(d => d with { TargetFrameworks = projectResult.TargetFrameworks })
315
+ .ToImmutableArray();
316
+
317
+ results[projectResult.FilePath] = projectResult with
318
+ {
319
+ Dependencies = [.. projectResult.Dependencies, .. packagesConfigDependencies],
320
+ };
321
+ }
322
+ else
323
+ {
324
+ results[projectResult.FilePath] = projectResult;
325
+ }
334
326
  }
335
- }
336
327
 
337
- if (!results.ContainsKey(relativeProjectPath) &&
338
- packagesConfigResult is not null &&
339
- packagesConfigResult.Dependencies.Length > 0)
340
- {
341
- // project contained only packages.config dependencies
342
- results[relativeProjectPath] = new ProjectDiscoveryResult()
328
+ if (!results.ContainsKey(relativeProjectPath) &&
329
+ packagesConfigResult is not null &&
330
+ packagesConfigResult.Dependencies.Length > 0)
343
331
  {
344
- FilePath = relativeProjectPath,
345
- Dependencies = packagesConfigResult.Dependencies,
346
- TargetFrameworks = packagesConfigResult.TargetFrameworks,
347
- };
332
+ // project contained only packages.config dependencies
333
+ results[relativeProjectPath] = new ProjectDiscoveryResult()
334
+ {
335
+ FilePath = relativeProjectPath,
336
+ Dependencies = packagesConfigResult.Dependencies,
337
+ TargetFrameworks = packagesConfigResult.TargetFrameworks,
338
+ ImportedFiles = [], // no imported files resolved for packages.config scenarios
339
+ AdditionalFiles = packagesConfigResult.AdditionalFiles,
340
+ };
341
+ }
348
342
  }
349
343
  }
350
344
 
@@ -8,13 +8,13 @@ internal static class DotNetToolsJsonDiscovery
8
8
  {
9
9
  if (!MSBuildHelper.TryGetDotNetToolsJsonPath(repoRootPath, workspacePath, out var dotnetToolsJsonPath))
10
10
  {
11
- logger.Log(" No dotnet-tools.json file found.");
11
+ logger.Info(" No dotnet-tools.json file found.");
12
12
  return null;
13
13
  }
14
14
 
15
15
  var dotnetToolsJsonFile = DotNetToolsJsonBuildFile.Open(workspacePath, dotnetToolsJsonPath, logger);
16
16
 
17
- logger.Log($" Discovered [{dotnetToolsJsonFile.RelativePath}] file.");
17
+ logger.Info($" Discovered [{dotnetToolsJsonFile.RelativePath}] file.");
18
18
 
19
19
  var dependencies = BuildFile.GetDependencies(dotnetToolsJsonFile)
20
20
  .OrderBy(d => d.Name)
@@ -8,13 +8,13 @@ internal static class GlobalJsonDiscovery
8
8
  {
9
9
  if (!MSBuildHelper.TryGetGlobalJsonPath(repoRootPath, workspacePath, out var globalJsonPath))
10
10
  {
11
- logger.Log(" No global.json file found.");
11
+ logger.Info(" No global.json file found.");
12
12
  return null;
13
13
  }
14
14
 
15
15
  var globalJsonFile = GlobalJsonBuildFile.Open(workspacePath, globalJsonPath, logger);
16
16
 
17
- logger.Log($" Discovered [{globalJsonFile.RelativePath}] file.");
17
+ logger.Info($" Discovered [{globalJsonFile.RelativePath}] file.");
18
18
 
19
19
  var dependencies = BuildFile.GetDependencies(globalJsonFile)
20
20
  .OrderBy(d => d.Name)
@@ -1,20 +1,26 @@
1
1
  using System.Collections.Immutable;
2
2
 
3
+ using NuGetUpdater.Core.Utilities;
4
+
3
5
  namespace NuGetUpdater.Core.Discover;
4
6
 
5
7
  internal static class PackagesConfigDiscovery
6
8
  {
7
9
  public static async Task<PackagesConfigDiscoveryResult?> Discover(string repoRootPath, string workspacePath, string projectPath, ILogger logger)
8
10
  {
9
- if (!NuGetHelper.TryGetPackagesConfigFile(projectPath, out var packagesConfigPath))
11
+ var projectDirectory = Path.GetDirectoryName(projectPath)!;
12
+ var additionalFiles = ProjectHelper.GetAllAdditionalFilesFromProject(projectPath, ProjectHelper.PathFormat.Full);
13
+ var packagesConfigPath = additionalFiles.FirstOrDefault(p => Path.GetFileName(p).Equals(ProjectHelper.PackagesConfigFileName, StringComparison.Ordinal));
14
+
15
+ if (packagesConfigPath is null)
10
16
  {
11
- logger.Log(" No packages.config file found.");
17
+ logger.Info(" No packages.config file found.");
12
18
  return null;
13
19
  }
14
20
 
15
21
  var packagesConfigFile = PackagesConfigBuildFile.Open(workspacePath, packagesConfigPath);
16
22
 
17
- logger.Log($" Discovered [{packagesConfigFile.RelativePath}] file.");
23
+ logger.Info($" Discovered [{packagesConfigFile.RelativePath}] file.");
18
24
 
19
25
  var dependencies = BuildFile.GetDependencies(packagesConfigFile)
20
26
  .OrderBy(d => d.Name)
@@ -23,11 +29,13 @@ internal static class PackagesConfigDiscovery
23
29
  // generate `$(TargetFramework)` via MSBuild
24
30
  var tfms = await MSBuildHelper.GetTargetFrameworkValuesFromProject(repoRootPath, projectPath, logger);
25
31
 
32
+ var additionalFilesRelative = additionalFiles.Select(p => Path.GetRelativePath(projectDirectory, p).NormalizePathToUnix()).ToImmutableArray();
26
33
  return new()
27
34
  {
28
35
  FilePath = packagesConfigFile.RelativePath,
29
36
  Dependencies = dependencies.Select(d => d with { TargetFrameworks = tfms }).ToImmutableArray(),
30
37
  TargetFrameworks = tfms,
38
+ AdditionalFiles = additionalFilesRelative,
31
39
  };
32
40
  }
33
41
  }
@@ -8,4 +8,5 @@ public sealed record PackagesConfigDiscoveryResult : IDiscoveryResultWithDepende
8
8
  public bool IsSuccess { get; init; } = true;
9
9
  public required ImmutableArray<Dependency> Dependencies { get; init; }
10
10
  public required ImmutableArray<string> TargetFrameworks { get; init; }
11
+ public required ImmutableArray<string> AdditionalFiles { get; init; }
11
12
  }
@@ -11,8 +11,6 @@ public record ProjectDiscoveryResult : IDiscoveryResultWithDependencies
11
11
  public ImmutableArray<Property> Properties { get; init; } = [];
12
12
  public ImmutableArray<string> TargetFrameworks { get; init; } = [];
13
13
  public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
14
-
15
- // this is purely for internal record keeping and should not be serialized
16
- [JsonIgnore]
17
- public ImmutableArray<string> ImportedFiles { get; init; } = [];
14
+ public required ImmutableArray<string> ImportedFiles { get; init; }
15
+ public required ImmutableArray<string> AdditionalFiles { get; init; }
18
16
  }
@@ -36,6 +36,14 @@ internal static class SdkProjectDiscovery
36
36
  "NETStandard.Library"
37
37
  };
38
38
 
39
+ // these are additional files that are relevant to the project and need to be reported
40
+ private static readonly HashSet<string> AdditionalFileNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
41
+ {
42
+ "packages.config",
43
+ "app.config",
44
+ "web.config",
45
+ };
46
+
39
47
  public static async Task<ImmutableArray<ProjectDiscoveryResult>> DiscoverAsync(string repoRootPath, string workspacePath, string startingProjectPath, ExperimentsManager experimentsManager, ILogger logger)
40
48
  {
41
49
  if (experimentsManager.UseDirectDiscovery)
@@ -73,6 +81,9 @@ internal static class SdkProjectDiscovery
73
81
  Dictionary<string, HashSet<string>> referencedProjects = new(PathComparer.Instance);
74
82
  // projectPath, referencedProjects
75
83
 
84
+ Dictionary<string, HashSet<string>> additionalFiles = new(PathComparer.Instance);
85
+ // projectPath, additionalFiles
86
+
76
87
  var tfms = await MSBuildHelper.GetTargetFrameworkValuesFromProject(repoRootPath, startingProjectPath, logger);
77
88
  foreach (var tfm in tfms)
78
89
  {
@@ -106,7 +117,7 @@ internal static class SdkProjectDiscovery
106
117
  if (exitCode != 0)
107
118
  {
108
119
  // log error, but still try to resolve what we can
109
- logger.Log($" Error determining dependencies from `{startingProjectPath}`:\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
120
+ logger.Warn($" Error determining dependencies from `{startingProjectPath}`:\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
110
121
  }
111
122
 
112
123
  var buildRoot = BinaryLog.ReadBuild(binLogPath);
@@ -154,17 +165,39 @@ internal static class SdkProjectDiscovery
154
165
  case NamedNode namedNode when namedNode is AddItem or RemoveItem:
155
166
  ProcessResolvedPackageReference(namedNode, packagesPerProject, topLevelPackagesPerProject);
156
167
 
157
- // maintain list of project references
158
- if (namedNode is AddItem addItem && addItem.Name == "ProjectReference")
168
+ if (namedNode is AddItem addItem)
159
169
  {
160
- var projectEvaluation = GetNearestProjectEvaluation(addItem);
161
- if (projectEvaluation is not null)
170
+ // maintain list of project references
171
+ if (addItem.Name.Equals("ProjectReference", StringComparison.OrdinalIgnoreCase))
172
+ {
173
+ var projectEvaluation = GetNearestProjectEvaluation(addItem);
174
+ if (projectEvaluation is not null)
175
+ {
176
+ foreach (var referencedProject in addItem.Children.OfType<Item>())
177
+ {
178
+ var referencedProjectPaths = referencedProjects.GetOrAdd(projectEvaluation.ProjectFile, () => new(PathComparer.Instance));
179
+ var referencedProjectPath = new FileInfo(Path.Combine(Path.GetDirectoryName(projectEvaluation.ProjectFile)!, referencedProject.Name)).FullName;
180
+ referencedProjectPaths.Add(referencedProjectPath);
181
+ }
182
+ }
183
+ }
184
+
185
+ // maintain list of additional files
186
+ if (addItem.Name.Equals("None", StringComparison.OrdinalIgnoreCase) ||
187
+ addItem.Name.Equals("Content", StringComparison.OrdinalIgnoreCase))
162
188
  {
163
- foreach (var referencedProject in addItem.Children.OfType<Item>())
189
+ var projectEvaluation = GetNearestProjectEvaluation(addItem);
190
+ if (projectEvaluation is not null)
164
191
  {
165
- var referencedProjectPaths = referencedProjects.GetOrAdd(projectEvaluation.ProjectFile, () => new(PathComparer.Instance));
166
- var referencedProjectPath = new FileInfo(Path.Combine(Path.GetDirectoryName(projectEvaluation.ProjectFile)!, referencedProject.Name)).FullName;
167
- referencedProjectPaths.Add(referencedProjectPath);
192
+ foreach (var additionalItem in addItem.Children.OfType<Item>())
193
+ {
194
+ if (AdditionalFileNames.Contains(additionalItem.Name))
195
+ {
196
+ var additionalFilesForProject = additionalFiles.GetOrAdd(projectEvaluation.ProjectFile, () => new(PathComparer.Instance));
197
+ var additionalFilePath = new FileInfo(Path.Combine(Path.GetDirectoryName(projectEvaluation.ProjectFile)!, additionalItem.Name)).FullName;
198
+ additionalFilesForProject.Add(additionalFilePath);
199
+ }
200
+ }
168
201
  }
169
202
  }
170
203
  }
@@ -220,11 +253,18 @@ internal static class SdkProjectDiscovery
220
253
  .Select(pkvp => new Property(pkvp.Key, pkvp.Value, Path.GetRelativePath(repoRootPath, projectPath).NormalizePathToUnix()))
221
254
  .OrderBy(p => p.Name)
222
255
  .ToImmutableArray();
223
- var referenced = referencedProjects.GetOrAdd(projectPath, () => new(StringComparer.OrdinalIgnoreCase))
256
+ var referenced = referencedProjects.GetOrAdd(projectPath, () => new(PathComparer.Instance))
224
257
  .Select(p => Path.GetRelativePath(projectFullDirectory, p).NormalizePathToUnix())
225
258
  .OrderBy(p => p)
226
259
  .ToImmutableArray();
227
- var imported = importedFiles.GetOrAdd(projectPath, () => new(StringComparer.OrdinalIgnoreCase))
260
+ var imported = importedFiles.GetOrAdd(projectPath, () => new(PathComparer.Instance))
261
+ .Select(p => Path.GetRelativePath(projectFullDirectory, p))
262
+ .Select(p => p.NormalizePathToUnix())
263
+ .OrderBy(p => p)
264
+ .ToImmutableArray();
265
+ var additionalFromLocation = ProjectHelper.GetAdditionalFilesFromProjectLocation(projectPath, ProjectHelper.PathFormat.Full);
266
+ var additional = additionalFiles.GetOrAdd(projectPath, () => new(PathComparer.Instance))
267
+ .Concat(additionalFromLocation)
228
268
  .Select(p => Path.GetRelativePath(projectFullDirectory, p))
229
269
  .Select(p => p.NormalizePathToUnix())
230
270
  .OrderBy(p => p)
@@ -238,6 +278,7 @@ internal static class SdkProjectDiscovery
238
278
  Properties = properties,
239
279
  ReferencedProjectPaths = referenced,
240
280
  ImportedFiles = imported,
281
+ AdditionalFiles = additional,
241
282
  };
242
283
  }).ToImmutableArray();
243
284
  return projectDiscoveryResults;
@@ -448,6 +489,7 @@ internal static class SdkProjectDiscovery
448
489
  Path.Join(Path.GetDirectoryName(buildFile.Path), "obj"),
449
490
  };
450
491
  var projectDirectory = Path.GetDirectoryName(buildFile.Path)!;
492
+ var additionalFiles = ProjectHelper.GetAllAdditionalFilesFromProject(buildFile.Path, ProjectHelper.PathFormat.Relative);
451
493
  results.Add(new()
452
494
  {
453
495
  FilePath = Path.GetRelativePath(workspacePath, buildFile.Path).NormalizePathToUnix(),
@@ -463,6 +505,7 @@ internal static class SdkProjectDiscovery
463
505
  .Where(b => !intermediateDirectories.Any(i => PathHelper.IsFileUnderDirectory(new DirectoryInfo(i), new FileInfo(b.Path))))
464
506
  .Select(b => Path.GetRelativePath(projectDirectory, b.Path).NormalizePathToUnix())
465
507
  .ToImmutableArray(),
508
+ AdditionalFiles = additionalFiles,
466
509
  });
467
510
  }
468
511
  }
@@ -7,7 +7,6 @@ public sealed record WorkspaceDiscoveryResult : NativeResult
7
7
  public required string Path { get; init; }
8
8
  public bool IsSuccess { get; init; } = true;
9
9
  public ImmutableArray<ProjectDiscoveryResult> Projects { get; init; }
10
- public ImmutableArray<string> ImportedFiles { get; init; } = [];
11
10
  public GlobalJsonDiscoveryResult? GlobalJson { get; init; }
12
11
  public DotNetToolsJsonDiscoveryResult? DotNetToolsJson { get; init; }
13
12
  }
@@ -37,8 +37,7 @@ public record ExperimentsManager
37
37
  }
38
38
  catch (JsonException ex)
39
39
  {
40
- // the following message has been specifically designed to match the format of `Dependabot.logger.info(...)` from Ruby
41
- logger.Log($"{DateTime.UtcNow:yyyy/MM/dd HH:mm:ss} INFO Error deserializing job file: {ex.ToString()}: {jobFileContent}");
40
+ logger.Info($"Error deserializing job file: {ex.ToString()}: {jobFileContent}");
42
41
  return new ExperimentsManager();
43
42
  }
44
43
  }
@@ -39,7 +39,7 @@ internal abstract class JsonBuildFile : BuildFile<string>
39
39
  {
40
40
  // We can't police that people have legal JSON files.
41
41
  // If they don't, we just return null.
42
- logger.Log($"Failed to parse JSON file: {RelativePath}, got {ex}");
42
+ logger.Warn($"Failed to parse JSON file: {RelativePath}, got {ex}");
43
43
  FailedToParse = true;
44
44
  return null;
45
45
  }
@@ -15,11 +15,11 @@ public class CompatibilityChecker
15
15
  var incompatibleFrameworks = projectFrameworks.Where(f => !compatibleFrameworks.Contains(f)).ToArray();
16
16
  if (incompatibleFrameworks.Length > 0)
17
17
  {
18
- logger.Log($"The package is not compatible. Incompatible project frameworks: {string.Join(", ", incompatibleFrameworks.Select(f => f.GetShortFolderName()))}");
18
+ logger.Warn($"The package is not compatible. Incompatible project frameworks: {string.Join(", ", incompatibleFrameworks.Select(f => f.GetShortFolderName()))}");
19
19
  return false;
20
20
  }
21
21
 
22
- logger.Log("The package is compatible.");
22
+ logger.Info("The package is compatible.");
23
23
  return true;
24
24
 
25
25
  static NuGetFramework ParseFramework(string tfm)
@@ -0,0 +1,13 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using NuGetUpdater.Core.Analyze;
4
+
5
+ namespace NuGetUpdater.Core.Run.ApiModel;
6
+
7
+ public record Advisory
8
+ {
9
+ public required string DependencyName { get; init; }
10
+ public ImmutableArray<Requirement>? AffectedVersions { get; init; } = null;
11
+ public ImmutableArray<Requirement>? PatchedVersions { get; init; } = null;
12
+ public ImmutableArray<Requirement>? UnaffectedVersions { get; init; } = null;
13
+ }
@@ -2,5 +2,22 @@ namespace NuGetUpdater.Core.Run.ApiModel;
2
2
 
3
3
  public sealed record AllowedUpdate
4
4
  {
5
- public string UpdateType { get; init; } = "all";
5
+ public DependencyType DependencyType { get; init; } = DependencyType.All;
6
+ public string? DependencyName { get; init; } = null;
7
+ public UpdateType UpdateType { get; init; } = UpdateType.All;
8
+ }
9
+
10
+ public enum DependencyType
11
+ {
12
+ All,
13
+ Direct,
14
+ Indirect,
15
+ Development,
16
+ Production,
17
+ }
18
+
19
+ public enum UpdateType
20
+ {
21
+ All,
22
+ Security,
6
23
  }
@@ -0,0 +1,8 @@
1
+ namespace NuGetUpdater.Core.Run.ApiModel;
2
+
3
+ public record CommitOptions
4
+ {
5
+ public string? Prefix { get; init; } = null;
6
+ public string? PrefixDevelopment { get; init; } = null;
7
+ public string? IncludeScope { get; init; } = null;
8
+ }
@@ -0,0 +1,19 @@
1
+ using System.Text.Json.Serialization;
2
+
3
+ using NuGetUpdater.Core.Analyze;
4
+
5
+ namespace NuGetUpdater.Core.Run.ApiModel;
6
+
7
+ public sealed record Condition
8
+ {
9
+ [JsonPropertyName("dependency-name")]
10
+ public required string DependencyName { get; init; }
11
+ [JsonPropertyName("source")]
12
+ public string? Source { get; init; } = null;
13
+ [JsonPropertyName("update-types")]
14
+ public string[] UpdateTypes { get; init; } = [];
15
+ [JsonPropertyName("updated-at")]
16
+ public DateTime? UpdatedAt { get; init; } = null;
17
+ [JsonPropertyName("version-requirement")]
18
+ public Requirement? VersionRequirement { get; init; } = null;
19
+ }
@@ -0,0 +1,8 @@
1
+ namespace NuGetUpdater.Core.Run.ApiModel;
2
+
3
+ public record DependencyGroup
4
+ {
5
+ public required string Name { get; init; }
6
+ public string? AppliesTo { get; init; }
7
+ public Dictionary<string, object> Rules { get; init; } = new();
8
+ }
@@ -0,0 +1,9 @@
1
+ using System.Collections.Immutable;
2
+
3
+ namespace NuGetUpdater.Core.Run.ApiModel;
4
+
5
+ public record GroupPullRequest
6
+ {
7
+ public required string DependencyGroupName { get; init; }
8
+ public required ImmutableArray<PullRequest> Dependencies { get; init; }
9
+ }
@@ -1,25 +1,28 @@
1
+ using System.Collections.Immutable;
1
2
  using System.Text.Json;
2
3
  using System.Text.Json.Serialization;
3
4
 
5
+ using NuGet.Credentials;
6
+
4
7
  namespace NuGetUpdater.Core.Run.ApiModel;
5
8
 
6
9
  public sealed record Job
7
10
  {
8
11
  public string PackageManager { get; init; } = "nuget";
9
- public AllowedUpdate[]? AllowedUpdates { get; init; } = null;
12
+ public ImmutableArray<AllowedUpdate> AllowedUpdates { get; init; } = [new AllowedUpdate()];
10
13
 
11
14
  [JsonConverter(typeof(NullAsBoolConverter))]
12
15
  public bool Debug { get; init; } = false;
13
- public object[]? DependencyGroups { get; init; } = null;
14
- public object[]? Dependencies { get; init; } = null;
16
+ public ImmutableArray<DependencyGroup> DependencyGroups { get; init; } = [];
17
+ public ImmutableArray<string>? Dependencies { get; init; } = null;
15
18
  public string? DependencyGroupToRefresh { get; init; } = null;
16
- public object[]? ExistingPullRequests { get; init; } = null;
17
- public object[]? ExistingGroupPullRequests { get; init; } = null;
19
+ public ImmutableArray<ImmutableArray<PullRequest>> ExistingPullRequests { get; init; } = [];
20
+ public ImmutableArray<GroupPullRequest> ExistingGroupPullRequests { get; init; } = [];
18
21
  public Dictionary<string, object>? Experiments { get; init; } = null;
19
- public object[]? IgnoreConditions { get; init; } = null;
22
+ public Condition[] IgnoreConditions { get; init; } = [];
20
23
  public bool LockfileOnly { get; init; } = false;
21
- public string? RequirementsUpdateStrategy { get; init; } = null;
22
- public object[]? SecurityAdvisories { get; init; } = null;
24
+ public RequirementsUpdateStrategy? RequirementsUpdateStrategy { get; init; } = null;
25
+ public ImmutableArray<Advisory> SecurityAdvisories { get; init; } = [];
23
26
  public bool SecurityUpdatesOnly { get; init; } = false;
24
27
  public required JobSource Source { get; init; }
25
28
  public bool UpdateSubdependencies { get; init; } = false;
@@ -27,8 +30,8 @@ public sealed record Job
27
30
  public bool VendorDependencies { get; init; } = false;
28
31
  public bool RejectExternalCode { get; init; } = false;
29
32
  public bool RepoPrivate { get; init; } = false;
30
- public object? CommitMessageOptions { get; init; } = null;
31
- public object[]? CredentialsMetadata { get; init; } = null;
33
+ public CommitOptions? CommitMessageOptions { get; init; } = null;
34
+ public ImmutableArray<Dictionary<string, string>>? CredentialsMetadata { get; init; } = null;
32
35
  public int MaxUpdaterRunTime { get; init; } = 0;
33
36
 
34
37
  public IEnumerable<string> GetAllDirectories()
@@ -0,0 +1,11 @@
1
+ using NuGet.Versioning;
2
+
3
+ namespace NuGetUpdater.Core.Run.ApiModel;
4
+
5
+ public record PullRequest
6
+ {
7
+ public required string DependencyName { get; init; }
8
+ public required NuGetVersion DependencyVersion { get; init; }
9
+ public bool DependencyRemoved { get; init; } = false;
10
+ public string? Directory { get; init; } = null;
11
+ }