dependabot-nuget 0.287.0 → 0.289.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/.gitignore +1 -0
  3. data/helpers/lib/NuGetUpdater/Directory.Build.targets +17 -0
  4. data/helpers/lib/NuGetUpdater/Directory.Packages.props +26 -17
  5. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +7 -3
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +3 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +88 -47
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +31 -16
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +1 -1
  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/DependencyDiscovery.props +7 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +10 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +64 -53
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +17 -5
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +3 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +3 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +429 -12
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +12 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +7 -2
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +23 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +43 -58
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/TargetFrameworkReporter.targets +13 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +13 -43
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -10
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +40 -33
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +12 -11
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/CollectionExtensions.cs +17 -0
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +74 -20
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathComparer.cs +31 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +46 -10
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +135 -3
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +71 -38
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +66 -4
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +11 -5
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +808 -222
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +477 -97
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -9
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +494 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +46 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +0 -1
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +401 -77
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +35 -2
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +3 -2
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +8 -4
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +40 -0
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -1
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +8 -5
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +49 -3
  71. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +3 -1
  72. data/lib/dependabot/nuget/file_fetcher.rb +12 -393
  73. data/lib/dependabot/nuget/file_parser.rb +23 -54
  74. data/lib/dependabot/nuget/file_updater.rb +21 -16
  75. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +2 -9
  76. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +183 -80
  77. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +25 -3
  78. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +1 -11
  79. data/lib/dependabot/nuget/native_helpers.rb +13 -4
  80. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +17 -4
  81. metadata +15 -12
  82. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  83. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +0 -17
  84. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs +0 -69
  85. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscoveryResult.cs +0 -11
  86. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  87. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
  88. data/lib/dependabot/nuget/native_discovery/native_directory_packages_props_discovery.rb +0 -44
@@ -59,6 +59,34 @@ public class SerializationTests
59
59
  Assert.Equal("specific-sdk", jobWrapper.Job.Source.Directory);
60
60
  }
61
61
 
62
+ [Fact]
63
+ public void DeserializeJob_DebugIsNull()
64
+ {
65
+ // the `debug` field is defined as a `bool`, but can appear as `null` in the wild
66
+ var jobContent = """
67
+ {
68
+ "job": {
69
+ "package-manager": "nuget",
70
+ "allowed-updates": [
71
+ {
72
+ "update-type": "all"
73
+ }
74
+ ],
75
+ "source": {
76
+ "provider": "github",
77
+ "repo": "some-org/some-repo",
78
+ "directory": "specific-sdk",
79
+ "hostname": null,
80
+ "api-endpoint": null
81
+ },
82
+ "debug": null
83
+ }
84
+ }
85
+ """;
86
+ var jobWrapper = RunWorker.Deserialize(jobContent);
87
+ Assert.False(jobWrapper.Job.Debug);
88
+ }
89
+
62
90
  [Fact]
63
91
  public void DeserializeJob_FieldsNotYetSupported()
64
92
  {
@@ -125,6 +153,7 @@ public class SerializationTests
125
153
  },
126
154
  "experiments": {
127
155
  "nuget_legacy_dependency_solver": true,
156
+ "nuget_use_direct_discovery": true,
128
157
  "unexpected_bool": true,
129
158
  "unexpected_number": 42,
130
159
  "unexpected_null": null,
@@ -140,6 +169,7 @@ public class SerializationTests
140
169
  """);
141
170
  var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
142
171
  Assert.True(experimentsManager.UseLegacyDependencySolver);
172
+ Assert.True(experimentsManager.UseDirectDiscovery);
143
173
  }
144
174
 
145
175
  [Fact]
@@ -166,6 +196,7 @@ public class SerializationTests
166
196
  """);
167
197
  var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
168
198
  Assert.False(experimentsManager.UseLegacyDependencySolver);
199
+ Assert.False(experimentsManager.UseDirectDiscovery);
169
200
  }
170
201
 
171
202
  [Fact]
@@ -190,6 +221,7 @@ public class SerializationTests
190
221
  """);
191
222
  var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
192
223
  Assert.False(experimentsManager.UseLegacyDependencySolver);
224
+ Assert.False(experimentsManager.UseDirectDiscovery);
193
225
  }
194
226
 
195
227
  [Fact]
@@ -212,7 +244,8 @@ public class SerializationTests
212
244
 
213
245
  // assert
214
246
  Assert.False(experimentsManager.UseLegacyDependencySolver);
215
- Assert.Single(capturingTestLogger.Messages.Where(m => m.Contains("Error deserializing job file")));
247
+ Assert.False(experimentsManager.UseDirectDiscovery);
248
+ Assert.Single(capturingTestLogger.Messages, m => m.Contains("Error deserializing job file"));
216
249
  }
217
250
 
218
251
  [Fact]
@@ -230,7 +263,7 @@ public class SerializationTests
230
263
 
231
264
  public IReadOnlyList<string> Messages => _messages;
232
265
 
233
- public void Log(string message)
266
+ public void LogRaw(string message)
234
267
  {
235
268
  _messages.Add(message);
236
269
  }
@@ -40,6 +40,8 @@ public class UpdatedDependencyListTests
40
40
  Properties = [],
41
41
  TargetFrameworks = ["net8.0"],
42
42
  ReferencedProjectPaths = [],
43
+ ImportedFiles = [],
44
+ AdditionalFiles = ["packages.config"],
43
45
  },
44
46
  new()
45
47
  {
@@ -50,6 +52,8 @@ public class UpdatedDependencyListTests
50
52
  Properties = [],
51
53
  TargetFrameworks = ["net8.0"],
52
54
  ReferencedProjectPaths = [],
55
+ ImportedFiles = [],
56
+ AdditionalFiles = ["packages.config"],
53
57
  },
54
58
  new()
55
59
  {
@@ -62,6 +66,8 @@ public class UpdatedDependencyListTests
62
66
  Properties = [],
63
67
  TargetFrameworks = ["net8.0"],
64
68
  ReferencedProjectPaths = [],
69
+ ImportedFiles = [],
70
+ AdditionalFiles = ["packages.config"],
65
71
  }
66
72
  ]
67
73
  };
@@ -99,13 +105,65 @@ public class UpdatedDependencyListTests
99
105
  new ReportedRequirement()
100
106
  {
101
107
  Requirement = "13.0.1",
102
- File = "/src/c/packages.config",
108
+ File = "/src/c/project.csproj",
103
109
  Groups = ["dependencies"],
104
110
  },
105
111
  ]
106
112
  },
107
113
  ],
108
- DependencyFiles = ["/src/a/project.csproj", "/src/b/project.csproj", "/src/c/project.csproj", "/src/a/packages.config", "/src/b/packages.config", "/src/c/packages.config"],
114
+ DependencyFiles = ["/src/a/packages.config", "/src/a/project.csproj", "/src/b/packages.config", "/src/b/project.csproj", "/src/c/packages.config", "/src/c/project.csproj"],
115
+ };
116
+
117
+ // doing JSON comparison makes this easier; we don't have to define custom record equality and we get an easy diff
118
+ var actualJson = JsonSerializer.Serialize(updatedDependencyList);
119
+ var expectedJson = JsonSerializer.Serialize(expectedDependencyList);
120
+ Assert.Equal(expectedJson, actualJson);
121
+ }
122
+
123
+ [Fact]
124
+ public async Task UpdatedDependencyListDeduplicatesFiles()
125
+ {
126
+ // arrange
127
+ using var tempDir = new TemporaryDirectory();
128
+ var testFiles = new[]
129
+ {
130
+ "Directory.Packages.props",
131
+ "project1/project1.csproj",
132
+ "project2/project2.csproj",
133
+ };
134
+ foreach (var testFile in testFiles)
135
+ {
136
+ var fullFilePath = Path.Join(tempDir.DirectoryPath, testFile);
137
+ Directory.CreateDirectory(Path.GetDirectoryName(fullFilePath)!);
138
+ await File.WriteAllTextAsync(fullFilePath, "");
139
+ }
140
+ var discovery = new WorkspaceDiscoveryResult()
141
+ {
142
+ Path = "",
143
+ Projects = [
144
+ new()
145
+ {
146
+ FilePath = "project1/project1.csproj",
147
+ Dependencies = [],
148
+ ImportedFiles = ["../Directory.Packages.props"],
149
+ AdditionalFiles = [],
150
+ },
151
+ new()
152
+ {
153
+ FilePath = "project2/project2.csproj",
154
+ Dependencies = [],
155
+ ImportedFiles = ["../Directory.Packages.props"],
156
+ AdditionalFiles = [],
157
+ }
158
+ ]
159
+ };
160
+
161
+ // act
162
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discovery, pathToContents: tempDir.DirectoryPath);
163
+ var expectedDependencyList = new UpdatedDependencyList()
164
+ {
165
+ Dependencies = [],
166
+ DependencyFiles = ["/Directory.Packages.props", "/project1/project1.csproj", "/project2/project2.csproj"],
109
167
  };
110
168
 
111
169
  // doing JSON comparison makes this easier; we don't have to define custom record equality and we get an easy diff
@@ -50,14 +50,15 @@ public sealed class TemporaryDirectory : IDisposable
50
50
  var parentDirectory = Path.GetDirectoryName(temporaryDirectory.DirectoryPath)!;
51
51
 
52
52
  // prevent directory crawling
53
- await File.WriteAllTextAsync(Path.Combine(parentDirectory, "Directory.Build.props"), """
53
+ await File.WriteAllTextAsync(Path.Combine(parentDirectory, "Directory.Build.props"), "<Project />");
54
+ await File.WriteAllTextAsync(Path.Combine(parentDirectory, "Directory.Build.targets"), "<Project />");
55
+ await File.WriteAllTextAsync(Path.Combine(parentDirectory, "Directory.Packages.props"), """
54
56
  <Project>
55
57
  <PropertyGroup>
56
58
  <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
57
59
  </PropertyGroup>
58
60
  </Project>
59
61
  """);
60
- await File.WriteAllTextAsync(Path.Combine(parentDirectory, "Directory.Build.targets"), "<Project />");
61
62
 
62
63
  foreach (var (path, contents) in fileContents)
63
64
  {
@@ -4,7 +4,7 @@ namespace NuGetUpdater.Core.Test;
4
4
 
5
5
  public class TestLogger : ILogger
6
6
  {
7
- public void Log(string message)
7
+ public void LogRaw(string message)
8
8
  {
9
9
  Debug.WriteLine(message);
10
10
  }
@@ -2,7 +2,7 @@ using Xunit;
2
2
 
3
3
  namespace NuGetUpdater.Core.Test.Update;
4
4
 
5
- public class BindingRedirectsTests
5
+ public class BindingRedirectsTests : TestBase
6
6
  {
7
7
  [Fact]
8
8
  public async Task SimpleBindingRedirectIsPerformed()
@@ -77,7 +77,8 @@ public abstract class UpdateWorkerTestBase : TestBase
77
77
  TestFile[]? additionalFiles = null,
78
78
  MockNuGetPackage[]? packages = null,
79
79
  ExperimentsManager? experimentsManager = null,
80
- string projectFilePath = "test-project.csproj")
80
+ string projectFilePath = "test-project.csproj",
81
+ ExpectedUpdateOperationResult? expectedResult = null)
81
82
  => TestUpdateForProject(
82
83
  dependencyName,
83
84
  oldVersion,
@@ -88,7 +89,8 @@ public abstract class UpdateWorkerTestBase : TestBase
88
89
  additionalFiles,
89
90
  additionalFilesExpected: additionalFiles,
90
91
  packages: packages,
91
- experimentsManager: experimentsManager);
92
+ experimentsManager: experimentsManager,
93
+ expectedResult: expectedResult);
92
94
 
93
95
  protected static Task TestUpdateForProject(
94
96
  string dependencyName,
@@ -263,8 +265,9 @@ public abstract class UpdateWorkerTestBase : TestBase
263
265
  AssertContainsFiles(expectedResult, actualResult);
264
266
  }
265
267
 
266
- public static async Task MockJobFileInDirectory(string temporaryDirectory)
268
+ public static async Task MockJobFileInDirectory(string temporaryDirectory, ExperimentsManager? experimentsManager = null)
267
269
  {
270
+ experimentsManager ??= new ExperimentsManager();
268
271
  var jobFile = new JobFile()
269
272
  {
270
273
  Job = new()
@@ -278,7 +281,8 @@ public abstract class UpdateWorkerTestBase : TestBase
278
281
  Provider = "github",
279
282
  Repo = "test/repo",
280
283
  Directory = "/",
281
- }
284
+ },
285
+ Experiments = experimentsManager.ToDictionary(),
282
286
  }
283
287
  };
284
288
  await File.WriteAllTextAsync(Path.Join(temporaryDirectory, "job.json"), JsonSerializer.Serialize(jobFile, RunWorker.SerializerOptions));
@@ -3109,6 +3109,46 @@ public partial class UpdateWorkerTests
3109
3109
  );
3110
3110
  }
3111
3111
 
3112
+ [Fact]
3113
+ public async Task NoChange_IfPeerDependenciesCannotBeEvaluated()
3114
+ {
3115
+ // make sure we don't throw if we find conflicting peer dependencies; this can happen in multi-tfm projects if the dependencies are too complicated to resolve
3116
+ // eventually this should be able to be resolved, but currently we can't branch on the different packages for different TFMs
3117
+ await TestNoChangeforProject("Some.Package", "1.0.0", "1.1.0",
3118
+ packages:
3119
+ [
3120
+ // initial packages
3121
+ new MockNuGetPackage("Some.Package", "1.0.0",
3122
+ DependencyGroups: [
3123
+ ("net8.0", [("Transitive.Dependency", "8.0.0")]),
3124
+ ("net9.0", [("Transitive.Dependency", "9.0.0")])
3125
+ ]),
3126
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "8.0.0", "net8.0"),
3127
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "9.0.0", "net9.0"),
3128
+
3129
+ // what we're trying to update to, but will fail
3130
+ new MockNuGetPackage("Some.Package", "1.1.0",
3131
+ DependencyGroups: [
3132
+ ("net8.0", [("Transitive.Dependency", "8.1.0")]),
3133
+ ("net9.0", [("Transitive.Dependency", "9.1.0")])
3134
+ ]),
3135
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "8.1.0", "net8.0"),
3136
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "9.1.0", "net9.0"),
3137
+ ],
3138
+ projectContents: """
3139
+ <Project Sdk="Microsoft.NET.Sdk">
3140
+ <PropertyGroup>
3141
+ <TargetFrameworks>net8.0;net9.0</TargetFrameworks>
3142
+ </PropertyGroup>
3143
+ <ItemGroup>
3144
+ <PackageReference Include="Some.Package" Version="1.0.0" />
3145
+ </ItemGroup>
3146
+ </Project>
3147
+ """,
3148
+ expectedResult: new() // success
3149
+ );
3150
+ }
3151
+
3112
3152
  [Fact]
3113
3153
  public async Task ProcessingProjectWithWorkloadReferencesDoesNotFail()
3114
3154
  {
@@ -2294,7 +2294,7 @@ public partial class UpdateWorkerTests
2294
2294
  var resultContents = await File.ReadAllTextAsync(resultOutputPath);
2295
2295
  var result = JsonSerializer.Deserialize<UpdateOperationResult>(resultContents, UpdaterWorker.SerializerOptions)!;
2296
2296
  Assert.Equal(ErrorType.MissingFile, result.ErrorType);
2297
- Assert.Equal(Path.Combine(temporaryDirectory.DirectoryPath, "this.file.does.not.exist.targets"), result.ErrorDetails.ToString());
2297
+ Assert.Equal(Path.Combine(temporaryDirectory.DirectoryPath, "this.file.does.not.exist.targets"), result.ErrorDetails!.ToString());
2298
2298
  }
2299
2299
 
2300
2300
  [Fact]
@@ -97,7 +97,7 @@ public static class AssertEx
97
97
  return;
98
98
  }
99
99
 
100
- Assert.True(false, GetAssertMessage(expected, actual, comparer, message));
100
+ Assert.Fail(GetAssertMessage(expected, actual, comparer, message));
101
101
  }
102
102
 
103
103
  private static bool SequenceEqual<T>(
@@ -0,0 +1,12 @@
1
+ using Xunit;
2
+
3
+ public class LinuxOnlyFactAttribute : FactAttribute
4
+ {
5
+ public LinuxOnlyFactAttribute()
6
+ {
7
+ if (!OperatingSystem.IsLinux())
8
+ {
9
+ Skip = "This test runs only on Linux.";
10
+ }
11
+ }
12
+ }
@@ -172,7 +172,8 @@ public class MSBuildHelperTests : TestBase
172
172
  temp.DirectoryPath,
173
173
  temp.DirectoryPath,
174
174
  "netstandard2.0",
175
- [new Dependency("Package.A", "1.0.0", DependencyType.Unknown)]
175
+ [new Dependency("Package.A", "1.0.0", DependencyType.Unknown)],
176
+ new TestLogger()
176
177
  );
177
178
  AssertEx.Equal(expectedDependencies, actualDependencies);
178
179
  }
@@ -300,7 +301,7 @@ public class MSBuildHelperTests : TestBase
300
301
  new Dependency("Package.2A", "1.0.0", DependencyType.Unknown),
301
302
  new Dependency("Package.2R", "18.0.0", DependencyType.Unknown),
302
303
  };
303
- var actualDependencies = await MSBuildHelper.GetAllPackageDependenciesAsync(temp.DirectoryPath, temp.DirectoryPath, "net8.0", packages);
304
+ var actualDependencies = await MSBuildHelper.GetAllPackageDependenciesAsync(temp.DirectoryPath, temp.DirectoryPath, "net8.0", packages, new TestLogger());
304
305
  for (int i = 0; i < actualDependencies.Length; i++)
305
306
  {
306
307
  var ad = actualDependencies[i];
@@ -334,7 +335,7 @@ public class MSBuildHelperTests : TestBase
334
335
  new Dependency("Package.B", "2.0.0", DependencyType.Unknown, TargetFrameworks: ["net8.0"]),
335
336
  new Dependency("Package.C", "3.0.0", DependencyType.Unknown, IsUpdate: true)
336
337
  };
337
- var actualDependencies = await MSBuildHelper.GetAllPackageDependenciesAsync(temp.DirectoryPath, temp.DirectoryPath, "net8.0", packages);
338
+ var actualDependencies = await MSBuildHelper.GetAllPackageDependenciesAsync(temp.DirectoryPath, temp.DirectoryPath, "net8.0", packages, new TestLogger());
338
339
  AssertEx.Equal(expectedDependencies, actualDependencies);
339
340
  }
340
341
 
@@ -371,7 +372,8 @@ public class MSBuildHelperTests : TestBase
371
372
  temp.DirectoryPath,
372
373
  temp.DirectoryPath,
373
374
  "net8.0",
374
- [new Dependency("Some.Package", "4.5.11", DependencyType.Unknown)]
375
+ [new Dependency("Some.Package", "4.5.11", DependencyType.Unknown)],
376
+ new TestLogger()
375
377
  );
376
378
  }
377
379
  finally
@@ -428,7 +430,8 @@ public class MSBuildHelperTests : TestBase
428
430
  temp.DirectoryPath,
429
431
  temp.DirectoryPath,
430
432
  "net8.0",
431
- [new Dependency("Package.A", "1.0.0", DependencyType.Unknown)]
433
+ [new Dependency("Package.A", "1.0.0", DependencyType.Unknown)],
434
+ new TestLogger()
432
435
  );
433
436
 
434
437
  AssertEx.Equal(expectedDependencies, actualDependencies);
@@ -23,14 +23,60 @@ public class PathHelperTests
23
23
  [Fact]
24
24
  public void VerifyResolveCaseInsensitivePath()
25
25
  {
26
- var temp = new TemporaryDirectory();
26
+ using var temp = new TemporaryDirectory();
27
27
  Directory.CreateDirectory(Path.Combine(temp.DirectoryPath, "src", "a"));
28
28
  File.WriteAllText(Path.Combine(temp.DirectoryPath, "src", "a", "packages.config"), "");
29
29
 
30
30
  var repoRootPath = Path.Combine(temp.DirectoryPath, "src");
31
31
 
32
- var resolvedPath = PathHelper.ResolveCaseInsensitivePathInsideRepoRoot(Path.Combine(repoRootPath, "A", "PACKAGES.CONFIG"), repoRootPath);
32
+ var resolvedPath = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(Path.Combine(repoRootPath, "A", "PACKAGES.CONFIG"), repoRootPath);
33
33
 
34
- Assert.Equal(Path.Combine(temp.DirectoryPath, "src", "a", "packages.config"), resolvedPath);
34
+ var expected = Path.Combine(temp.DirectoryPath, "src", "a", "packages.config").NormalizePathToUnix();
35
+ Assert.Equal(expected, resolvedPath!.First());
36
+ }
37
+
38
+ [LinuxOnlyFact]
39
+ public void VerifyMultipleMatchingPathsReturnsAllPaths()
40
+ {
41
+ using var temp = new TemporaryDirectory();
42
+ Directory.CreateDirectory(Path.Combine(temp.DirectoryPath, "src", "a"));
43
+ Directory.CreateDirectory(Path.Combine(temp.DirectoryPath, "src", "A"));
44
+
45
+ File.WriteAllText(Path.Combine(temp.DirectoryPath, "src", "a", "packages.config"), "");
46
+ File.WriteAllText(Path.Combine(temp.DirectoryPath, "src", "A", "packages.config"), "");
47
+
48
+ var repoRootPath = Path.Combine(temp.DirectoryPath, "src");
49
+
50
+ var resolvedPaths = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(Path.Combine(repoRootPath, "A", "PACKAGES.CONFIG"), repoRootPath);
51
+
52
+ var expected = new[]
53
+ {
54
+ Path.Combine(temp.DirectoryPath, "src", "a", "packages.config").NormalizePathToUnix(),
55
+ Path.Combine(temp.DirectoryPath, "src", "A", "packages.config").NormalizePathToUnix(),
56
+ };
57
+
58
+ Assert.Equal(expected, resolvedPaths!);
59
+ }
60
+
61
+ [LinuxOnlyFact]
62
+ public async void FilesWithDifferentlyCasedDirectoriesCanBeResolved()
63
+ {
64
+ // arrange
65
+ using var temp = new TemporaryDirectory();
66
+ var testFile1 = "src/project1/project1.csproj";
67
+ var testFile2 = "SRC/project2/project2.csproj";
68
+ var testFiles = new[] { testFile1, testFile2 };
69
+ foreach (var testFile in testFiles)
70
+ {
71
+ var fullPath = Path.Join(temp.DirectoryPath, testFile); Directory.CreateDirectory(Path.GetDirectoryName(fullPath)!);
72
+ await File.WriteAllTextAsync(fullPath, "");
73
+ }
74
+
75
+ // act
76
+ var actualFile1 = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(Path.Join(temp.DirectoryPath, testFile1), temp.DirectoryPath);
77
+ var actualFile2 = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(Path.Join(temp.DirectoryPath, testFile2), temp.DirectoryPath);
78
+
79
+ // assert
80
+ Assert.EndsWith(testFile1, actualFile1![0]); Assert.EndsWith(testFile2, actualFile2![0]);
35
81
  }
36
82
  }
@@ -14,7 +14,9 @@ module Dependabot
14
14
 
15
15
  sig { returns(String) }
16
16
  def self.temp_directory
17
- File.join(NativeDiscoveryJsonReader.temp_directory, "analysis")
17
+ d = File.join(Dir.tmpdir, "analysis")
18
+ FileUtils.mkdir_p(d)
19
+ d
18
20
  end
19
21
 
20
22
  sig { params(dependency_name: String).returns(String) }