dependabot-nuget 0.250.0 → 0.252.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Common.props +1 -0
  3. data/helpers/lib/NuGetUpdater/Directory.Packages.props +26 -0
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +35 -0
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/NuGetUpdater.Cli.csproj +1 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +4 -7
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +251 -0
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/NuGetUpdater.Cli.Test.csproj +3 -3
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Dependency.cs +56 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyType.cs +1 -1
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs +69 -0
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscoveryResult.cs +11 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +217 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +30 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscoveryResult.cs +10 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +30 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscoveryResult.cs +10 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/IDiscoveryResult.cs +14 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +29 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +10 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +13 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +127 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +13 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EvaluationResult.cs +8 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EvaluationResultType.cs +9 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/BuildFile.cs +6 -8
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/DotNetToolsJsonBuildFile.cs +4 -7
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +24 -17
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +2 -2
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/PackagesConfigBuildFile.cs +8 -13
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +100 -19
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/XmlBuildFile.cs +2 -2
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +6 -6
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Property.cs +6 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +23 -36
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -10
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +16 -21
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +4 -19
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/HashSetExtensions.cs +14 -0
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ImmutableArrayExtensions.cs +18 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +0 -1
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +121 -67
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +27 -4
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +117 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +91 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +71 -0
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +59 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +380 -0
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +306 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +36 -0
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/DotNetToolsJsonBuildFileTests.cs +1 -2
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +2 -3
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/PackagesConfigBuildFileTests.cs +4 -6
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/ProjectBuildFileTests.cs +6 -5
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +4 -3
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +38 -6
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +12 -40
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +30 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +272 -0
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/DiffUtil.cs +266 -0
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +195 -152
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/SdkPackageUpdaterHelperTests.cs +7 -11
  63. data/lib/dependabot/nuget/discovery/dependency_details.rb +95 -0
  64. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +126 -0
  65. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +43 -0
  66. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +83 -0
  67. data/lib/dependabot/nuget/discovery/evaluation_details.rb +63 -0
  68. data/lib/dependabot/nuget/discovery/project_discovery.rb +71 -0
  69. data/lib/dependabot/nuget/discovery/property_details.rb +43 -0
  70. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +66 -0
  71. data/lib/dependabot/nuget/file_parser.rb +19 -128
  72. data/lib/dependabot/nuget/file_updater.rb +28 -60
  73. data/lib/dependabot/nuget/native_helpers.rb +55 -0
  74. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +3 -8
  75. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +1 -0
  76. data/lib/dependabot/nuget/update_checker/property_updater.rb +1 -0
  77. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +17 -152
  78. data/lib/dependabot/nuget/update_checker/version_finder.rb +1 -6
  79. data/lib/dependabot/nuget/update_checker.rb +4 -1
  80. metadata +43 -11
  81. data/lib/dependabot/nuget/file_parser/dotnet_tools_json_parser.rb +0 -71
  82. data/lib/dependabot/nuget/file_parser/global_json_parser.rb +0 -68
  83. data/lib/dependabot/nuget/file_parser/packages_config_parser.rb +0 -92
  84. data/lib/dependabot/nuget/file_parser/project_file_parser.rb +0 -620
  85. data/lib/dependabot/nuget/file_parser/property_value_finder.rb +0 -225
  86. data/lib/dependabot/nuget/file_updater/property_value_updater.rb +0 -81
@@ -0,0 +1,306 @@
1
+ using Xunit;
2
+
3
+ namespace NuGetUpdater.Core.Test.Discover;
4
+
5
+ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
6
+ {
7
+ [Theory]
8
+ [InlineData("src/project.csproj")]
9
+ [InlineData("src/project.vbproj")]
10
+ [InlineData("src/project.fsproj")]
11
+ public async Task TestProjectFiles(string projectPath)
12
+ {
13
+ await TestDiscoveryAsync(
14
+ workspacePath: "src",
15
+ files: new[]
16
+ {
17
+ (projectPath, """
18
+ <Project Sdk="Microsoft.NET.Sdk">
19
+ <PropertyGroup>
20
+ <TargetFramework>netstandard2.0</TargetFramework>
21
+ <NewtonsoftJsonPackageVersion>9.0.1</NewtonsoftJsonPackageVersion>
22
+ </PropertyGroup>
23
+
24
+ <ItemGroup>
25
+ <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
26
+ </ItemGroup>
27
+ </Project>
28
+ """)
29
+ },
30
+ expectedResult: new()
31
+ {
32
+ FilePath = "src",
33
+ Projects = [
34
+ new()
35
+ {
36
+ FilePath = Path.GetFileName(projectPath),
37
+ TargetFrameworks = ["netstandard2.0"],
38
+ ReferencedProjectPaths = [],
39
+ ExpectedDependencyCount = 19,
40
+ Dependencies = [
41
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
42
+ new("Newtonsoft.Json", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["netstandard2.0"], IsDirect: true)
43
+ ],
44
+ Properties = [
45
+ new("NewtonsoftJsonPackageVersion", "9.0.1", projectPath),
46
+ new("TargetFramework", "netstandard2.0", projectPath),
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ );
52
+ }
53
+
54
+ [Fact]
55
+ public async Task TestPackageConfig()
56
+ {
57
+ var projectPath = "src/project.csproj";
58
+ await TestDiscoveryAsync(
59
+ workspacePath: "",
60
+ files: new[]
61
+ {
62
+ (projectPath, """
63
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
64
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
65
+ <PropertyGroup>
66
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
67
+ </PropertyGroup>
68
+ <ItemGroup>
69
+ <None Include="packages.config" />
70
+ </ItemGroup>
71
+ <ItemGroup>
72
+ <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
73
+ <HintPath>packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
74
+ <Private>True</Private>
75
+ </Reference>
76
+ </ItemGroup>
77
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
78
+ </Project>
79
+ """),
80
+ ("src/packages.config", """
81
+ <packages>
82
+ <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
83
+ </packages>
84
+ """),
85
+ },
86
+ expectedResult: new()
87
+ {
88
+ FilePath = "",
89
+ Projects = [
90
+ new()
91
+ {
92
+ FilePath = projectPath,
93
+ TargetFrameworks = ["net45"],
94
+ ReferencedProjectPaths = [],
95
+ ExpectedDependencyCount = 2, // Should we ignore Microsoft.NET.ReferenceAssemblies?
96
+ Dependencies = [
97
+ new("Newtonsoft.Json", "7.0.1", DependencyType.PackagesConfig, TargetFrameworks: ["net45"])
98
+ ],
99
+ Properties = [
100
+ new("TargetFrameworkVersion", "v4.5", projectPath),
101
+ ]
102
+ }
103
+ ]
104
+ }
105
+ );
106
+ }
107
+
108
+ [Fact]
109
+ public async Task TestProps()
110
+ {
111
+ var projectPath = "src/project.csproj";
112
+ await TestDiscoveryAsync(
113
+ workspacePath: "",
114
+ files: new[]
115
+ {
116
+ (projectPath, """
117
+ <Project Sdk="Microsoft.NET.Sdk">
118
+ <PropertyGroup>
119
+ <TargetFramework>netstandard2.0</TargetFramework>
120
+ </PropertyGroup>
121
+
122
+ <ItemGroup>
123
+ <PackageReference Include="Newtonsoft.Json" />
124
+ </ItemGroup>
125
+ </Project>
126
+ """),
127
+ ("Directory.Packages.props", """
128
+ <Project>
129
+ <PropertyGroup>
130
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
131
+ <NewtonsoftJsonPackageVersion>9.0.1</NewtonsoftJsonPackageVersion>
132
+ </PropertyGroup>
133
+
134
+ <ItemGroup>
135
+ <PackageVersion Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
136
+ </ItemGroup>
137
+ </Project>
138
+ """)
139
+ },
140
+ expectedResult: new()
141
+ {
142
+ FilePath = "",
143
+ Projects = [
144
+ new()
145
+ {
146
+ FilePath = projectPath,
147
+ TargetFrameworks = ["netstandard2.0"],
148
+ ReferencedProjectPaths = [],
149
+ ExpectedDependencyCount = 19,
150
+ Dependencies = [
151
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
152
+ new("Newtonsoft.Json", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["netstandard2.0"], IsDirect: true)
153
+ ],
154
+ Properties = [
155
+ new("ManagePackageVersionsCentrally", "true", "Directory.Packages.props"),
156
+ new("NewtonsoftJsonPackageVersion", "9.0.1", "Directory.Packages.props"),
157
+ new("TargetFramework", "netstandard2.0", projectPath),
158
+ ]
159
+ }
160
+ ],
161
+ DirectoryPackagesProps = new()
162
+ {
163
+ FilePath = "Directory.Packages.props",
164
+ Dependencies = [
165
+ new("Newtonsoft.Json", "9.0.1", DependencyType.PackageVersion, IsDirect: true)
166
+ ],
167
+ }
168
+ }
169
+ );
170
+ }
171
+
172
+ [Fact]
173
+ public async Task TestRepo()
174
+ {
175
+ var solutionPath = "solution.sln";
176
+ await TestDiscoveryAsync(
177
+ workspacePath: "",
178
+ files: new[]
179
+ {
180
+ ("src/project.csproj", """
181
+ <Project Sdk="Microsoft.NET.Sdk">
182
+ <PropertyGroup>
183
+ <TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
184
+ </PropertyGroup>
185
+
186
+ <ItemGroup>
187
+ <PackageReference Include="Newtonsoft.Json" />
188
+ </ItemGroup>
189
+ </Project>
190
+ """),
191
+ ("Directory.Packages.props", """
192
+ <Project>
193
+ <PropertyGroup>
194
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
195
+ <NewtonsoftJsonPackageVersion>9.0.1</NewtonsoftJsonPackageVersion>
196
+ </PropertyGroup>
197
+
198
+ <ItemGroup>
199
+ <PackageVersion Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
200
+ </ItemGroup>
201
+ </Project>
202
+ """),
203
+ (solutionPath, """
204
+ Microsoft Visual Studio Solution File, Format Version 12.00
205
+ # Visual Studio 14
206
+ VisualStudioVersion = 14.0.22705.0
207
+ MinimumVisualStudioVersion = 10.0.40219.1
208
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "project", ".\src\project.csproj", "{782E0C0A-10D3-444D-9640-263D03D2B20C}"
209
+ EndProject
210
+ Global
211
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
212
+ Debug|Any CPU = Debug|Any CPU
213
+ Release|Any CPU = Release|Any CPU
214
+ EndGlobalSection
215
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
216
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
217
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Debug|Any CPU.Build.0 = Debug|Any CPU
218
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Release|Any CPU.ActiveCfg = Release|Any CPU
219
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Release|Any CPU.Build.0 = Release|Any CPU
220
+ EndGlobalSection
221
+ GlobalSection(SolutionProperties) = preSolution
222
+ HideSolutionNode = FALSE
223
+ EndGlobalSection
224
+ EndGlobal
225
+ """),
226
+ ("global.json", """
227
+ {
228
+ "sdk": {
229
+ "version": "6.0.405",
230
+ "rollForward": "latestPatch"
231
+ },
232
+ "msbuild-sdks": {
233
+ "My.Custom.Sdk": "5.0.0",
234
+ "My.Other.Sdk": "1.0.0-beta"
235
+ }
236
+ }
237
+ """),
238
+ (".config/dotnet-tools.json", """
239
+ {
240
+ "version": 1,
241
+ "isRoot": true,
242
+ "tools": {
243
+ "microsoft.botsay": {
244
+ "version": "1.0.0",
245
+ "commands": [
246
+ "botsay"
247
+ ]
248
+ },
249
+ "dotnetsay": {
250
+ "version": "2.1.3",
251
+ "commands": [
252
+ "dotnetsay"
253
+ ]
254
+ }
255
+ }
256
+ }
257
+ """),
258
+ },
259
+ expectedResult: new()
260
+ {
261
+ FilePath = "",
262
+ Projects = [
263
+ new()
264
+ {
265
+ FilePath = "src/project.csproj",
266
+ TargetFrameworks = ["net6.0", "netstandard2.0"],
267
+ ExpectedDependencyCount = 19,
268
+ Dependencies = [
269
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
270
+ new("Newtonsoft.Json", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net6.0", "netstandard2.0"], IsDirect: true)
271
+ ],
272
+ Properties = [
273
+ new("ManagePackageVersionsCentrally", "true", "Directory.Packages.props"),
274
+ new("NewtonsoftJsonPackageVersion", "9.0.1", "Directory.Packages.props"),
275
+ new("TargetFrameworks", "netstandard2.0;net6.0", "src/project.csproj"),
276
+ ]
277
+ }
278
+ ],
279
+ DirectoryPackagesProps = new()
280
+ {
281
+ FilePath = "Directory.Packages.props",
282
+ Dependencies = [
283
+ new("Newtonsoft.Json", "9.0.1", DependencyType.PackageVersion, IsDirect: true)
284
+ ],
285
+ },
286
+ GlobalJson = new()
287
+ {
288
+ FilePath = "global.json",
289
+ Dependencies = [
290
+ new("Microsoft.NET.Sdk", "6.0.405", DependencyType.MSBuildSdk),
291
+ new("My.Custom.Sdk", "5.0.0", DependencyType.MSBuildSdk),
292
+ new("My.Other.Sdk", "1.0.0-beta", DependencyType.MSBuildSdk),
293
+ ]
294
+ },
295
+ DotNetToolsJson = new()
296
+ {
297
+ FilePath = ".config/dotnet-tools.json",
298
+ Dependencies = [
299
+ new("microsoft.botsay", "1.0.0", DependencyType.DotNetTool),
300
+ new("dotnetsay", "2.1.3", DependencyType.DotNetTool),
301
+ ]
302
+ }
303
+ }
304
+ );
305
+ }
306
+ }
@@ -0,0 +1,36 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using NuGetUpdater.Core.Discover;
4
+
5
+ namespace NuGetUpdater.Core.Test.Discover;
6
+
7
+ public record ExpectedWorkspaceDiscoveryResult : IDiscoveryResult
8
+ {
9
+ public required string FilePath { get; init; }
10
+ public bool IsSuccess { get; init; } = true;
11
+ public ImmutableArray<ExpectedSdkProjectDiscoveryResult> Projects { get; init; }
12
+ public int? ExpectedProjectCount { get; init; }
13
+ public ExpectedDirectoryPackagesPropsDiscovertyResult? DirectoryPackagesProps { get; init; }
14
+ public ExpectedDependencyDiscoveryResult? GlobalJson { get; init; }
15
+ public ExpectedDependencyDiscoveryResult? DotNetToolsJson { get; init; }
16
+ }
17
+
18
+ public record ExpectedDirectoryPackagesPropsDiscovertyResult : ExpectedDependencyDiscoveryResult
19
+ {
20
+ public bool IsTransitivePinningEnabled { get; init; }
21
+ }
22
+
23
+ public record ExpectedSdkProjectDiscoveryResult : ExpectedDependencyDiscoveryResult
24
+ {
25
+ public ImmutableArray<Property> Properties { get; init; } = [];
26
+ public ImmutableArray<string> TargetFrameworks { get; init; } = [];
27
+ public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
28
+ }
29
+
30
+ public record ExpectedDependencyDiscoveryResult : IDiscoveryResultWithDependencies
31
+ {
32
+ public required string FilePath { get; init; }
33
+ public bool IsSuccess { get; init; } = true;
34
+ public ImmutableArray<Dependency> Dependencies { get; init; }
35
+ public int? ExpectedDependencyCount { get; init; }
36
+ }
@@ -1,4 +1,3 @@
1
- using System.Collections.Generic;
2
1
  using System.Diagnostics.CodeAnalysis;
3
2
 
4
3
  using Xunit;
@@ -30,7 +29,7 @@ public class DotnetToolsJsonBuildFileTests
30
29
  """;
31
30
 
32
31
  private static DotNetToolsJsonBuildFile GetBuildFile() => new(
33
- repoRootPath: "/",
32
+ basePath: "/",
34
33
  path: "/.config/dotnet-tools.json",
35
34
  contents: DotnetToolsJson,
36
35
  logger: new Logger(verbose: true));
@@ -1,6 +1,4 @@
1
- using System.Collections.Generic;
2
1
  using System.Diagnostics.CodeAnalysis;
3
- using System.Linq;
4
2
 
5
3
  using Xunit;
6
4
 
@@ -29,7 +27,7 @@ public class GlobalJsonBuildFileTests
29
27
  """;
30
28
 
31
29
  private static GlobalJsonBuildFile GetBuildFile(string contents) => new(
32
- repoRootPath: "/",
30
+ basePath: "/",
33
31
  path: "/global.json",
34
32
  contents: contents,
35
33
  logger: new Logger(verbose: true));
@@ -55,6 +53,7 @@ public class GlobalJsonBuildFileTests
55
53
  {
56
54
  var expectedDependencies = new List<Dependency>
57
55
  {
56
+ new("Microsoft.NET.Sdk", "6.0.405", DependencyType.MSBuildSdk),
58
57
  new("My.Custom.Sdk", "5.0.0", DependencyType.MSBuildSdk),
59
58
  new("My.Other.Sdk", "1.0.0-beta", DependencyType.MSBuildSdk)
60
59
  };
@@ -1,6 +1,4 @@
1
- using System.Collections.Generic;
2
1
  using System.Diagnostics.CodeAnalysis;
3
- using System.Linq;
4
2
 
5
3
  using Microsoft.Language.Xml;
6
4
 
@@ -28,7 +26,7 @@ public class PackagesConfigBuildFileTests
28
26
  """;
29
27
 
30
28
  private static PackagesConfigBuildFile GetBuildFile(string contents) => new(
31
- repoRootPath: "/",
29
+ basePath: "/",
32
30
  path: "/packages.config",
33
31
  contents: Parser.ParseText(contents));
34
32
 
@@ -37,9 +35,9 @@ public class PackagesConfigBuildFileTests
37
35
  {
38
36
  var expectedDependencies = new List<Dependency>
39
37
  {
40
- new("Microsoft.CodeDom.Providers.DotNetCompilerPlatform", "1.0.0", DependencyType.PackageConfig),
41
- new("Microsoft.Net.Compilers", "1.0.0", DependencyType.PackageConfig, true),
42
- new("Newtonsoft.Json", "8.0.3", DependencyType.PackageConfig)
38
+ new("Microsoft.CodeDom.Providers.DotNetCompilerPlatform", "1.0.0", DependencyType.PackagesConfig),
39
+ new("Microsoft.Net.Compilers", "1.0.0", DependencyType.PackagesConfig, IsDevDependency: true),
40
+ new("Newtonsoft.Json", "8.0.3", DependencyType.PackagesConfig)
43
41
  };
44
42
 
45
43
  var buildFile = GetBuildFile(PackagesConfig);
@@ -1,10 +1,10 @@
1
- using System.Collections.Generic;
2
1
  using System.Diagnostics.CodeAnalysis;
3
- using System.Linq;
4
2
  using System.Text.RegularExpressions;
5
3
 
6
4
  using Microsoft.Language.Xml;
7
5
 
6
+ using NuGetUpdater.Core.Test.Utilities;
7
+
8
8
  using Xunit;
9
9
 
10
10
  namespace NuGetUpdater.Core.Test.Files;
@@ -50,7 +50,7 @@ public class ProjectBuildFileTests
50
50
  """;
51
51
 
52
52
  private static ProjectBuildFile GetBuildFile(string contents, string filename) => new(
53
- repoRootPath: "/",
53
+ basePath: "/",
54
54
  path: $"/{filename}",
55
55
  contents: Parser.ParseText(contents));
56
56
 
@@ -59,16 +59,17 @@ public class ProjectBuildFileTests
59
59
  {
60
60
  var expectedDependencies = new List<Dependency>
61
61
  {
62
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
62
63
  new("GuiLabs.Language.Xml", "1.2.60", DependencyType.PackageReference),
63
64
  new("Microsoft.CodeAnalysis.CSharp", null, DependencyType.PackageReference),
64
- new("Newtonsoft.Json", "13.0.3", DependencyType.PackageReference, IsOverride: true)
65
+ new("Newtonsoft.Json", "13.0.3", DependencyType.PackageReference, IsUpdate: true, IsOverride: true)
65
66
  };
66
67
 
67
68
  var buildFile = GetBuildFile(ProjectCsProj, "Project.csproj");
68
69
 
69
70
  var dependencies = buildFile.GetDependencies();
70
71
 
71
- Assert.Equal(expectedDependencies, dependencies);
72
+ AssertEx.Equal(expectedDependencies, dependencies);
72
73
  }
73
74
 
74
75
  [Fact]
@@ -11,9 +11,10 @@
11
11
  </ItemGroup>
12
12
 
13
13
  <ItemGroup>
14
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
15
- <PackageReference Include="xunit" Version="2.4.2" />
16
- <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
14
+ <PackageReference Include="DiffPlex" />
15
+ <PackageReference Include="Microsoft.NET.Test.Sdk" />
16
+ <PackageReference Include="xunit" />
17
+ <PackageReference Include="xunit.runner.visualstudio" />
17
18
  </ItemGroup>
18
19
 
19
20
  <ItemGroup>
@@ -1,8 +1,7 @@
1
- using System;
2
- using System.IO;
3
-
4
1
  namespace NuGetUpdater.Core.Test;
5
2
 
3
+ using TestFile = (string Path, string Contents);
4
+
6
5
  public sealed class TemporaryDirectory : IDisposable
7
6
  {
8
7
  public string DirectoryPath { get; }
@@ -20,15 +19,48 @@ public sealed class TemporaryDirectory : IDisposable
20
19
  Directory.Delete(DirectoryPath, true);
21
20
  }
22
21
 
23
- public static TemporaryDirectory CreateWithContents(params (string Path, string Contents)[] fileContents)
22
+ public async Task<TestFile[]> ReadFileContentsAsync(HashSet<string> filePaths)
23
+ {
24
+ var files = new List<(string Path, string Content)>();
25
+ foreach (var file in Directory.GetFiles(DirectoryPath, "*.*", SearchOption.AllDirectories))
26
+ {
27
+ var localPath = file.StartsWith(DirectoryPath)
28
+ ? file[DirectoryPath.Length..]
29
+ : file; // how did this happen?
30
+ localPath = localPath.NormalizePathToUnix();
31
+ if (localPath.StartsWith('/'))
32
+ {
33
+ localPath = localPath[1..];
34
+ }
35
+
36
+ if (filePaths.Contains(localPath))
37
+ {
38
+ var content = await File.ReadAllTextAsync(file);
39
+ files.Add((localPath, content));
40
+ }
41
+ }
42
+
43
+ return files.ToArray();
44
+ }
45
+
46
+ public static async Task<TemporaryDirectory> CreateWithContentsAsync(params TestFile[] fileContents)
24
47
  {
25
48
  var temporaryDirectory = new TemporaryDirectory();
49
+
50
+ var parentDirectory = Path.GetDirectoryName(temporaryDirectory.DirectoryPath)!;
51
+
52
+ // prevent directory crawling
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"), "<Project />");
56
+
26
57
  foreach (var (path, contents) in fileContents)
27
58
  {
28
- var fullPath = Path.Combine(temporaryDirectory.DirectoryPath, path);
59
+ var localPath = path.StartsWith('/') ? path[1..] : path; // remove path rooting character
60
+ var fullPath = Path.Combine(temporaryDirectory.DirectoryPath, localPath);
29
61
  var fullDirectory = Path.GetDirectoryName(fullPath)!;
30
62
  Directory.CreateDirectory(fullDirectory);
31
- File.WriteAllText(fullPath, contents);
63
+ await File.WriteAllTextAsync(fullPath, contents);
32
64
  }
33
65
 
34
66
  return temporaryDirectory;
@@ -1,16 +1,15 @@
1
1
  using System;
2
- using System.Collections.Generic;
3
2
  using System.IO;
4
3
  using System.Linq;
5
4
  using System.Threading.Tasks;
6
5
 
7
6
  using Xunit;
8
7
 
9
- using TestFile = (string Path, string Content);
10
- using TestProject = (string Path, string Content, System.Guid ProjectId);
11
-
12
8
  namespace NuGetUpdater.Core.Test.Update;
13
9
 
10
+ using TestFile = (string Path, string Content);
11
+ using TestProject = (string Path, string Content, Guid ProjectId);
12
+
14
13
  public abstract class UpdateWorkerTestBase
15
14
  {
16
15
  protected static Task TestNoChange(
@@ -20,7 +19,7 @@ public abstract class UpdateWorkerTestBase
20
19
  bool useSolution,
21
20
  string projectContents,
22
21
  bool isTransitive = false,
23
- (string Path, string Content)[]? additionalFiles = null,
22
+ TestFile[]? additionalFiles = null,
24
23
  string projectFilePath = "test-project.csproj")
25
24
  {
26
25
  return useSolution
@@ -67,7 +66,7 @@ public abstract class UpdateWorkerTestBase
67
66
  string newVersion,
68
67
  string projectContents,
69
68
  bool isTransitive = false,
70
- (string Path, string Content)[]? additionalFiles = null,
69
+ TestFile[]? additionalFiles = null,
71
70
  string projectFilePath = "test-project.csproj")
72
71
  => TestUpdateForProject(
73
72
  dependencyName,
@@ -202,53 +201,26 @@ public abstract class UpdateWorkerTestBase
202
201
  AssertContainsFiles(expectedResult, actualResult);
203
202
  }
204
203
 
205
- protected static async Task<(string Path, string Content)[]> RunUpdate((string Path, string Content)[] files, Func<string, Task> action)
204
+ protected static async Task<TestFile[]> RunUpdate(TestFile[] files, Func<string, Task> action)
206
205
  {
207
206
  // write initial files
208
- using var tempDir = new TemporaryDirectory();
209
- foreach (var file in files)
210
- {
211
- var localPath = file.Path.StartsWith('/') ? file.Path[1..] : file.Path; // remove path rooting character
212
- var filePath = Path.Combine(tempDir.DirectoryPath, localPath);
213
- var directoryPath = Path.GetDirectoryName(filePath);
214
- Directory.CreateDirectory(directoryPath!);
215
- await File.WriteAllTextAsync(filePath, file.Content);
216
- }
207
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(files);
217
208
 
218
209
  // run update
219
- await action(tempDir.DirectoryPath);
210
+ await action(temporaryDirectory.DirectoryPath);
220
211
 
221
212
  // gather results
222
- var expectedFiles = new HashSet<string>(files.Select(f => f.Path));
223
- var result = new List<(string Path, string Content)>();
224
- foreach (var file in Directory.GetFiles(tempDir.DirectoryPath, "*.*", SearchOption.AllDirectories))
225
- {
226
- var localPath = file.StartsWith(tempDir.DirectoryPath)
227
- ? file[tempDir.DirectoryPath.Length..]
228
- : file; // how did this happen?
229
- localPath = localPath.NormalizePathToUnix();
230
- if (localPath.StartsWith('/'))
231
- {
232
- localPath = localPath[1..];
233
- }
234
-
235
- if (expectedFiles.Contains(localPath))
236
- {
237
- var content = await File.ReadAllTextAsync(file);
238
- result.Add((localPath, content));
239
- }
240
- }
241
-
242
- return result.ToArray();
213
+ var filePaths = files.Select(f => f.Path).ToHashSet();
214
+ return await temporaryDirectory.ReadFileContentsAsync(filePaths);
243
215
  }
244
216
 
245
- protected static void AssertEqualFiles((string Path, string Content)[] expected, (string Path, string Content)[] actual)
217
+ protected static void AssertEqualFiles(TestFile[] expected, TestFile[] actual)
246
218
  {
247
219
  Assert.Equal(expected.Length, actual.Length);
248
220
  AssertContainsFiles(expected, actual);
249
221
  }
250
222
 
251
- protected static void AssertContainsFiles((string Path, string Content)[] expected, (string Path, string Content)[] actual)
223
+ protected static void AssertContainsFiles(TestFile[] expected, TestFile[] actual)
252
224
  {
253
225
  var actualContents = actual.ToDictionary(pair => pair.Path, pair => pair.Content);
254
226
  foreach (var expectedPair in expected)
@@ -2528,5 +2528,35 @@ public partial class UpdateWorkerTests
2528
2528
  """
2529
2529
  );
2530
2530
  }
2531
+
2532
+ [Fact]
2533
+ public async Task UnresolvablePropertyDoesNotStopOtherUpdates()
2534
+ {
2535
+ // the property `$(MauiVersion)` cannot be resolved
2536
+ await TestUpdateForProject("Newtonsoft.Json", "7.0.1", "13.0.1",
2537
+ projectContents: """
2538
+ <Project Sdk="Microsoft.NET.Sdk">
2539
+ <PropertyGroup>
2540
+ <TargetFramework>net8.0</TargetFramework>
2541
+ </PropertyGroup>
2542
+ <ItemGroup>
2543
+ <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
2544
+ <PackageReference Include="Newtonsoft.Json" Version="7.0.1" />
2545
+ </ItemGroup>
2546
+ </Project>
2547
+ """,
2548
+ expectedProjectContents: """
2549
+ <Project Sdk="Microsoft.NET.Sdk">
2550
+ <PropertyGroup>
2551
+ <TargetFramework>net8.0</TargetFramework>
2552
+ </PropertyGroup>
2553
+ <ItemGroup>
2554
+ <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
2555
+ <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2556
+ </ItemGroup>
2557
+ </Project>
2558
+ """
2559
+ );
2560
+ }
2531
2561
  }
2532
2562
  }