dependabot-nuget 0.288.0 → 0.289.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) 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.Test/EntryPointTests.Analyze.cs +3 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +23 -3
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +30 -15
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +60 -66
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +11 -3
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +1 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -4
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +54 -11
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +1 -2
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +43 -54
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +13 -43
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +2 -10
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +38 -33
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +12 -11
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +18 -17
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +17 -9
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +87 -5
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -5
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +16 -0
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +6 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +147 -36
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +184 -48
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -5
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +32 -10
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +400 -76
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +2 -2
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -2
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +40 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -1
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +8 -5
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +47 -2
  57. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +3 -1
  58. data/lib/dependabot/nuget/file_fetcher.rb +12 -393
  59. data/lib/dependabot/nuget/file_parser.rb +23 -60
  60. data/lib/dependabot/nuget/file_updater.rb +21 -16
  61. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +2 -9
  62. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +183 -77
  63. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +25 -3
  64. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +1 -8
  65. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +17 -4
  66. metadata +8 -9
  67. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +0 -17
  69. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  70. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
@@ -51,7 +51,7 @@ internal static partial class MSBuildHelper
51
51
  var globalJsonPaths = candidateDirectories.Select(d => Path.Combine(d, "global.json")).Where(File.Exists).Select(p => (p, p + Guid.NewGuid().ToString())).ToArray();
52
52
  foreach (var (globalJsonPath, tempGlobalJsonPath) in globalJsonPaths)
53
53
  {
54
- logger.Log($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}`{(retainMSBuildSdks ? " and retaining MSBuild SDK declarations" : string.Empty)}.");
54
+ logger.Info($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}`{(retainMSBuildSdks ? " and retaining MSBuild SDK declarations" : string.Empty)}.");
55
55
  File.Move(globalJsonPath, tempGlobalJsonPath);
56
56
  if (retainMSBuildSdks)
57
57
  {
@@ -80,7 +80,7 @@ internal static partial class MSBuildHelper
80
80
  {
81
81
  foreach (var (globalJsonpath, tempGlobalJsonPath) in globalJsonPaths)
82
82
  {
83
- logger.Log($"Restoring `global.json` to `{Path.GetDirectoryName(globalJsonpath)}`.");
83
+ logger.Info($"Restoring `global.json` to `{Path.GetDirectoryName(globalJsonpath)}`.");
84
84
  File.Move(tempGlobalJsonPath, globalJsonpath, overwrite: retainMSBuildSdks);
85
85
  }
86
86
  }
@@ -327,7 +327,7 @@ internal static partial class MSBuildHelper
327
327
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
328
328
  try
329
329
  {
330
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
330
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
331
331
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
332
332
 
333
333
  // NU1608: Detected package version outside of dependency constraint
@@ -347,7 +347,7 @@ internal static partial class MSBuildHelper
347
347
 
348
348
  try
349
349
  {
350
- string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
350
+ string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
351
351
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
352
352
 
353
353
  // Add Dependency[] packages to List<PackageToUpdate> existingPackages
@@ -398,10 +398,10 @@ internal static partial class MSBuildHelper
398
398
  if (added == true)
399
399
  {
400
400
  // Add existing versions to existing list
401
- packageManager.UpdateExistingPackagesWithNewVersions(existingDuplicate, packagesToUpdate);
401
+ packageManager.UpdateExistingPackagesWithNewVersions(existingDuplicate, packagesToUpdate, logger);
402
402
 
403
403
  // Make relationships
404
- await packageManager.PopulatePackageDependenciesAsync(existingDuplicate, targetFramework, Path.GetDirectoryName(projectPath));
404
+ await packageManager.PopulatePackageDependenciesAsync(existingDuplicate, targetFramework, Path.GetDirectoryName(projectPath), logger);
405
405
 
406
406
  // Update all to new versions
407
407
  foreach (var package in existingDuplicate)
@@ -414,10 +414,10 @@ internal static partial class MSBuildHelper
414
414
  else
415
415
  {
416
416
  // Add existing versions to existing list
417
- packageManager.UpdateExistingPackagesWithNewVersions(existingPackages, packagesToUpdate);
417
+ packageManager.UpdateExistingPackagesWithNewVersions(existingPackages, packagesToUpdate, logger);
418
418
 
419
419
  // Make relationships
420
- await packageManager.PopulatePackageDependenciesAsync(existingPackages, targetFramework, Path.GetDirectoryName(projectPath));
420
+ await packageManager.PopulatePackageDependenciesAsync(existingPackages, targetFramework, Path.GetDirectoryName(projectPath), logger);
421
421
 
422
422
  // Update all to new versions
423
423
  foreach (var package in existingPackages)
@@ -503,7 +503,7 @@ internal static partial class MSBuildHelper
503
503
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
504
504
  try
505
505
  {
506
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
506
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
507
507
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath], workingDirectory: tempDirectory.FullName);
508
508
  ThrowOnUnauthenticatedFeed(stdOut);
509
509
 
@@ -627,7 +627,7 @@ internal static partial class MSBuildHelper
627
627
  return projectRoot;
628
628
  }
629
629
 
630
- private static IEnumerable<PackageSource>? LoadPackageSources(string nugetConfigPath)
630
+ private static IEnumerable<PackageSource>? LoadPackageSources(string nugetConfigPath, ILogger logger)
631
631
  {
632
632
  try
633
633
  {
@@ -638,8 +638,8 @@ internal static partial class MSBuildHelper
638
638
  }
639
639
  catch (NuGetConfigurationException ex)
640
640
  {
641
- Console.WriteLine("Error while parsing NuGet.config");
642
- Console.WriteLine(ex.Message);
641
+ logger.Warn("Error while parsing NuGet.config");
642
+ logger.Warn(ex.Message);
643
643
 
644
644
  // Nuget.config is invalid. Won't be able to do anything with specific sources.
645
645
  return null;
@@ -652,6 +652,7 @@ internal static partial class MSBuildHelper
652
652
  string projectPath,
653
653
  string targetFramework,
654
654
  IReadOnlyCollection<Dependency> packages,
655
+ ILogger logger,
655
656
  bool usePackageDownload = false)
656
657
  {
657
658
  var projectDirectory = Path.GetDirectoryName(projectPath);
@@ -664,7 +665,7 @@ internal static partial class MSBuildHelper
664
665
  File.Copy(nugetConfigPath, Path.Combine(tempDir.FullName, "NuGet.Config"));
665
666
  var nugetConfigDir = Path.GetDirectoryName(nugetConfigPath);
666
667
 
667
- var packageSources = LoadPackageSources(nugetConfigPath);
668
+ var packageSources = LoadPackageSources(nugetConfigPath, logger);
668
669
  if (packageSources is not null)
669
670
  {
670
671
  // We need to copy local package sources from the NuGet.Config file to the temp directory
@@ -761,7 +762,7 @@ internal static partial class MSBuildHelper
761
762
  ThrowOnUnauthenticatedFeed(stdOut);
762
763
  if (exitCode != 0)
763
764
  {
764
- logger.Log($"Error determining target frameworks.\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
765
+ logger.Warn($"Error determining target frameworks.\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}");
765
766
  }
766
767
 
767
768
  // There are 3 return values, all uses slightly differently. Only one will be set, the others will be blank
@@ -805,13 +806,13 @@ internal static partial class MSBuildHelper
805
806
  string projectPath,
806
807
  string targetFramework,
807
808
  IReadOnlyCollection<Dependency> packages,
808
- ILogger? logger = null)
809
+ ILogger logger)
809
810
  {
810
811
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-resolution_");
811
812
  try
812
813
  {
813
814
  var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
814
- var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
815
+ var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger);
815
816
 
816
817
  var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", ["build", tempProjectPath, "/t:_ReportDependencies"], workingDirectory: tempDirectory.FullName);
817
818
  ThrowOnUnauthenticatedFeed(stdout);
@@ -836,7 +837,7 @@ internal static partial class MSBuildHelper
836
837
  }
837
838
  else
838
839
  {
839
- logger?.Log($"dotnet build in {nameof(GetAllPackageDependenciesAsync)} failed. STDOUT: {stdout} STDERR: {stderr}");
840
+ logger?.Warn($"dotnet build in {nameof(GetAllPackageDependenciesAsync)} failed. STDOUT: {stdout} STDERR: {stderr}");
840
841
  return [];
841
842
  }
842
843
  }
@@ -4,28 +4,12 @@ namespace NuGetUpdater.Core;
4
4
 
5
5
  internal static class NuGetHelper
6
6
  {
7
- internal const string PackagesConfigFileName = "packages.config";
8
-
9
- public static bool TryGetPackagesConfigFile(string projectPath, [NotNullWhen(returnValue: true)] out string? packagesConfigPath)
10
- {
11
- var projectDirectory = Path.GetDirectoryName(projectPath);
12
-
13
- packagesConfigPath = PathHelper.JoinPath(projectDirectory, PackagesConfigFileName);
14
- if (File.Exists(packagesConfigPath))
15
- {
16
- return true;
17
- }
18
-
19
- packagesConfigPath = null;
20
- return false;
21
- }
22
-
23
7
  internal static async Task<bool> DownloadNuGetPackagesAsync(string repoRoot, string projectPath, IReadOnlyCollection<Dependency> packages, ILogger logger)
24
8
  {
25
9
  var tempDirectory = Directory.CreateTempSubdirectory("msbuild_sdk_restore_");
26
10
  try
27
11
  {
28
- var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, usePackageDownload: true);
12
+ var tempProjectPath = await MSBuildHelper.CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, "netstandard2.0", packages, logger, usePackageDownload: true);
29
13
  var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["restore", tempProjectPath]);
30
14
 
31
15
  return exitCode == 0;
@@ -105,7 +105,7 @@ internal static class PathHelper
105
105
  /// </summary>
106
106
  /// <param name="filePath">The file path to resolve.</param>
107
107
  /// <param name="repoRootPath">The root path of the repository.</param>
108
- public static string? ResolveCaseInsensitivePathInsideRepoRoot(string filePath, string repoRootPath)
108
+ public static List<string>? ResolveCaseInsensitivePathsInsideRepoRoot(string filePath, string repoRootPath)
109
109
  {
110
110
  if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(repoRootPath))
111
111
  {
@@ -123,7 +123,7 @@ internal static class PathHelper
123
123
  }
124
124
 
125
125
  // Start resolving from the root path
126
- var currentPath = normalizedRepoRoot;
126
+ var currentPaths = new List<string> { normalizedRepoRoot };
127
127
  var relativePath = normalizedFilePath.Substring(normalizedRepoRoot.Length).TrimStart('/');
128
128
 
129
129
  foreach (var part in relativePath.Split('/'))
@@ -133,20 +133,28 @@ internal static class PathHelper
133
133
  continue;
134
134
  }
135
135
 
136
- // Enumerate the current directory to find a case-insensitive match
137
- var nextPath = Directory
138
- .EnumerateFileSystemEntries(currentPath)
139
- .FirstOrDefault(entry => string.Equals(Path.GetFileName(entry), part, StringComparison.OrdinalIgnoreCase));
136
+ var nextPaths = new List<string>();
140
137
 
141
- if (nextPath == null)
138
+ // Iterate through all current paths to find matches for the current part
139
+ foreach (var currentPath in currentPaths)
140
+ {
141
+ var matches = Directory
142
+ .EnumerateFileSystemEntries(currentPath)
143
+ .Where(entry => string.Equals(Path.GetFileName(entry), part, StringComparison.OrdinalIgnoreCase));
144
+
145
+ nextPaths.AddRange(matches);
146
+ }
147
+
148
+ if (!nextPaths.Any())
142
149
  {
143
150
  return null; // Part of the path does not exist
144
151
  }
145
152
 
146
- currentPath = nextPath;
153
+ currentPaths = nextPaths;
147
154
  }
148
155
 
149
- return currentPath.NormalizePathToUnix(); // Fully resolved path with correct casing
156
+ // Normalize all resulting paths to Unix format
157
+ return currentPaths.Select(path => path.NormalizePathToUnix()).ToList();
150
158
  }
151
159
 
152
160
  /// <summary>
@@ -0,0 +1,96 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using Microsoft.Build.Construction;
4
+
5
+ namespace NuGetUpdater.Core.Utilities;
6
+
7
+ internal static class ProjectHelper
8
+ {
9
+ public const string PackagesConfigFileName = "packages.config";
10
+ public const string AppConfigFileName = "app.config";
11
+ public const string WebConfigFileName = "web.config";
12
+ public const string PackagesLockJsonFileName = "packages.lock.json";
13
+
14
+ public enum PathFormat
15
+ {
16
+ Relative,
17
+ Full,
18
+ }
19
+
20
+ public static ImmutableArray<string> GetAllAdditionalFilesFromProject(string fullProjectPath, PathFormat pathFormat)
21
+ {
22
+ return GetAdditionalFilesFromProjectContent(fullProjectPath, pathFormat)
23
+ .AddRange(GetAdditionalFilesFromProjectLocation(fullProjectPath, pathFormat));
24
+ }
25
+
26
+ public static ImmutableArray<string> GetAdditionalFilesFromProjectContent(string fullProjectPath, PathFormat pathFormat)
27
+ {
28
+ var projectRootElement = ProjectRootElement.Open(fullProjectPath);
29
+ var additionalFilesWithFullPaths = new[]
30
+ {
31
+ projectRootElement.GetItemPathWithFileName(PackagesConfigFileName),
32
+ projectRootElement.GetItemPathWithFileName(AppConfigFileName),
33
+ projectRootElement.GetItemPathWithFileName(WebConfigFileName),
34
+ }.Where(p => p is not null).Cast<string>().ToImmutableArray();
35
+
36
+ var additionalFiles = additionalFilesWithFullPaths
37
+ .Select(p => MakePathAppropriateFormat(fullProjectPath, p, pathFormat))
38
+ .ToImmutableArray();
39
+ return additionalFiles;
40
+ }
41
+
42
+ public static ImmutableArray<string> GetAdditionalFilesFromProjectLocation(string fullProjectPath, PathFormat pathFormat)
43
+ {
44
+ var additionalFilesWithFullPaths = new[]
45
+ {
46
+ GetPathWithRegardsToProjectFile(fullProjectPath, PackagesLockJsonFileName),
47
+ }.Where(p => p is not null).Cast<string>().ToImmutableArray();
48
+
49
+ var additionalFiles = additionalFilesWithFullPaths
50
+ .Select(p => MakePathAppropriateFormat(fullProjectPath, p, pathFormat))
51
+ .ToImmutableArray();
52
+ return additionalFiles;
53
+ }
54
+
55
+ public static string? GetPackagesConfigPathFromProject(string fullProjectPath, PathFormat pathFormat)
56
+ {
57
+ var additionalFiles = GetAdditionalFilesFromProjectContent(fullProjectPath, pathFormat);
58
+ var packagesConfigFile = additionalFiles.FirstOrDefault(p => Path.GetFileName(p).Equals(PackagesConfigFileName, StringComparison.Ordinal));
59
+ return packagesConfigFile;
60
+ }
61
+
62
+ private static string MakePathAppropriateFormat(string fullProjectPath, string fullFilePath, PathFormat pathFormat)
63
+ {
64
+ var projectDirectory = Path.GetDirectoryName(fullProjectPath)!;
65
+ var updatedPath = pathFormat switch
66
+ {
67
+ PathFormat.Full => fullFilePath,
68
+ PathFormat.Relative => Path.GetRelativePath(projectDirectory, fullFilePath),
69
+ _ => throw new NotSupportedException(),
70
+ };
71
+ return updatedPath.NormalizePathToUnix();
72
+ }
73
+
74
+ private static string? GetItemPathWithFileName(this ProjectRootElement projectRootElement, string itemFileName)
75
+ {
76
+ var projectDirectory = Path.GetDirectoryName(projectRootElement.FullPath)!;
77
+ var packagesConfigPath = projectRootElement.Items
78
+ .Where(i => i.ElementName.Equals("None", StringComparison.OrdinalIgnoreCase) ||
79
+ i.ElementName.Equals("Content", StringComparison.OrdinalIgnoreCase))
80
+ .Where(i => Path.GetFileName(i.Include).Equals(itemFileName, StringComparison.OrdinalIgnoreCase))
81
+ .Select(i => Path.GetFullPath(Path.Combine(projectDirectory, i.Include)))
82
+ .Where(File.Exists)
83
+ .FirstOrDefault()
84
+ ?.NormalizePathToUnix();
85
+ return packagesConfigPath;
86
+ }
87
+
88
+ private static string? GetPathWithRegardsToProjectFile(string fullProjectPath, string fileName)
89
+ {
90
+ var projectDirectory = Path.GetDirectoryName(fullProjectPath)!;
91
+ var filePath = Directory.EnumerateFiles(projectDirectory)
92
+ .Where(p => Path.GetFileName(p).Equals(fileName, StringComparison.Ordinal))
93
+ .FirstOrDefault();
94
+ return filePath;
95
+ }
96
+ }
@@ -32,6 +32,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
32
32
  Dependencies = [
33
33
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
34
34
  ],
35
+ ReferencedProjectPaths = [],
36
+ ImportedFiles = [],
37
+ AdditionalFiles = [],
35
38
  },
36
39
  ],
37
40
  },
@@ -80,6 +83,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
80
83
  new("Some.Package", "4.0.1", DependencyType.PackageReference),
81
84
  new("Some.Transitive.Dependency", "4.0.1", DependencyType.PackageReference),
82
85
  ],
86
+ ReferencedProjectPaths = [],
87
+ ImportedFiles = [],
88
+ AdditionalFiles = [],
83
89
  },
84
90
  ],
85
91
  },
@@ -129,6 +135,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
129
135
  Dependencies = [
130
136
  new("Some.Transitive.Dependency", "4.0.1", DependencyType.PackageReference, EvaluationResult: evaluationResult, TargetFrameworks: ["net8.0"]),
131
137
  ],
138
+ ReferencedProjectPaths = [],
139
+ ImportedFiles = [],
140
+ AdditionalFiles = [],
132
141
  },
133
142
  new()
134
143
  {
@@ -137,6 +146,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
137
146
  Dependencies = [
138
147
  new("Some.Package", "4.0.1", DependencyType.PackageReference, EvaluationResult: evaluationResult, TargetFrameworks: ["net8.0"]),
139
148
  ],
149
+ ReferencedProjectPaths = [],
150
+ ImportedFiles = [],
151
+ AdditionalFiles = [],
140
152
  },
141
153
  ],
142
154
  },
@@ -187,6 +199,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
187
199
  Dependencies = [
188
200
  new("Package.A", "4.5.0", DependencyType.PackageReference, EvaluationResult: evaluationResult, TargetFrameworks: ["net8.0"]),
189
201
  ],
202
+ ReferencedProjectPaths = [],
203
+ ImportedFiles = [],
204
+ AdditionalFiles = [],
190
205
  },
191
206
  new()
192
207
  {
@@ -195,6 +210,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
195
210
  Dependencies = [
196
211
  new("Package.B", "4.5.0", DependencyType.PackageReference, EvaluationResult: evaluationResult, TargetFrameworks: ["net8.0"]),
197
212
  ],
213
+ ReferencedProjectPaths = [],
214
+ ImportedFiles = [],
215
+ AdditionalFiles = [],
198
216
  },
199
217
  ],
200
218
  },
@@ -241,6 +259,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
241
259
  Dependencies = [
242
260
  new("Some.Transitive.Dependency", "$(MissingPackageVersion)", DependencyType.PackageReference, EvaluationResult: new EvaluationResult(EvaluationResultType.PropertyNotFound, "$(MissingPackageVersion)", "$(MissingPackageVersion)", "$(MissingPackageVersion)", ErrorMessage: null)),
243
261
  ],
262
+ ReferencedProjectPaths = [],
263
+ ImportedFiles = [],
264
+ AdditionalFiles = [],
244
265
  },
245
266
  ],
246
267
  },
@@ -281,6 +302,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
281
302
  Dependencies = [
282
303
  new("Some.Package", "1.0.0", DependencyType.PackageReference), // this was found in the source, but doesn't exist in any feed
283
304
  ],
305
+ ReferencedProjectPaths = [],
306
+ ImportedFiles = [],
307
+ AdditionalFiles = [],
284
308
  },
285
309
  ],
286
310
  },
@@ -326,6 +350,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
326
350
  Dependencies = [
327
351
  new("Some.Transitive.Dependency", "4.0.1", DependencyType.PackageReference),
328
352
  ],
353
+ ReferencedProjectPaths = [],
354
+ ImportedFiles = [],
355
+ AdditionalFiles = [],
329
356
  },
330
357
  ],
331
358
  },
@@ -366,7 +393,10 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
366
393
  TargetFrameworks = ["net8.0"],
367
394
  Dependencies = [
368
395
  new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
369
- ]
396
+ ],
397
+ ReferencedProjectPaths = [],
398
+ ImportedFiles = [],
399
+ AdditionalFiles = [],
370
400
  },
371
401
  new()
372
402
  {
@@ -374,7 +404,10 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
374
404
  TargetFrameworks = ["NET8.0"],
375
405
  Dependencies = [
376
406
  new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
377
- ]
407
+ ],
408
+ ReferencedProjectPaths = [],
409
+ ImportedFiles = [],
410
+ AdditionalFiles = [],
378
411
  }
379
412
  ]
380
413
  },
@@ -418,6 +451,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
418
451
  Dependencies = [
419
452
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
420
453
  ],
454
+ ReferencedProjectPaths = [],
455
+ ImportedFiles = [],
456
+ AdditionalFiles = [],
421
457
  },
422
458
  ],
423
459
  },
@@ -585,7 +621,10 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
585
621
  Dependencies =
586
622
  [
587
623
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
588
- ]
624
+ ],
625
+ ReferencedProjectPaths = [],
626
+ ImportedFiles = [],
627
+ AdditionalFiles = [],
589
628
  }
590
629
  ]
591
630
  },
@@ -754,7 +793,10 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
754
793
  Dependencies =
755
794
  [
756
795
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
757
- ]
796
+ ],
797
+ ReferencedProjectPaths = [],
798
+ ImportedFiles = [],
799
+ AdditionalFiles = [],
758
800
  }
759
801
  ]
760
802
  },
@@ -939,7 +981,10 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
939
981
  Dependencies =
940
982
  [
941
983
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
942
- ]
984
+ ],
985
+ ReferencedProjectPaths = [],
986
+ ImportedFiles = [],
987
+ AdditionalFiles = [],
943
988
  }
944
989
  ]
945
990
  },
@@ -1049,6 +1094,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
1049
1094
  Dependencies = [
1050
1095
  new("Some.Package", "1.2.3", DependencyType.PackageReference),
1051
1096
  ],
1097
+ ReferencedProjectPaths = [],
1098
+ ImportedFiles = [],
1099
+ AdditionalFiles = [],
1052
1100
  }
1053
1101
  ]
1054
1102
  },
@@ -1167,6 +1215,9 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
1167
1215
  Dependencies = [
1168
1216
  new("Some.Package", "1.0.0", DependencyType.PackageReference),
1169
1217
  ],
1218
+ ReferencedProjectPaths = [],
1219
+ ImportedFiles = [],
1220
+ AdditionalFiles = [],
1170
1221
  }
1171
1222
  ]
1172
1223
  },
@@ -1187,4 +1238,35 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
1187
1238
  }
1188
1239
  );
1189
1240
  }
1241
+
1242
+ [Fact]
1243
+ public void DeserializeDependencyInfo_UnsupportedIgnoredVersionsAreIgnored()
1244
+ {
1245
+ // arrange
1246
+ // "1.0.0.pre.rc2" isn't a valid NuGet version; ignore that requirement
1247
+ var json = """
1248
+ {
1249
+ "Name": "Some.Package",
1250
+ "Version": "1.10.0",
1251
+ "IsVulnerable": false,
1252
+ "IgnoredVersions": [
1253
+ "> 1.0.0.pre.rc2, < 2",
1254
+ "< 1.0.1"
1255
+ ],
1256
+ "Vulnerabilities": []
1257
+ }
1258
+ """;
1259
+
1260
+ // act
1261
+ var dependencyInfo = AnalyzeWorker.DeserializeDependencyInfo(json);
1262
+
1263
+ // assert
1264
+ Assert.NotNull(dependencyInfo);
1265
+ Assert.Equal("Some.Package", dependencyInfo.Name);
1266
+ Assert.Equal("1.10.0", dependencyInfo.Version);
1267
+ Assert.False(dependencyInfo.IsVulnerable);
1268
+ Assert.Single(dependencyInfo.IgnoredVersions);
1269
+ Assert.Equal("< 1.0.1", dependencyInfo.IgnoredVersions.Single().ToString());
1270
+ Assert.Empty(dependencyInfo.Vulnerabilities);
1271
+ }
1190
1272
  }
@@ -43,7 +43,6 @@ public class DiscoveryWorkerTestBase : TestBase
43
43
  ValidateResultWithDependencies(expectedResult.GlobalJson, actualResult.GlobalJson);
44
44
  ValidateResultWithDependencies(expectedResult.DotNetToolsJson, actualResult.DotNetToolsJson);
45
45
  ValidateProjectResults(expectedResult.Projects, actualResult.Projects, experimentsManager);
46
- AssertEx.Equal(expectedResult.ImportedFiles, actualResult.ImportedFiles, PathComparer.Instance);
47
46
  Assert.Equal(expectedResult.ExpectedProjectCount ?? expectedResult.Projects.Length, actualResult.Projects.Length);
48
47
  Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
49
48
  Assert.Equal(expectedResult.ErrorDetails, actualResult.ErrorDetails);
@@ -92,10 +91,8 @@ public class DiscoveryWorkerTestBase : TestBase
92
91
  AssertEx.Equal(expectedProject.Properties, actualProperties, PropertyComparer.Instance);
93
92
  AssertEx.Equal(expectedProject.TargetFrameworks, actualProject.TargetFrameworks);
94
93
  AssertEx.Equal(expectedProject.ReferencedProjectPaths, actualProject.ReferencedProjectPaths);
95
- if (expectedProject.ImportedFiles is not null)
96
- {
97
- AssertEx.Equal(expectedProject.ImportedFiles.Value.Select(PathHelper.NormalizePathToUnix), actualProject.ImportedFiles.Select(PathHelper.NormalizePathToUnix));
98
- }
94
+ AssertEx.Equal(expectedProject.ImportedFiles, actualProject.ImportedFiles);
95
+ AssertEx.Equal(expectedProject.AdditionalFiles, actualProject.AdditionalFiles);
99
96
 
100
97
  // some dependencies are byproducts of the older temporary project discovery process and shouldn't be returned
101
98
  var actualDependencies = actualProject.Dependencies;
@@ -30,6 +30,9 @@ public partial class DiscoveryWorkerTests
30
30
  <PropertyGroup>
31
31
  <TargetFramework>net46</TargetFramework>
32
32
  </PropertyGroup>
33
+ <ItemGroup>
34
+ <None Include="packages.config" />
35
+ </ItemGroup>
33
36
  </Project>
34
37
  """)
35
38
  ],
@@ -48,6 +51,11 @@ public partial class DiscoveryWorkerTests
48
51
  new("Package.A", "1.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net46"]),
49
52
  new("Package.B", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net46"]),
50
53
  ],
54
+ ReferencedProjectPaths = [],
55
+ ImportedFiles = [],
56
+ AdditionalFiles = [
57
+ "packages.config"
58
+ ],
51
59
  }
52
60
  ],
53
61
  }
@@ -78,6 +86,9 @@ public partial class DiscoveryWorkerTests
78
86
  <PropertyGroup>
79
87
  <TargetFramework>net46</TargetFramework>
80
88
  </PropertyGroup>
89
+ <ItemGroup>
90
+ <None Include="packages.config" />
91
+ </ItemGroup>
81
92
  </Project>
82
93
  """)
83
94
  ],
@@ -94,6 +105,11 @@ public partial class DiscoveryWorkerTests
94
105
  new("Package.A", "1.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net46"]),
95
106
  new("Package.B", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net46"]),
96
107
  ],
108
+ ReferencedProjectPaths = [],
109
+ ImportedFiles = [],
110
+ AdditionalFiles = [
111
+ "packages.config"
112
+ ],
97
113
  }
98
114
  ],
99
115
  }
@@ -73,6 +73,9 @@ public partial class DiscoveryWorkerTests
73
73
  new("TargetFramework", "net8.0", "src/project1/project1.csproj")
74
74
  ],
75
75
  TargetFrameworks = ["net8.0"],
76
+ ReferencedProjectPaths = [],
77
+ ImportedFiles = [],
78
+ AdditionalFiles = [],
76
79
  },
77
80
  new()
78
81
  {
@@ -86,6 +89,9 @@ public partial class DiscoveryWorkerTests
86
89
  new("TargetFramework", "net8.0", "src/project2/project2.csproj")
87
90
  ],
88
91
  TargetFrameworks = ["net8.0"],
92
+ ReferencedProjectPaths = [],
93
+ ImportedFiles = [],
94
+ AdditionalFiles = [],
89
95
  }
90
96
  ]
91
97
  }