dependabot-nuget 0.321.2 → 0.322.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +22 -22
  3. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageMapper.cs +9 -0
  4. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +21 -7
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +19 -11
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +19 -9
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +21 -14
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +8 -5
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +29 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +20 -19
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +2 -1
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscoveryTargetingPacks.props +2 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/IDependencySolver.cs +8 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/MSBuildDependencySolver.cs +32 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +1 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +10 -1
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +6 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +5 -13
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/PrivateSourceTimedOutException.cs +12 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceTimedOut.cs +10 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +1 -1
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +1 -1
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +1 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +1 -1
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +6 -3
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +376 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/IFileWriter.cs +14 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +477 -0
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +9 -5
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +18 -7
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +26 -1
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +15 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +633 -0
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +0 -2
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -2
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +49 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +0 -1
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +484 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +21 -22
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +1 -1
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +8 -0
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/DotNetToolsJsonUpdaterTests.cs +181 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterTestsBase.cs +61 -0
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +917 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests_MiscellaneousTests.cs +154 -0
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/TestFileWriterReturnsConstantResult.cs +20 -0
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +1620 -0
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests_CreateUpdatedVersionRangeTests.cs +25 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/GlobalJsonUpdaterTests.cs +139 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +1961 -1
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateOperationResultTests.cs +116 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +16 -1043
  60. data/helpers/lib/NuGetUpdater/global.json +1 -1
  61. metadata +21 -10
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +0 -375
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +0 -296
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.LockFile.cs +0 -251
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +0 -201
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +0 -3821
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -2706
@@ -0,0 +1,633 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using NuGetUpdater.Core.DependencySolver;
4
+ using NuGetUpdater.Core.Test.Utilities;
5
+
6
+ using Xunit;
7
+
8
+ namespace NuGetUpdater.Core.Test.DependencySolver;
9
+
10
+ public class MSBuildDependencySolverTests : TestBase
11
+ {
12
+ [Fact]
13
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingTopLevelPackage()
14
+ {
15
+ // Updating root package
16
+ // CS-Script Code to 2.0.0 requires its dependency Microsoft.CodeAnalysis.CSharp.Scripting to be 3.6.0 and its transitive dependency Microsoft.CodeAnalysis.Common to be 3.6.0
17
+ await TestAsync(
18
+ packages: [
19
+ // initial packages
20
+ MockNuGetPackage.CreateSimplePackage("CS-Script.Core", "1.3.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.Scripting.Common", "[3.4.0]")])]),
21
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Scripting.Common", "3.4.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[3.4.0]")])]),
22
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "3.4.0", "net8.0"),
23
+ // available packages
24
+ MockNuGetPackage.CreateSimplePackage("CS-Script.Core", "2.0.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Scripting.Common", "[3.6.0]")])]),
25
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Scripting.Common", "3.6.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[3.6.0]")])]),
26
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "3.6.0", "net8.0"),
27
+ ],
28
+ existingTopLevelDependencies: [
29
+ "CS-Script.Core/1.3.1",
30
+ "Microsoft.CodeAnalysis.Scripting.Common/3.4.0",
31
+ "Microsoft.CodeAnalysis.Common/3.4.0",
32
+ ],
33
+ desiredDependencies: [
34
+ "CS-Script.Core/2.0.0",
35
+ ],
36
+ targetFramework: "net8.0",
37
+ expectedResolvedDependencies: [
38
+ "CS-Script.Core/2.0.0",
39
+ "Microsoft.CodeAnalysis.Scripting.Common/3.6.0",
40
+ "Microsoft.CodeAnalysis.Common/3.6.0",
41
+ ]
42
+ );
43
+ }
44
+
45
+ [Fact]
46
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingNonExistingDependency()
47
+ {
48
+ // Updating a dependency (Microsoft.Bcl.AsyncInterfaces) of the root package (Azure.Core) will require the root package to also update, but since the dependency is not in the existing list, we do not include it
49
+ await TestAsync(
50
+ packages: [
51
+ // initial packages
52
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.21.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "[1.0.0]")])]),
53
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.0.0", "net8.0"),
54
+ // available packages
55
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.22.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "[1.1.1]")])]),
56
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.1.1", "net8.0"),
57
+ ],
58
+ existingTopLevelDependencies: [
59
+ "Azure.Core/1.21.0",
60
+ ],
61
+ desiredDependencies: [
62
+ "Microsoft.Bcl.AsyncInterfaces/1.1.1",
63
+ ],
64
+ targetFramework: "net8.0",
65
+ expectedResolvedDependencies: [
66
+ "Azure.Core/1.22.0",
67
+ ]
68
+ );
69
+ }
70
+
71
+ [Fact]
72
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingNonExistentDependencyAndKeepingReference()
73
+ {
74
+ // Adding a reference
75
+ // Newtonsoft.Json needs to update to 13.0.1. Although Newtonsoft.Json.Bson can use the original version of 12.0.1, for security vulnerabilities and
76
+ // because there is no later version of Newtonsoft.Json.Bson 1.0.2, Newtonsoft.Json would be added to the existing list to prevent resolution
77
+ await TestAsync(
78
+ packages: [
79
+ // initial packages
80
+ MockNuGetPackage.CreateSimplePackage("Newtonsoft.Json.Bson", "1.0.2", "net8.0", [(null, [("Newtonsoft.Json", "12.0.1")])]),
81
+ MockNuGetPackage.CreateSimplePackage("Newtonsoft.Json", "12.0.1", "net8.0"),
82
+ // available packages
83
+ MockNuGetPackage.CreateSimplePackage("Newtonsoft.Json", "13.0.1", "net8.0"),
84
+ ],
85
+ existingTopLevelDependencies: [
86
+ "Newtonsoft.Json.Bson/1.0.2"
87
+ ],
88
+ desiredDependencies: [
89
+ "Newtonsoft.Json/13.0.1",
90
+ ],
91
+ targetFramework: "net8.0",
92
+ expectedResolvedDependencies: [
93
+ "Newtonsoft.Json.Bson/1.0.2",
94
+ "Newtonsoft.Json/13.0.1",
95
+ ]
96
+ );
97
+ }
98
+
99
+ [Fact]
100
+ public async Task DependencyConflictsCanBeResolvedNewTransitiveDependencyNotExisting()
101
+ {
102
+ // Updating unreferenced dependency
103
+ // Root package (Microsoft.CodeAnalysis.Compilers) and its dependencies (Microsoft.CodeAnalysis.CSharp), (Microsoft.CodeAnalysis.VisualBasic) are all 4.9.2
104
+ // These packages all require the transitive dependency of the root package (Microsoft.CodeAnalysis.Common) to be 4.9.2, but it's not in the existing list
105
+ // If Microsoft.CodeAnalysis.Common is updated to 4.10.0, everything else updates and Microsoft.CoseAnalysis.Common is not kept in the existing list
106
+ await TestAsync(
107
+ packages: [
108
+ // initial packages
109
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.9.2", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.9.2]"), ("Microsoft.CodeAnalysis.CSharp", "[4.9.2]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.9.2]")])]),
110
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.9.2", "net8.0"),
111
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.9.2", "net8.0"),
112
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", "net8.0"),
113
+ // available packages
114
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.10.0]"), ("Microsoft.CodeAnalysis.CSharp", "[4.10.0]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.10.0]")])]),
115
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.10.0", "net8.0"),
116
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.10.0", "net8.0"),
117
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.10.0", "net8.0"),
118
+ ],
119
+ existingTopLevelDependencies: [
120
+ "Microsoft.CodeAnalysis.Compilers/4.9.2",
121
+ "Microsoft.CodeAnalysis.CSharp/4.9.2",
122
+ "Microsoft.CodeAnalysis.VisualBasic/4.9.2",
123
+ ],
124
+ desiredDependencies: [
125
+ "Microsoft.CodeAnalysis.Common/4.10.0",
126
+ ],
127
+ targetFramework: "net8.0",
128
+ expectedResolvedDependencies: [
129
+ "Microsoft.CodeAnalysis.Compilers/4.10.0",
130
+ "Microsoft.CodeAnalysis.CSharp/4.10.0",
131
+ "Microsoft.CodeAnalysis.VisualBasic/4.10.0",
132
+ ]
133
+ );
134
+ }
135
+
136
+ [Fact]
137
+ public async Task DependencyConflictsCanBeResolvedTransitiveDependencyExisting()
138
+ {
139
+ // Updating referenced dependency
140
+ // The same as previous test, but the transitive dependency (Microsoft.CodeAnalysis.Common) is in the existing list
141
+ await TestAsync(
142
+ packages: [
143
+ // initial packages
144
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.9.2", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.9.2]"), ("Microsoft.CodeAnalysis.CSharp", "[4.9.2]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.9.2]")])]),
145
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.9.2", "net8.0"),
146
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.9.2", "net8.0"),
147
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", "net8.0"),
148
+ // available packages
149
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.10.0]"), ("Microsoft.CodeAnalysis.CSharp", "[4.10.0]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.10.0]")])]),
150
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.10.0", "net8.0"),
151
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.10.0", "net8.0"),
152
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.10.0", "net8.0"),
153
+ ],
154
+ existingTopLevelDependencies: [
155
+ "Microsoft.CodeAnalysis.Compilers/4.9.2",
156
+ "Microsoft.CodeAnalysis.Common/4.9.2",
157
+ "Microsoft.CodeAnalysis.CSharp/4.9.2",
158
+ "Microsoft.CodeAnalysis.VisualBasic/4.9.2",
159
+ ],
160
+ desiredDependencies: [
161
+ "Microsoft.CodeAnalysis.Common/4.10.0",
162
+ ],
163
+ targetFramework: "net8.0",
164
+ expectedResolvedDependencies: [
165
+ "Microsoft.CodeAnalysis.Compilers/4.10.0",
166
+ "Microsoft.CodeAnalysis.Common/4.10.0",
167
+ "Microsoft.CodeAnalysis.CSharp/4.10.0",
168
+ "Microsoft.CodeAnalysis.VisualBasic/4.10.0",
169
+ ]
170
+ );
171
+ }
172
+
173
+ [Fact]
174
+ public async Task DependencyConflictsCanBeResolvedNewSelectiveAdditionPackages()
175
+ {
176
+ // A combination of the third and fourth test, to measure efficiency of updating separate families
177
+ // Keeping a dependency that was not included in the original list (Newtonsoft.Json)
178
+ // Not keeping a dependency that was not included in the original list (Microsoft.CodeAnalysis.Common)
179
+ await TestAsync(
180
+ packages: [
181
+ // initial packages
182
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.9.2", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.9.2]"), ("Microsoft.CodeAnalysis.CSharp", "[4.9.2]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.9.2]")])]),
183
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.9.2", "net8.0"),
184
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.9.2", "net8.0"),
185
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", "net8.0"),
186
+ MockNuGetPackage.CreateSimplePackage("Newtonsoft.Json.Bson", "1.0.2", "net8.0", [(null, [("Newtonsoft.Json", "13.0.1")])]),
187
+ MockNuGetPackage.CreateSimplePackage("Newtonsoft.Json", "13.0.1", "net8.0"),
188
+ // available packages
189
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Compilers", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.10.0]"), ("Microsoft.CodeAnalysis.CSharp", "[4.10.0]"), ("Microsoft.CodeAnalysis.VisualBasic", "[4.10.0]")])]),
190
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.10.0", "net8.0"),
191
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.10.0", "net8.0"),
192
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.VisualBasic", "4.10.0", "net8.0"),
193
+ ],
194
+ existingTopLevelDependencies: [
195
+ "Microsoft.CodeAnalysis.Compilers/4.9.2",
196
+ "Microsoft.CodeAnalysis.CSharp/4.9.2",
197
+ "Microsoft.CodeAnalysis.VisualBasic/4.9.2",
198
+ "Newtonsoft.Json.Bson/1.0.2",
199
+ ],
200
+ desiredDependencies: [
201
+ "Microsoft.CodeAnalysis.Common/4.10.0",
202
+ "Newtonsoft.Json/13.0.1",
203
+ ],
204
+ targetFramework: "net8.0",
205
+ expectedResolvedDependencies: [
206
+ "Microsoft.CodeAnalysis.Compilers/4.10.0",
207
+ "Microsoft.CodeAnalysis.CSharp/4.10.0",
208
+ "Microsoft.CodeAnalysis.VisualBasic/4.10.0",
209
+ "Newtonsoft.Json.Bson/1.0.2",
210
+ "Newtonsoft.Json/13.0.1",
211
+ ]
212
+ );
213
+ }
214
+
215
+ [Fact]
216
+ public async Task DependencyConflictsCanBeResolvedNewSharingDependency()
217
+ {
218
+ // Two top level packages (Buildalyzer), (Microsoft.CodeAnalysis.CSharp.Scripting) that share a dependency (Microsoft.CodeAnalysis.Csharp)
219
+ // Updating ONE of the top level packages, which updates the dependencies and their other "parents"
220
+ // First family: Buildalyzer 7.0.1 requires Microsoft.CodeAnalysis.CSharp to be = 4.0.1 and Microsoft.CodeAnalysis.Common to be 4.0.1 (@ 6.0.4, Microsoft.CodeAnalysis.Common isn't a dependency of buildalyzer)
221
+ // Second family: Microsoft.CodeAnalysis.CSharp.Scripting 4.0.1 requires Microsoft.CodeAnalysis.CSharp 4.0.1 and Microsoft.CodeAnalysis.Common to be 4.0.1 (Specific version)
222
+ // Updating Buildalyzer to 7.0.1 will update its transitive dependency (Microsoft.CodeAnalysis.Common) and then its transitive dependency's "family"
223
+ await TestAsync(
224
+ packages: [
225
+ MockNuGetPackage.CreateSimplePackage("Buildalyzer", "6.0.4", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[3.10.0]")])]),
226
+ MockNuGetPackage.CreateSimplePackage("Buildalyzer", "7.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.0.1]")])]),
227
+
228
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "3.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[3.10.0]")])]),
229
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.0.1]")])]),
230
+
231
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "3.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[3.10.0]")])]),
232
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.0.1]")])]),
233
+
234
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "3.10.0", "net8.0"),
235
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.0.1", "net8.0"),
236
+ ],
237
+ existingTopLevelDependencies: [
238
+ "Buildalyzer/6.0.4",
239
+ "Microsoft.CodeAnalysis.CSharp.Scripting/3.10.0",
240
+ "Microsoft.CodeAnalysis.CSharp/3.10.0",
241
+ "Microsoft.CodeAnalysis.Common/3.10.0",
242
+ ],
243
+ desiredDependencies: [
244
+ "Buildalyzer/7.0.1",
245
+ ],
246
+ targetFramework: "net8.0",
247
+ expectedResolvedDependencies: [
248
+ "Buildalyzer/7.0.1",
249
+ "Microsoft.CodeAnalysis.CSharp.Scripting/4.0.1",
250
+ "Microsoft.CodeAnalysis.CSharp/4.0.1",
251
+ "Microsoft.CodeAnalysis.Common/4.0.1",
252
+ ]
253
+ );
254
+ }
255
+
256
+ [Fact]
257
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingEntireFamily()
258
+ {
259
+ // Updating two families at once to test efficiency
260
+ // First family: Direct dependency (Microsoft.CodeAnalysis.Common) needs to be updated, which will then need to update in the existing list its dependency (System.Collections.Immutable) and "parent" (Microsoft.CodeAnalysis.Csharp.Scripting)
261
+ // Second family: Updating the root package (Azure.Core) in the existing list will also need to update its dependency (Microsoft.Bcl.AsyncInterfaces)
262
+ await TestAsync(
263
+ packages: [
264
+ // initial packages
265
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.8.0]"), ("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
266
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
267
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.8.0", "net8.0", [(null, [("System.Collections.Immutable", "7.0.0")])]),
268
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "7.0.0", "net8.0"),
269
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.21.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "1.0.0")])]),
270
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.0.0", "net8.0"),
271
+ // available packages
272
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.10.0]"), ("Microsoft.CodeAnalysis.Common", "[4.10.0]")])]),
273
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.10.0]")])]),
274
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.10.0", "net8.0", [(null, [("System.Collections.Immutable", "8.0.0")])]),
275
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "8.0.0", "net8.0"),
276
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.22.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "1.1.1")])]),
277
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.1.1", "net8.0"),
278
+ ],
279
+ existingTopLevelDependencies: [
280
+ "System.Collections.Immutable/7.0.0",
281
+ "Microsoft.CodeAnalysis.CSharp.Scripting/4.8.0",
282
+ "Microsoft.Bcl.AsyncInterfaces/1.0.0",
283
+ "Azure.Core/1.21.0",
284
+ ],
285
+ desiredDependencies: [
286
+ "Microsoft.CodeAnalysis.Common/4.10.0",
287
+ "Azure.Core/1.22.0",
288
+ ],
289
+ targetFramework: "net8.0",
290
+ expectedResolvedDependencies: [
291
+ "System.Collections.Immutable/8.0.0",
292
+ "Microsoft.CodeAnalysis.CSharp.Scripting/4.10.0",
293
+ "Microsoft.Bcl.AsyncInterfaces/1.1.1",
294
+ "Azure.Core/1.22.0",
295
+ ]
296
+ );
297
+ }
298
+
299
+ [Fact]
300
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingTopLevelAndDependency()
301
+ {
302
+ // Similar to the last test, except Microsoft.CodeAnalysis.Common is in the existing list
303
+ await TestAsync(
304
+ packages: [
305
+ // initial packages
306
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.8.0]"), ("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
307
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
308
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.8.0", "net8.0", [(null, [("System.Collections.Immutable", "7.0.0")])]),
309
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "7.0.0", "net8.0"),
310
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.21.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "1.0.0")])]),
311
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.0.0", "net8.0"),
312
+ // available packages
313
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.10.0]"), ("Microsoft.CodeAnalysis.Common", "[4.10.0]")])]),
314
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.10.0]")])]),
315
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.10.0", "net8.0", [(null, [("System.Collections.Immutable", "8.0.0")])]),
316
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "8.0.0", "net8.0"),
317
+ MockNuGetPackage.CreateSimplePackage("Azure.Core", "1.22.0", "net8.0", [(null, [("Microsoft.Bcl.AsyncInterfaces", "1.1.1")])]),
318
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Bcl.AsyncInterfaces", "1.1.1", "net8.0"),
319
+ ],
320
+ existingTopLevelDependencies: [
321
+ "System.Collections.Immutable/7.0.0",
322
+ "Microsoft.CodeAnalysis.CSharp.Scripting/4.8.0",
323
+ "Microsoft.CodeAnalysis.Common/4.8.0",
324
+ "Microsoft.Bcl.AsyncInterfaces/1.0.0",
325
+ "Azure.Core/1.21.0",
326
+ ],
327
+ desiredDependencies: [
328
+ "Microsoft.CodeAnalysis.Common/4.10.0",
329
+ "Azure.Core/1.22.0",
330
+ ],
331
+ targetFramework: "net8.0",
332
+ expectedResolvedDependencies: [
333
+ "System.Collections.Immutable/8.0.0",
334
+ "Microsoft.CodeAnalysis.CSharp.Scripting/4.10.0",
335
+ "Microsoft.CodeAnalysis.Common/4.10.0",
336
+ "Microsoft.Bcl.AsyncInterfaces/1.1.1",
337
+ "Azure.Core/1.22.0",
338
+ ]
339
+ );
340
+ }
341
+
342
+ [Fact]
343
+ public async Task DependencyConflictsCanBeResolvedNewOutOfScope()
344
+ {
345
+ // Out of scope test: AutoMapper.Extensions.Microsoft.DependencyInjection's versions are not yet compatible
346
+ // To update root package (AutoMapper.Collection) to 10.0.0, its dependency (AutoMapper) needs to update to 13.0.0.
347
+ // However, there is no higher version of AutoMapper's other "parent" (AutoMapper.Extensions.Microsoft.DependencyInjection) that is compatible with the new version
348
+ await TestAsync(
349
+ packages: [
350
+ MockNuGetPackage.CreateSimplePackage("AutoMapper.Extensions.Microsoft.DependencyInjection", "12.0.1", "net8.0", [(null, [("AutoMapper", "[12.0.1]")])]),
351
+ MockNuGetPackage.CreateSimplePackage("AutoMapper", "12.0.1", "net8.0"),
352
+ MockNuGetPackage.CreateSimplePackage("AutoMapper", "13.0.1", "net8.0"),
353
+ MockNuGetPackage.CreateSimplePackage("AutoMapper.Collection", "9.0.0", "net8.0", [(null, [("AutoMapper", "[12.0.0, 13.0.0)")])]),
354
+ MockNuGetPackage.CreateSimplePackage("AutoMapper.Collection", "10.0.0", "net8.0", [(null, [("AutoMapper", "[13.0.0, 14.0.0)")])]),
355
+ ],
356
+ existingTopLevelDependencies: [
357
+ "AutoMapper.Extensions.Microsoft.DependencyInjection/12.0.1",
358
+ "AutoMapper/12.0.1",
359
+ "AutoMapper.Collection/9.0.0",
360
+ ],
361
+ desiredDependencies: [
362
+ "AutoMapper.Collection/10.0.0",
363
+ ],
364
+ targetFramework: "net8.0",
365
+ expectedResolvedDependencies: [
366
+ "AutoMapper.Extensions.Microsoft.DependencyInjection/12.0.1",
367
+ "AutoMapper/12.0.1",
368
+ "AutoMapper.Collection/9.0.0",
369
+ ]
370
+ );
371
+ }
372
+
373
+ [Fact]
374
+ public async Task DependencyConflictsCanBeResolvedNewTwoDependenciesShareSameParent()
375
+ {
376
+ // Two dependencies (Microsoft.Extensions.Caching.Memory), (Microsoft.EntityFrameworkCore.Analyzers) used by the same parent (Microsoft.EntityFrameworkCore), updating one of the dependencies
377
+ await TestAsync(
378
+ packages: [
379
+ // initial packages
380
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore", "7.0.11", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Analyzers", "7.0.11"), ("Microsoft.Extensions.Caching.Memory", "[7.0.0]")])]),
381
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "7.0.11", "net8.0"),
382
+ MockNuGetPackage.CreateSimplePackage("Microsoft.Extensions.Caching.Memory", "7.0.0", "net8.0"),
383
+ // available packages
384
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore", "8.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0"), ("Microsoft.Extensions.Caching.Memory", "[8.0.0]")])]),
385
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", "net8.0"),
386
+ ],
387
+ existingTopLevelDependencies: [
388
+ "Microsoft.EntityFrameworkCore/7.0.11",
389
+ "Microsoft.EntityFrameworkCore.Analyzers/7.0.11",
390
+ ],
391
+ desiredDependencies: [
392
+ "Microsoft.Extensions.Caching.Memory/8.0.0",
393
+ ],
394
+ targetFramework: "net8.0",
395
+ expectedResolvedDependencies: [
396
+ "Microsoft.EntityFrameworkCore/8.0.0",
397
+ "Microsoft.EntityFrameworkCore.Analyzers/8.0.0",
398
+ ]
399
+ );
400
+ }
401
+
402
+ [Fact]
403
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourExisting()
404
+ {
405
+ // Updating referenced package
406
+ // 4 dependency chain to be updated. Since the package to be updated is in the existing list, do not update its parents since we want to change as little as possible
407
+ await TestAsync(
408
+ packages: [
409
+ // initial packages
410
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Design", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Relational", "[7.0.0]")])]),
411
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Relational", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore", "[7.0.0]")])]),
412
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Analyzers", "[7.0.0]")])]),
413
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "7.0.0", "net8.0"),
414
+ // available packages
415
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", "net8.0"),
416
+ ],
417
+ existingTopLevelDependencies: [
418
+ "Microsoft.EntityFrameworkCore.Design/7.0.0",
419
+ "Microsoft.EntityFrameworkCore.Relational/7.0.0",
420
+ "Microsoft.EntityFrameworkCore/7.0.0",
421
+ "Microsoft.EntityFrameworkCore.Analyzers/7.0.0",
422
+ ],
423
+ desiredDependencies: [
424
+ "Microsoft.EntityFrameworkCore.Analyzers/8.0.0",
425
+ ],
426
+ targetFramework: "net8.0",
427
+ expectedResolvedDependencies: [
428
+ "Microsoft.EntityFrameworkCore.Design/7.0.0",
429
+ "Microsoft.EntityFrameworkCore.Relational/7.0.0",
430
+ "Microsoft.EntityFrameworkCore/7.0.0",
431
+ "Microsoft.EntityFrameworkCore.Analyzers/8.0.0",
432
+ ]
433
+ );
434
+ }
435
+
436
+ [Fact]
437
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourNotInExisting()
438
+ {
439
+ // Updating unreferenced package
440
+ // 4 dependency chain to be updated, dependency to be updated is not in the existing list, so its family will all be updated
441
+ await TestAsync(
442
+ packages: [
443
+ // initial packages
444
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Design", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Relational", "[7.0.0]")])]),
445
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Relational", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore", "[7.0.0]")])]),
446
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore", "7.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Analyzers", "[7.0.0]")])]),
447
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "7.0.0", "net8.0"),
448
+ // available packages
449
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Design", "8.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Relational", "[8.0.0]")])]),
450
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Relational", "8.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore", "[8.0.0]")])]),
451
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore", "8.0.0", "net8.0", [(null, [("Microsoft.EntityFrameworkCore.Analyzers", "[8.0.0]")])]),
452
+ MockNuGetPackage.CreateSimplePackage("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", "net8.0"),
453
+ ],
454
+ existingTopLevelDependencies: [
455
+ "Microsoft.EntityFrameworkCore.Design/7.0.0",
456
+ "Microsoft.EntityFrameworkCore.Relational/7.0.0",
457
+ "Microsoft.EntityFrameworkCore/7.0.0",
458
+ ],
459
+ desiredDependencies: [
460
+ "Microsoft.EntityFrameworkCore.Analyzers/8.0.0",
461
+ ],
462
+ targetFramework: "net8.0",
463
+ expectedResolvedDependencies: [
464
+ "Microsoft.EntityFrameworkCore.Design/8.0.0",
465
+ "Microsoft.EntityFrameworkCore.Relational/8.0.0",
466
+ "Microsoft.EntityFrameworkCore/8.0.0",
467
+ ]
468
+ );
469
+ }
470
+
471
+ [Fact]
472
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificExisting()
473
+ {
474
+
475
+ // Updating a referenced transitive dependency
476
+ // Updating a transtitive dependency (System.Collections.Immutable) to 8.0.0, which will update its "parent" (Microsoft.CodeAnalysis.CSharp) and its "grandparent" (Microsoft.CodeAnalysis.CSharp.Workspaces) to update
477
+ await TestAsync(
478
+ packages: [
479
+ // initial packages
480
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "7.0.0", "net8.0"),
481
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Workspaces", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.8.0]"), ("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
482
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
483
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.8.0", "net8.0", [(null, [("System.Collections.Immutable", "7.0.0")])]),
484
+ // available packages
485
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "8.0.0", "net8.0"),
486
+ ],
487
+ existingTopLevelDependencies: [
488
+ "System.Collections.Immutable/7.0.0",
489
+ "Microsoft.CodeAnalysis.CSharp.Workspaces/4.8.0",
490
+ "Microsoft.CodeAnalysis.CSharp/4.8.0",
491
+ "Microsoft.CodeAnalysis.Common/4.8.0",
492
+ ],
493
+ desiredDependencies: [
494
+ "System.Collections.Immutable/8.0.0",
495
+ ],
496
+ targetFramework: "net8.0",
497
+ expectedResolvedDependencies: [
498
+ "System.Collections.Immutable/8.0.0",
499
+ "Microsoft.CodeAnalysis.CSharp.Workspaces/4.8.0",
500
+ "Microsoft.CodeAnalysis.CSharp/4.8.0",
501
+ "Microsoft.CodeAnalysis.Common/4.8.0",
502
+ ]
503
+ );
504
+ }
505
+
506
+ [Fact]
507
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificNotInExisting()
508
+ {
509
+ // Similar to the last test, with the "grandchild" (System.Collections.Immutable) not in the existing list
510
+ await TestAsync(
511
+ packages: [
512
+ // initial packages
513
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Workspaces", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.8.0]"), ("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
514
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.8.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.8.0]")])]),
515
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.8.0", "net8.0", [(null, [("System.Collections.Immutable", "[7.0.0]")])]),
516
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "7.0.0", "net8.0"),
517
+ // available packages
518
+ MockNuGetPackage.CreateSimplePackage("System.Collections.Immutable", "8.0.0", "net8.0"),
519
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Workspaces", "4.9.2", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.9.2]"), ("Microsoft.CodeAnalysis.Common", "[4.9.2]")])]),
520
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.9.2", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.9.2]")])]),
521
+ MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.9.2", "net8.0", [(null, [("System.Collections.Immutable", "[8.0.0]")])]),
522
+ ],
523
+ existingTopLevelDependencies: [
524
+ "Microsoft.CodeAnalysis.CSharp.Workspaces/4.8.0",
525
+ "Microsoft.CodeAnalysis.CSharp/4.8.0",
526
+ "Microsoft.CodeAnalysis.Common/4.8.0",
527
+ ],
528
+ desiredDependencies: [
529
+ "System.Collections.Immutable/8.0.0",
530
+ ],
531
+ targetFramework: "net8.0",
532
+ expectedResolvedDependencies: [
533
+ "Microsoft.CodeAnalysis.CSharp.Workspaces/4.9.2",
534
+ "Microsoft.CodeAnalysis.CSharp/4.9.2",
535
+ "Microsoft.CodeAnalysis.Common/4.9.2",
536
+ ]
537
+ );
538
+ }
539
+
540
+ [Fact]
541
+
542
+ public async Task DependencyConflictsCanBeResolvedAndUnnecessaryUpdatesAreNotPerformed()
543
+ {
544
+ await TestAsync(
545
+ packages: [
546
+ MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.0.0", "net8.0", [(null, [("Transitive.Dependency", "1.0.0")])]), // update from this...
547
+ MockNuGetPackage.CreateSimplePackage("Some.Dependency", "2.0.0", "net8.0", [(null, [("Transitive.Dependency", "1.0.0")])]), // ...to this...
548
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "1.0.0", "net8.0"), // ...which depends on this...
549
+ MockNuGetPackage.CreateSimplePackage("Transitive.Dependency", "2.0.0", "net8.0"), // ...but don't update this because it's not necessary
550
+ ],
551
+ existingTopLevelDependencies: [
552
+ "Some.Dependency/1.0.0",
553
+ "Transitive.Dependency/1.0.0",
554
+ ],
555
+ desiredDependencies: [
556
+ "Some.Dependency/2.0.0",
557
+ ],
558
+ targetFramework: "net8.0",
559
+ expectedResolvedDependencies: [
560
+ "Some.Dependency/2.0.0",
561
+ "Transitive.Dependency/1.0.0",
562
+ ]
563
+ );
564
+ }
565
+
566
+ [Fact(Timeout = 120_000)] // 2m
567
+ public async Task DependencyConflictsCanBeResolved_TopLevelDependencyHasNewerVersionsThatDoNotPullUpTransitive()
568
+ {
569
+ await TestAsync(
570
+ packages: [
571
+ // initial packages
572
+ MockNuGetPackage.CreateSimplePackage("Top.Level.Package", "1.41.0", "net8.0", [(null, [("Transitive.Package", "6.0.0")])]),
573
+ MockNuGetPackage.CreateSimplePackage("Transitive.Package", "6.0.0", "net8.0"),
574
+ // available packages
575
+ MockNuGetPackage.CreateSimplePackage("Top.Level.Package", "1.45.0", "net8.0", [(null, [("Transitive.Package", "6.0.0")])]),
576
+ MockNuGetPackage.CreateSimplePackage("Transitive.Package", "8.0.5", "net8.0"),
577
+ ],
578
+ existingTopLevelDependencies: [
579
+ "Top.Level.Package/1.41.0",
580
+ ],
581
+ desiredDependencies: [
582
+ "Transitive.Package/8.0.5",
583
+ ],
584
+ targetFramework: "net8.0",
585
+ expectedResolvedDependencies: [
586
+ "Top.Level.Package/1.41.0",
587
+ "Transitive.Package/8.0.5",
588
+ ]
589
+ );
590
+ }
591
+
592
+ private static async Task TestAsync(
593
+ ImmutableArray<string> existingTopLevelDependencies,
594
+ ImmutableArray<string> desiredDependencies,
595
+ string targetFramework,
596
+ ImmutableArray<string> expectedResolvedDependencies,
597
+ MockNuGetPackage[]? packages = null
598
+ )
599
+ {
600
+ // arrange
601
+ var projectName = "project.csproj";
602
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
603
+ (projectName, $"""
604
+ <Project Sdk="Microsoft.NET.Sdk">
605
+ <PropertyGroup>
606
+ <TargetFramework>{targetFramework}</TargetFramework>
607
+ </PropertyGroup>
608
+ <ItemGroup>
609
+ {string.Join("\n ", existingTopLevelDependencies.Select(d => $@"<PackageReference Include=""{d.Split('/')[0]}"" Version=""{d.Split('/')[1]}"" />"))}
610
+ </ItemGroup>
611
+ </Project>
612
+ """)
613
+ );
614
+ await Update.UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDir.DirectoryPath);
615
+ var repoContentsPath = new DirectoryInfo(tempDir.DirectoryPath);
616
+ var projectPath = new FileInfo(Path.Combine(repoContentsPath.FullName, projectName));
617
+ var experimentsManager = new ExperimentsManager() { UseDirectDiscovery = true };
618
+ var logger = new TestLogger();
619
+ var msbuildDepSolver = new MSBuildDependencySolver(repoContentsPath, projectPath, experimentsManager, logger);
620
+
621
+ // act
622
+ var resolvedDependencies = await msbuildDepSolver.SolveAsync(
623
+ [.. existingTopLevelDependencies.Select(d => new Dependency(d.Split('/')[0], d.Split('/')[1], DependencyType.PackageReference))],
624
+ [.. desiredDependencies.Select(d => new Dependency(d.Split('/')[0], d.Split('/')[1], DependencyType.PackageReference))],
625
+ targetFramework
626
+ );
627
+
628
+ // assert
629
+ Assert.NotNull(resolvedDependencies);
630
+ var actualResolvedDependencyStrings = resolvedDependencies.Value.Select(d => $"{d.Name}/{d.Version}");
631
+ AssertEx.Equal(expectedResolvedDependencies, actualResolvedDependencyStrings);
632
+ }
633
+ }
@@ -31,7 +31,6 @@ public partial class DiscoveryWorkerTests
31
31
  {
32
32
  FilePath = "global.json",
33
33
  Dependencies = [
34
- new("Microsoft.NET.Sdk", "2.2.104", DependencyType.MSBuildSdk),
35
34
  new("Microsoft.Build.Traversal", "1.0.45", DependencyType.MSBuildSdk),
36
35
  ]
37
36
  },
@@ -65,7 +64,6 @@ public partial class DiscoveryWorkerTests
65
64
  {
66
65
  FilePath = "global.json",
67
66
  Dependencies = [
68
- new("Microsoft.NET.Sdk", "2.2.104", DependencyType.MSBuildSdk),
69
67
  new("Microsoft.Build.Traversal", "1.0.45", DependencyType.MSBuildSdk),
70
68
  ]
71
69
  },