dependabot-nuget 0.288.0 → 0.290.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +19 -17
  3. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +29 -2
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +25 -4
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +33 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +25 -10
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +60 -66
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +11 -3
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +1 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +54 -11
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +1 -2
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +67 -58
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +15 -44
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +2 -10
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +38 -33
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +25 -23
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +18 -17
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +17 -9
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +87 -5
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -5
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +16 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +6 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +143 -36
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +184 -48
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -5
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +32 -10
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +402 -102
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +342 -2
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -14
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  74. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +95 -0
  75. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -7
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +558 -711
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +47 -2
  80. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +4 -2
  81. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  82. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  83. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  84. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  85. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  86. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  87. data/lib/dependabot/nuget/file_fetcher.rb +11 -393
  88. data/lib/dependabot/nuget/file_parser.rb +23 -61
  89. data/lib/dependabot/nuget/file_updater.rb +28 -23
  90. data/lib/dependabot/nuget/native_helpers.rb +14 -5
  91. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  92. data/lib/dependabot/nuget/update_checker.rb +116 -190
  93. metadata +20 -32
  94. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  95. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  96. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  97. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
  98. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  99. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  100. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -129
  101. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -171
  102. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  103. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -82
  104. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  105. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -68
  106. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  107. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -201
  108. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  109. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  110. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  111. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  112. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  113. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  114. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  115. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  116. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  117. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -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
+ }