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
@@ -0,0 +1,15 @@
1
+ using System.Text.Json.Serialization;
2
+
3
+ namespace NuGetUpdater.Core.Run.ApiModel;
4
+
5
+ public enum RequirementsUpdateStrategy
6
+ {
7
+ [JsonStringEnumMemberName("bump_versions")]
8
+ BumpVersions,
9
+ [JsonStringEnumMemberName("bump_versions_if_necessary")]
10
+ BumpVersionsIfNecessary,
11
+ [JsonStringEnumMemberName("lockfile_only")]
12
+ LockfileOnly,
13
+ [JsonStringEnumMemberName("widen_ranges")]
14
+ WidenRanges,
15
+ }
@@ -1,3 +1,4 @@
1
+ using System.Collections.Immutable;
1
2
  using System.Net;
2
3
  using System.Text;
3
4
  using System.Text.Json;
@@ -21,7 +22,7 @@ public class RunWorker
21
22
  {
22
23
  PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower,
23
24
  WriteIndented = true,
24
- Converters = { new JsonStringEnumConverter() },
25
+ Converters = { new JsonStringEnumConverter(), new RequirementConverter(), new VersionConverter() },
25
26
  };
26
27
 
27
28
  public RunWorker(IApiHandler apiHandler, IDiscoveryWorker discoverWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updateWorker, ILogger logger)
@@ -113,8 +114,8 @@ public class RunWorker
113
114
  {
114
115
  var discoveryResult = await _discoveryWorker.RunAsync(repoContentsPath.FullName, repoDirectory);
115
116
 
116
- _logger.Log("Discovery JSON content:");
117
- _logger.Log(JsonSerializer.Serialize(discoveryResult, DiscoveryWorker.SerializerOptions));
117
+ _logger.Info("Discovery JSON content:");
118
+ _logger.Info(JsonSerializer.Serialize(discoveryResult, DiscoveryWorker.SerializerOptions));
118
119
 
119
120
  // report dependencies
120
121
  var discoveredUpdatedDependencies = GetUpdatedDependencyListFromDiscovery(discoveryResult, repoContentsPath.FullName);
@@ -123,9 +124,8 @@ public class RunWorker
123
124
  // TODO: pull out relevant dependencies, then check each for updates and track the changes
124
125
  // TODO: for each top-level dependency, _or_ specific dependency (if security, use transitive)
125
126
  var originalDependencyFileContents = new Dictionary<string, string>();
126
- var allowedUpdates = job.AllowedUpdates ?? [];
127
127
  var actualUpdatedDependencies = new List<ReportedDependency>();
128
- if (allowedUpdates.Any(a => a.UpdateType == "all"))
128
+ if (job.AllowedUpdates.Any(a => a.UpdateType == UpdateType.All))
129
129
  {
130
130
  await _apiHandler.IncrementMetric(new()
131
131
  {
@@ -134,35 +134,28 @@ public class RunWorker
134
134
  });
135
135
 
136
136
  // track original contents for later handling
137
- async Task TrackOriginalContentsAsync(string directory, string fileName, string? replacementFileName = null)
137
+ async Task TrackOriginalContentsAsync(string directory, string fileName)
138
138
  {
139
- var repoFullPath = Path.Join(directory, fileName);
140
- if (replacementFileName is not null)
141
- {
142
- repoFullPath = Path.Join(Path.GetDirectoryName(repoFullPath)!, replacementFileName);
143
- }
144
-
145
- repoFullPath = repoFullPath.FullyNormalizedRootedPath();
139
+ var repoFullPath = Path.Join(directory, fileName).FullyNormalizedRootedPath();
146
140
  var localFullPath = Path.Join(repoContentsPath.FullName, repoFullPath);
147
-
148
- if (!File.Exists(localFullPath))
149
- {
150
- return;
151
- }
152
-
153
141
  var content = await File.ReadAllTextAsync(localFullPath);
154
142
  originalDependencyFileContents[repoFullPath] = content;
155
143
  }
156
144
 
157
145
  foreach (var project in discoveryResult.Projects)
158
146
  {
147
+ var projectDirectory = Path.GetDirectoryName(project.FilePath);
159
148
  await TrackOriginalContentsAsync(discoveryResult.Path, project.FilePath);
160
- await TrackOriginalContentsAsync(discoveryResult.Path, project.FilePath, replacementFileName: "packages.config");
149
+ foreach (var extraFile in project.ImportedFiles.Concat(project.AdditionalFiles))
150
+ {
151
+ var extraFilePath = Path.Join(projectDirectory, extraFile);
152
+ await TrackOriginalContentsAsync(discoveryResult.Path, extraFilePath);
153
+ }
161
154
  // TODO: include global.json, etc.
162
155
  }
163
156
 
164
157
  // do update
165
- _logger.Log($"Running update in directory {repoDirectory}");
158
+ _logger.Info($"Running update in directory {repoDirectory}");
166
159
  foreach (var project in discoveryResult.Projects)
167
160
  {
168
161
  foreach (var dependency in project.Dependencies.Where(d => !d.IsTransitive))
@@ -180,25 +173,20 @@ public class RunWorker
180
173
  continue;
181
174
  }
182
175
 
176
+ var ignoredVersions = GetIgnoredRequirementsForDependency(job, dependency.Name);
183
177
  var dependencyInfo = new DependencyInfo()
184
178
  {
185
179
  Name = dependency.Name,
186
180
  Version = dependency.Version!,
187
181
  IsVulnerable = false,
188
- IgnoredVersions = [],
182
+ IgnoredVersions = ignoredVersions,
189
183
  Vulnerabilities = [],
190
184
  };
191
185
  var analysisResult = await _analyzeWorker.RunAsync(repoContentsPath.FullName, discoveryResult, dependencyInfo);
192
186
  // TODO: log analysisResult
193
187
  if (analysisResult.CanUpdate)
194
188
  {
195
- var dependencyLocation = Path.Join(discoveryResult.Path, project.FilePath);
196
- if (dependency.Type == DependencyType.PackagesConfig)
197
- {
198
- dependencyLocation = Path.Join(Path.GetDirectoryName(dependencyLocation)!, "packages.config");
199
- }
200
-
201
- dependencyLocation = dependencyLocation.FullyNormalizedRootedPath();
189
+ var dependencyLocation = Path.Join(discoveryResult.Path, project.FilePath).FullyNormalizedRootedPath();
202
190
 
203
191
  // TODO: this is inefficient, but not likely causing a bottleneck
204
192
  var previousDependency = discoveredUpdatedDependencies.Dependencies
@@ -241,48 +229,46 @@ public class RunWorker
241
229
  }
242
230
 
243
231
  // create PR - we need to manually check file contents; we can't easily use `git status` in tests
244
- var updatedDependencyFiles = new List<DependencyFile>();
245
- async Task AddUpdatedFileIfDifferentAsync(string directory, string fileName, string? replacementFileName = null)
232
+ var updatedDependencyFiles = new Dictionary<string, DependencyFile>();
233
+ async Task AddUpdatedFileIfDifferentAsync(string directory, string fileName)
246
234
  {
247
- var repoFullPath = Path.Join(directory, fileName);
248
- if (replacementFileName is not null)
249
- {
250
- repoFullPath = Path.Join(Path.GetDirectoryName(repoFullPath)!, replacementFileName);
251
- }
252
-
253
- repoFullPath = repoFullPath.FullyNormalizedRootedPath();
254
- var localFullPath = Path.Join(repoContentsPath.FullName, repoFullPath);
255
-
256
- if (!File.Exists(localFullPath))
257
- {
258
- return;
259
- }
260
-
235
+ var repoFullPath = Path.Join(directory, fileName).FullyNormalizedRootedPath();
236
+ var localFullPath = Path.GetFullPath(Path.Join(repoContentsPath.FullName, repoFullPath));
261
237
  var originalContent = originalDependencyFileContents[repoFullPath];
262
238
  var updatedContent = await File.ReadAllTextAsync(localFullPath);
263
239
  if (updatedContent != originalContent)
264
240
  {
265
- updatedDependencyFiles.Add(new DependencyFile()
241
+ updatedDependencyFiles[localFullPath] = new DependencyFile()
266
242
  {
267
243
  Name = Path.GetFileName(repoFullPath),
268
244
  Directory = Path.GetDirectoryName(repoFullPath)!.NormalizePathToUnix(),
269
245
  Content = updatedContent,
270
- });
246
+ };
271
247
  }
272
248
  }
273
249
 
274
250
  foreach (var project in discoveryResult.Projects)
275
251
  {
276
252
  await AddUpdatedFileIfDifferentAsync(discoveryResult.Path, project.FilePath);
277
- await AddUpdatedFileIfDifferentAsync(discoveryResult.Path, project.FilePath, replacementFileName: "packages.config");
253
+ var projectDirectory = Path.GetDirectoryName(project.FilePath);
254
+ foreach (var extraFile in project.ImportedFiles.Concat(project.AdditionalFiles))
255
+ {
256
+ var extraFilePath = Path.Join(projectDirectory, extraFile);
257
+ await AddUpdatedFileIfDifferentAsync(discoveryResult.Path, extraFilePath);
258
+ }
259
+ // TODO: handle global.json, etc.
278
260
  }
279
261
 
280
262
  if (updatedDependencyFiles.Count > 0)
281
263
  {
264
+ var updatedDependencyFileList = updatedDependencyFiles
265
+ .OrderBy(kvp => kvp.Key)
266
+ .Select(kvp => kvp.Value)
267
+ .ToArray();
282
268
  var createPullRequest = new CreatePullRequest()
283
269
  {
284
270
  Dependencies = actualUpdatedDependencies.ToArray(),
285
- UpdatedDependencyFiles = updatedDependencyFiles.ToArray(),
271
+ UpdatedDependencyFiles = updatedDependencyFileList,
286
272
  BaseCommitSha = baseCommitSha,
287
273
  CommitMessage = "TODO: message",
288
274
  PrTitle = "TODO: title",
@@ -303,7 +289,7 @@ public class RunWorker
303
289
 
304
290
  var result = new RunResult()
305
291
  {
306
- Base64DependencyFiles = originalDependencyFileContents.Select(kvp =>
292
+ Base64DependencyFiles = originalDependencyFileContents.OrderBy(kvp => kvp.Key).Select(kvp =>
307
293
  {
308
294
  var fullPath = kvp.Key.FullyNormalizedRootedPath();
309
295
  return new DependencyFile()
@@ -318,6 +304,25 @@ public class RunWorker
318
304
  return result;
319
305
  }
320
306
 
307
+ internal static ImmutableArray<Requirement> GetIgnoredRequirementsForDependency(Job job, string dependencyName)
308
+ {
309
+ var ignoreConditions = job.IgnoreConditions
310
+ .Where(c => c.DependencyName.Equals(dependencyName, StringComparison.OrdinalIgnoreCase))
311
+ .ToArray();
312
+ if (ignoreConditions.Length == 1 && ignoreConditions[0].VersionRequirement is null)
313
+ {
314
+ // if only one match with no version requirement, ignore all versions
315
+ return [Requirement.Parse("> 0.0.0")];
316
+ }
317
+
318
+ var ignoredVersions = ignoreConditions
319
+ .Select(c => c.VersionRequirement)
320
+ .Where(r => r is not null)
321
+ .Cast<Requirement>()
322
+ .ToImmutableArray();
323
+ return ignoredVersions;
324
+ }
325
+
321
326
  internal static UpdatedDependencyList GetUpdatedDependencyListFromDiscovery(WorkspaceDiscoveryResult discoveryResult, string pathToContents)
322
327
  {
323
328
  string GetFullRepoPath(string path)
@@ -339,14 +344,20 @@ public class RunWorker
339
344
  foreach (var project in discoveryResult.Projects)
340
345
  {
341
346
  var projectDirectory = Path.GetDirectoryName(project.FilePath);
342
- var pathToPackagesConfig = Path.Join(pathToContents, discoveryResult.Path, projectDirectory, "packages.config");
343
-
344
- if (File.Exists(pathToPackagesConfig))
347
+ foreach (var extraFile in project.ImportedFiles.Concat(project.AdditionalFiles))
345
348
  {
346
- auxiliaryFiles.Add(GetFullRepoPath(Path.Join(projectDirectory, "packages.config")));
349
+ var extraFileFullPath = Path.Join(projectDirectory, extraFile);
350
+ var extraFileRepoPath = GetFullRepoPath(extraFileFullPath);
351
+ auxiliaryFiles.Add(extraFileRepoPath);
347
352
  }
348
353
  }
349
354
 
355
+ var dependencyFiles = discoveryResult.Projects
356
+ .Select(p => GetFullRepoPath(p.FilePath))
357
+ .Concat(auxiliaryFiles)
358
+ .Distinct()
359
+ .OrderBy(p => p)
360
+ .ToArray();
350
361
  var updatedDependencyList = new UpdatedDependencyList()
351
362
  {
352
363
  Dependencies = discoveryResult.Projects.SelectMany(p =>
@@ -357,9 +368,7 @@ public class RunWorker
357
368
  Name = d.Name,
358
369
  Requirements = d.IsTransitive ? [] : [new ReportedRequirement()
359
370
  {
360
- File = d.Type == DependencyType.PackagesConfig
361
- ? Path.Join(Path.GetDirectoryName(GetFullRepoPath(p.FilePath))!, "packages.config").FullyNormalizedRootedPath()
362
- : GetFullRepoPath(p.FilePath),
371
+ File = GetFullRepoPath(p.FilePath),
363
372
  Requirement = d.Version!,
364
373
  Groups = ["dependencies"],
365
374
  }],
@@ -367,7 +376,7 @@ public class RunWorker
367
376
  }
368
377
  );
369
378
  }).ToArray(),
370
- DependencyFiles = discoveryResult.Projects.Select(p => GetFullRepoPath(p.FilePath)).Concat(auxiliaryFiles).ToArray(),
379
+ DependencyFiles = dependencyFiles,
371
380
  };
372
381
  return updatedDependencyList;
373
382
  }
@@ -0,0 +1,19 @@
1
+ using System.Text.Json;
2
+ using System.Text.Json.Serialization;
3
+
4
+ using NuGet.Versioning;
5
+
6
+ namespace NuGetUpdater.Core.Analyze;
7
+
8
+ public class VersionConverter : JsonConverter<NuGetVersion>
9
+ {
10
+ public override NuGetVersion? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
11
+ {
12
+ return NuGetVersion.Parse(reader.GetString()!);
13
+ }
14
+
15
+ public override void Write(Utf8JsonWriter writer, NuGetVersion value, JsonSerializerOptions options)
16
+ {
17
+ writer.WriteStringValue(value.ToString());
18
+ }
19
+ }
@@ -8,6 +8,8 @@ using Microsoft.Language.Xml;
8
8
 
9
9
  using NuGet.ProjectManagement;
10
10
 
11
+ using NuGetUpdater.Core.Utilities;
12
+
11
13
  using Runtime_AssemblyBinding = CoreV2::NuGet.Runtime.AssemblyBinding;
12
14
 
13
15
  namespace NuGetUpdater.Core;
@@ -32,7 +34,7 @@ internal static class BindingRedirectManager
32
34
  /// <param name="updatedPackageVersion">The version of the package that was updated</param>
33
35
  public static async ValueTask UpdateBindingRedirectsAsync(ProjectBuildFile projectBuildFile, string updatedPackageName, string updatedPackageVersion)
34
36
  {
35
- var configFile = await TryGetRuntimeConfigurationFile(projectBuildFile);
37
+ var configFile = await TryGetRuntimeConfigurationFile(projectBuildFile.Path);
36
38
  if (configFile is null)
37
39
  {
38
40
  // no runtime config file so no need to add binding redirects
@@ -58,7 +60,8 @@ internal static class BindingRedirectManager
58
60
  // finally we pull out the assembly `HintPath` values for _all_ references relative to the project file in a unix-style value
59
61
  // e.g., ../packages/Some.Other.Package/4.5.6/lib/net45/Some.Other.Package.dll
60
62
  // all of that is passed to `AddBindingRedirects()` so we can ensure binding redirects for the relevant assemblies
61
- var packagesDirectory = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, updatedPackageName, updatedPackageVersion, packagesConfigPath: null)!;
63
+ var packagesConfigPath = ProjectHelper.GetPackagesConfigPathFromProject(projectBuildFile.Path, ProjectHelper.PathFormat.Full);
64
+ var packagesDirectory = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, updatedPackageName, updatedPackageVersion, packagesConfigPath)!;
62
65
  var assemblyPathPrefix = Path.Combine(packagesDirectory, $"{updatedPackageName}.{updatedPackageVersion}").NormalizePathToUnix().EnsureSuffix("/");
63
66
  var assemblyPaths = references.Select(static x => x.HintPath).Select(x => Path.GetRelativePath(Path.GetDirectoryName(projectBuildFile.Path)!, x).NormalizePathToUnix()).ToList();
64
67
  var bindingsAndAssemblyPaths = bindings.Zip(assemblyPaths);
@@ -124,56 +127,24 @@ internal static class BindingRedirectManager
124
127
  }
125
128
  }
126
129
 
127
- private static async ValueTask<ConfigurationFile?> TryGetRuntimeConfigurationFile(ProjectBuildFile projectBuildFile)
130
+ private static async ValueTask<ConfigurationFile?> TryGetRuntimeConfigurationFile(string fullProjectPath)
128
131
  {
129
- var directoryPath = Path.GetDirectoryName(projectBuildFile.Path);
130
- if (directoryPath is null)
131
- {
132
- return null;
133
- }
134
-
135
- var configFile = projectBuildFile.ItemNodes
136
- .Where(IsConfigFile)
137
- .FirstOrDefault();
132
+ var additionalFiles = ProjectHelper.GetAdditionalFilesFromProjectContent(fullProjectPath, ProjectHelper.PathFormat.Full);
133
+ var configFilePath = additionalFiles
134
+ .FirstOrDefault(p =>
135
+ {
136
+ var fileName = Path.GetFileName(p);
137
+ return fileName.Equals(ProjectHelper.AppConfigFileName, StringComparison.OrdinalIgnoreCase)
138
+ || fileName.Equals(ProjectHelper.WebConfigFileName, StringComparison.OrdinalIgnoreCase);
139
+ });
138
140
 
139
- if (configFile is null)
141
+ if (configFilePath is null)
140
142
  {
141
143
  return null;
142
144
  }
143
145
 
144
- var configFilePath = Path.GetFullPath(Path.Combine(directoryPath, GetValue(configFile)));
145
146
  var configFileContents = await File.ReadAllTextAsync(configFilePath);
146
147
  return new ConfigurationFile(configFilePath, configFileContents, false);
147
-
148
- static string GetValue(IXmlElementSyntax element)
149
- {
150
- var content = element.GetAttributeValue("Include");
151
- if (!string.IsNullOrEmpty(content))
152
- {
153
- return content;
154
- }
155
-
156
- content = element.GetContentValue();
157
- if (!string.IsNullOrEmpty(content))
158
- {
159
- return content;
160
- }
161
-
162
- return string.Empty;
163
- }
164
-
165
- static bool IsConfigFile(IXmlElementSyntax element)
166
- {
167
- var content = GetValue(element);
168
- if (content is null)
169
- {
170
- return false;
171
- }
172
-
173
- var path = Path.GetFileName(content);
174
- return (element.Name == "None" && string.Equals(path, "app.config", StringComparison.OrdinalIgnoreCase))
175
- || (element.Name == "Content" && string.Equals(path, "web.config", StringComparison.OrdinalIgnoreCase));
176
- }
177
148
  }
178
149
 
179
150
  private static string AddBindingRedirects(ConfigurationFile configFile, IEnumerable<(Runtime_AssemblyBinding Binding, string AssemblyPath)> bindingRedirectsAndAssemblyPaths, string assemblyPathPrefix)
@@ -12,18 +12,18 @@ internal static class DotNetToolsJsonUpdater
12
12
  {
13
13
  if (!MSBuildHelper.TryGetDotNetToolsJsonPath(repoRootPath, workspacePath, out var dotnetToolsJsonPath))
14
14
  {
15
- logger.Log(" No dotnet-tools.json file found.");
15
+ logger.Info(" No dotnet-tools.json file found.");
16
16
  return;
17
17
  }
18
18
 
19
19
  var dotnetToolsJsonFile = DotNetToolsJsonBuildFile.Open(repoRootPath, dotnetToolsJsonPath, logger);
20
20
 
21
- logger.Log($" Updating [{dotnetToolsJsonFile.RelativePath}] file.");
21
+ logger.Info($" Updating [{dotnetToolsJsonFile.RelativePath}] file.");
22
22
 
23
23
  var containsDependency = dotnetToolsJsonFile.GetDependencies().Any(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase));
24
24
  if (!containsDependency)
25
25
  {
26
- logger.Log($" Dependency [{dependencyName}] not found.");
26
+ logger.Info($" Dependency [{dependencyName}] not found.");
27
27
  return;
28
28
  }
29
29
 
@@ -39,7 +39,7 @@ internal static class DotNetToolsJsonUpdater
39
39
 
40
40
  if (await dotnetToolsJsonFile.SaveAsync())
41
41
  {
42
- logger.Log($" Saved [{dotnetToolsJsonFile.RelativePath}].");
42
+ logger.Info($" Saved [{dotnetToolsJsonFile.RelativePath}].");
43
43
  }
44
44
  }
45
45
  }
@@ -12,25 +12,25 @@ internal static class GlobalJsonUpdater
12
12
  {
13
13
  if (!MSBuildHelper.TryGetGlobalJsonPath(repoRootPath, workspacePath, out var globalJsonPath))
14
14
  {
15
- logger.Log(" No global.json file found.");
15
+ logger.Info(" No global.json file found.");
16
16
  return;
17
17
  }
18
18
 
19
19
  var globalJsonFile = GlobalJsonBuildFile.Open(repoRootPath, globalJsonPath, logger);
20
20
 
21
- logger.Log($" Updating [{globalJsonFile.RelativePath}] file.");
21
+ logger.Info($" Updating [{globalJsonFile.RelativePath}] file.");
22
22
 
23
23
  var containsDependency = globalJsonFile.GetDependencies().Any(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase));
24
24
  if (!containsDependency)
25
25
  {
26
- logger.Log($" Dependency [{dependencyName}] not found.");
26
+ logger.Info($" Dependency [{dependencyName}] not found.");
27
27
  return;
28
28
  }
29
29
 
30
30
  if (globalJsonFile.MSBuildSdks?.TryGetPropertyValue(dependencyName, out var version) != true
31
31
  || version?.GetValue<string>() is not string versionString)
32
32
  {
33
- logger.Log(" Unable to determine dependency version.");
33
+ logger.Info(" Unable to determine dependency version.");
34
34
  return;
35
35
  }
36
36
 
@@ -43,7 +43,7 @@ internal static class GlobalJsonUpdater
43
43
 
44
44
  if (await globalJsonFile.SaveAsync())
45
45
  {
46
- logger.Log($" Saved [{globalJsonFile.RelativePath}].");
46
+ logger.Info($" Saved [{globalJsonFile.RelativePath}].");
47
47
  }
48
48
  }
49
49
  }
@@ -7,21 +7,13 @@ internal static class LockFileUpdater
7
7
  string projectPath,
8
8
  ILogger logger)
9
9
  {
10
- var projectDirectory = Path.GetDirectoryName(projectPath);
11
- var lockPath = Path.Combine(projectDirectory, "packages.lock.json");
12
- logger.Log($" Updating lock file");
13
- if (!File.Exists(lockPath))
14
- {
15
- logger.Log($" File [{Path.GetRelativePath(repoRootPath, lockPath)}] does not exist.");
16
- return;
17
- }
18
-
10
+ var projectDirectory = Path.GetDirectoryName(projectPath)!;
19
11
  await MSBuildHelper.SidelineGlobalJsonAsync(projectDirectory, repoRootPath, async () =>
20
12
  {
21
13
  var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", ["restore", "--force-evaluate", projectPath], workingDirectory: projectDirectory);
22
14
  if (exitCode != 0)
23
15
  {
24
- logger.Log($" Lock file update failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
16
+ logger.Error($" Lock file update failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
25
17
  }
26
18
  return (exitCode, stdout, stderr);
27
19
  }, logger, retainMSBuildSdks: true);