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
@@ -1,9 +1,1876 @@
1
+ using System.Collections.Immutable;
2
+ using System.Net;
3
+ using System.Net.Mail;
4
+ using System.Text;
5
+ using System.Text.Json;
6
+
7
+ using NuGet;
8
+ using NuGet.Versioning;
9
+
10
+ using NuGetUpdater.Core.Run;
11
+ using NuGetUpdater.Core.Run.ApiModel;
12
+ using NuGetUpdater.Core.Test.Utilities;
13
+ using NuGetUpdater.Core.Updater;
14
+
1
15
  using Xunit;
2
16
 
3
17
  namespace NuGetUpdater.Core.Test.Update;
4
18
 
5
19
  public class PackagesConfigUpdaterTests : TestBase
6
20
  {
21
+ [Fact]
22
+ public async Task UpdateSingleDependencyInPackagesConfig()
23
+ {
24
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
25
+ packages: [
26
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
27
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net45"),
28
+ ],
29
+ projectContents: """
30
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
31
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
32
+ <PropertyGroup>
33
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
34
+ </PropertyGroup>
35
+ <ItemGroup>
36
+ <None Include="packages.config" />
37
+ </ItemGroup>
38
+ <ItemGroup>
39
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
40
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
41
+ <Private>True</Private>
42
+ </Reference>
43
+ </ItemGroup>
44
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
45
+ </Project>
46
+ """,
47
+ packagesConfigContents: """
48
+ <packages>
49
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
50
+ </packages>
51
+ """,
52
+ expectedProjectContents: """
53
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
54
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
55
+ <PropertyGroup>
56
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
57
+ </PropertyGroup>
58
+ <ItemGroup>
59
+ <None Include="packages.config" />
60
+ </ItemGroup>
61
+ <ItemGroup>
62
+ <Reference Include="Some.Package">
63
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
64
+ <Private>True</Private>
65
+ </Reference>
66
+ </ItemGroup>
67
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
68
+ </Project>
69
+ """,
70
+ expectedPackagesConfigContents: """
71
+ <?xml version="1.0" encoding="utf-8"?>
72
+ <packages>
73
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
74
+ </packages>
75
+ """,
76
+ expectedUpdateOperations: [
77
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
78
+ ]
79
+ );
80
+ }
81
+
82
+ [Fact]
83
+ public async Task UpdateSingleDependencyInPackagesConfig_ReferenceHasNoAssemblyVersion()
84
+ {
85
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
86
+ packages: [
87
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
88
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net45"),
89
+ ],
90
+ projectContents: """
91
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
92
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
93
+ <PropertyGroup>
94
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
95
+ </PropertyGroup>
96
+ <ItemGroup>
97
+ <None Include="packages.config" />
98
+ </ItemGroup>
99
+ <ItemGroup>
100
+ <Reference Include="Some.Package">
101
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
102
+ <Private>True</Private>
103
+ </Reference>
104
+ </ItemGroup>
105
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
106
+ </Project>
107
+ """,
108
+ packagesConfigContents: """
109
+ <packages>
110
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
111
+ </packages>
112
+ """,
113
+ expectedProjectContents: """
114
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
115
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
116
+ <PropertyGroup>
117
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
118
+ </PropertyGroup>
119
+ <ItemGroup>
120
+ <None Include="packages.config" />
121
+ </ItemGroup>
122
+ <ItemGroup>
123
+ <Reference Include="Some.Package">
124
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
125
+ <Private>True</Private>
126
+ </Reference>
127
+ </ItemGroup>
128
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
129
+ </Project>
130
+ """,
131
+ expectedPackagesConfigContents: """
132
+ <?xml version="1.0" encoding="utf-8"?>
133
+ <packages>
134
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
135
+ </packages>
136
+ """,
137
+ expectedUpdateOperations: [
138
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
139
+ ]
140
+ );
141
+ }
142
+
143
+ [Fact]
144
+ public async Task UpdateDependency_NoAssembliesAndContentDirectoryDiffersByCase()
145
+ {
146
+ await TestAsync("Package.With.No.Assembly", "1.0.0", "1.1.0",
147
+ packages: [
148
+ // this package is expected to have a directory named `content`, but here it differs by case as `Content`
149
+ new MockNuGetPackage("Package.With.No.Assembly", "1.0.0", Files: [("Content/some-content.txt", [])]),
150
+ new MockNuGetPackage("Package.With.No.Assembly", "1.1.0", Files: [("Content/some-content.txt", [])]),
151
+ ],
152
+ projectContents: """
153
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
154
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
155
+ <PropertyGroup>
156
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
157
+ </PropertyGroup>
158
+ <ItemGroup>
159
+ <None Include="packages.config" />
160
+ </ItemGroup>
161
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
162
+ </Project>
163
+ """,
164
+ packagesConfigContents: """
165
+ <packages>
166
+ <package id="Package.With.No.Assembly" version="1.0.0" targetFramework="net45" />
167
+ </packages>
168
+ """,
169
+ expectedProjectContents: """
170
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
171
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
172
+ <PropertyGroup>
173
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
174
+ </PropertyGroup>
175
+ <ItemGroup>
176
+ <None Include="packages.config" />
177
+ </ItemGroup>
178
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
179
+ </Project>
180
+ """,
181
+ expectedPackagesConfigContents: """
182
+ <?xml version="1.0" encoding="utf-8"?>
183
+ <packages>
184
+ <package id="Package.With.No.Assembly" version="1.1.0" targetFramework="net45" />
185
+ </packages>
186
+ """,
187
+ expectedUpdateOperations: [
188
+ new DirectUpdate() { DependencyName = "Package.With.No.Assembly", NewVersion = NuGetVersion.Parse("1.1.0"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
189
+ ]
190
+ );
191
+ }
192
+
193
+ [Fact]
194
+ public async Task UpdatePackageWithTargetsFileWhereProjectUsesBackslashes()
195
+ {
196
+ // The bug that caused this test to be written did not repro on Windows. The reason is that the packages
197
+ // directory is determined to be `..\packages`, but the backslash was retained. Later when packages were
198
+ // restored to that location, a directory with a name like `..?packages` would be created which didn't
199
+ // match the <Import> element's path of "..\packages\..." that had no `Condition="Exists(path)"` attribute.
200
+ await TestAsync("Some.Package", "1.0.0", "2.0.0",
201
+ packages: [
202
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net45"),
203
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net45"),
204
+ new MockNuGetPackage("Package.With.Targets", "1.0.0", Files: [("build/SomeFile.targets", Encoding.UTF8.GetBytes("<Project />"))]),
205
+ ],
206
+ projectPath: "src/project.csproj",
207
+ projectContents: """
208
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
209
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
210
+ <PropertyGroup>
211
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
212
+ </PropertyGroup>
213
+ <ItemGroup>
214
+ <None Include="packages.config" />
215
+ </ItemGroup>
216
+ <ItemGroup>
217
+ <Reference Include="Some.Package">
218
+ <HintPath>..\packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
219
+ <Private>True</Private>
220
+ </Reference>
221
+ </ItemGroup>
222
+ <Import Project="..\packages\Package.With.Targets.1.0.0\build\SomeFile.targets" />
223
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
224
+ </Project>
225
+ """,
226
+ packagesConfigPath: "src/packages.config",
227
+ packagesConfigContents: """
228
+ <?xml version="1.0" encoding="utf-8"?>
229
+ <packages>
230
+ <package id="Package.With.Targets" version="1.0.0" targetFramework="net45" />
231
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
232
+ </packages>
233
+ """,
234
+ expectedProjectContents: """
235
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
236
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
237
+ <PropertyGroup>
238
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
239
+ </PropertyGroup>
240
+ <ItemGroup>
241
+ <None Include="packages.config" />
242
+ </ItemGroup>
243
+ <ItemGroup>
244
+ <Reference Include="Some.Package">
245
+ <HintPath>..\packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
246
+ <Private>True</Private>
247
+ </Reference>
248
+ </ItemGroup>
249
+ <Import Project="..\packages\Package.With.Targets.1.0.0\build\SomeFile.targets" />
250
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
251
+ </Project>
252
+ """,
253
+ expectedPackagesConfigContents: """
254
+ <?xml version="1.0" encoding="utf-8"?>
255
+ <packages>
256
+ <package id="Package.With.Targets" version="1.0.0" targetFramework="net45" />
257
+ <package id="Some.Package" version="2.0.0" targetFramework="net45" />
258
+ </packages>
259
+ """,
260
+ expectedUpdateOperations: [
261
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/src/project.csproj", "/src/packages.config"] },
262
+ ]
263
+ );
264
+ }
265
+
266
+ [Fact]
267
+ public async Task UpdatePackagesConfigWithNonStandardLocationOfPackagesDirectory()
268
+ {
269
+ // update Some.Package from 7.0.1 to 13.0.1 with the actual assembly in a non-standard location
270
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
271
+ packages: [
272
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
273
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net45"),
274
+ ],
275
+ projectContents: """
276
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
277
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
278
+ <PropertyGroup>
279
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
280
+ </PropertyGroup>
281
+ <ItemGroup>
282
+ <None Include="packages.config" />
283
+ </ItemGroup>
284
+ <ItemGroup>
285
+ <Reference Include="Some.Package">
286
+ <HintPath>some-non-standard-location\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
287
+ <Private>True</Private>
288
+ </Reference>
289
+ </ItemGroup>
290
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
291
+ </Project>
292
+ """,
293
+ packagesConfigContents: """
294
+ <packages>
295
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
296
+ </packages>
297
+ """,
298
+ expectedProjectContents: """
299
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
300
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
301
+ <PropertyGroup>
302
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
303
+ </PropertyGroup>
304
+ <ItemGroup>
305
+ <None Include="packages.config" />
306
+ </ItemGroup>
307
+ <ItemGroup>
308
+ <Reference Include="Some.Package">
309
+ <HintPath>some-non-standard-location\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
310
+ <Private>True</Private>
311
+ </Reference>
312
+ </ItemGroup>
313
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
314
+ </Project>
315
+ """,
316
+ expectedPackagesConfigContents: """
317
+ <?xml version="1.0" encoding="utf-8"?>
318
+ <packages>
319
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
320
+ </packages>
321
+ """,
322
+ expectedUpdateOperations: [
323
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
324
+ ]
325
+ );
326
+ }
327
+
328
+ [Fact]
329
+ public async Task UpdateBindingRedirectInAppConfig_UnrelatedBindingRedirectIsUntouched()
330
+ {
331
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
332
+ packages: [
333
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
334
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
335
+ MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
336
+ ],
337
+ projectContents: """
338
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
339
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
340
+ <PropertyGroup>
341
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
342
+ </PropertyGroup>
343
+ <ItemGroup>
344
+ <None Include="packages.config" />
345
+ </ItemGroup>
346
+ <ItemGroup>
347
+ <None Include="app.config" />
348
+ </ItemGroup>
349
+ <ItemGroup>
350
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
351
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
352
+ <Private>True</Private>
353
+ </Reference>
354
+ <Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
355
+ <HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
356
+ <Private>True</Private>
357
+ </Reference>
358
+ </ItemGroup>
359
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
360
+ </Project>
361
+ """,
362
+ packagesConfigContents: """
363
+ <packages>
364
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
365
+ </packages>
366
+ """,
367
+ additionalFiles:
368
+ [
369
+ ("app.config", """
370
+ <?xml version="1.0" encoding="utf-8"?>
371
+ <configuration>
372
+ <runtime>
373
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
374
+ <dependentAssembly>
375
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
376
+ <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
377
+ </dependentAssembly>
378
+ <dependentAssembly>
379
+ <assemblyIdentity name="Unrelated.Package" culture="neutral" />
380
+ <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
381
+ </dependentAssembly>
382
+ </assemblyBinding>
383
+ </runtime>
384
+ </configuration>
385
+ """)
386
+ ],
387
+ expectedProjectContents: """
388
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
389
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
390
+ <PropertyGroup>
391
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
392
+ </PropertyGroup>
393
+ <ItemGroup>
394
+ <None Include="packages.config" />
395
+ </ItemGroup>
396
+ <ItemGroup>
397
+ <None Include="app.config" />
398
+ </ItemGroup>
399
+ <ItemGroup>
400
+ <Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
401
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
402
+ <Private>True</Private>
403
+ </Reference>
404
+ <Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
405
+ <HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
406
+ <Private>True</Private>
407
+ </Reference>
408
+ </ItemGroup>
409
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
410
+ </Project>
411
+ """,
412
+ expectedPackagesConfigContents: """
413
+ <?xml version="1.0" encoding="utf-8"?>
414
+ <packages>
415
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
416
+ </packages>
417
+ """,
418
+ additionalFilesExpected:
419
+ [
420
+ ("app.config", """
421
+ <?xml version="1.0" encoding="utf-8"?>
422
+ <configuration>
423
+ <runtime>
424
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
425
+ <dependentAssembly>
426
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
427
+ <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
428
+ </dependentAssembly>
429
+ <dependentAssembly>
430
+ <assemblyIdentity name="Unrelated.Package" culture="neutral" />
431
+ <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
432
+ </dependentAssembly>
433
+ </assemblyBinding>
434
+ </runtime>
435
+ </configuration>
436
+ """)
437
+ ],
438
+ expectedUpdateOperations: [
439
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config", "/app.config"] },
440
+ ]
441
+ );
442
+ }
443
+
444
+ [Fact]
445
+ public async Task BindingRedirectIsAddedForUpdatedPackage()
446
+ {
447
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
448
+ packages: [
449
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
450
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
451
+ MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
452
+ ],
453
+ projectContents: """
454
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
455
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
456
+ <PropertyGroup>
457
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
458
+ </PropertyGroup>
459
+ <ItemGroup>
460
+ <None Include="packages.config" />
461
+ </ItemGroup>
462
+ <ItemGroup>
463
+ <None Include="app.config" />
464
+ </ItemGroup>
465
+ <ItemGroup>
466
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
467
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
468
+ <Private>True</Private>
469
+ </Reference>
470
+ <Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
471
+ <HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
472
+ <Private>True</Private>
473
+ </Reference>
474
+ </ItemGroup>
475
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
476
+ </Project>
477
+ """,
478
+ packagesConfigContents: """
479
+ <packages>
480
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
481
+ </packages>
482
+ """,
483
+ additionalFiles: [
484
+ ("app.config", """
485
+ <configuration>
486
+ <runtime />
487
+ </configuration>
488
+ """)
489
+ ],
490
+ expectedProjectContents: """
491
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
492
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
493
+ <PropertyGroup>
494
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
495
+ </PropertyGroup>
496
+ <ItemGroup>
497
+ <None Include="packages.config" />
498
+ </ItemGroup>
499
+ <ItemGroup>
500
+ <None Include="app.config" />
501
+ </ItemGroup>
502
+ <ItemGroup>
503
+ <Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
504
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
505
+ <Private>True</Private>
506
+ </Reference>
507
+ <Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
508
+ <HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
509
+ <Private>True</Private>
510
+ </Reference>
511
+ </ItemGroup>
512
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
513
+ </Project>
514
+ """,
515
+ expectedPackagesConfigContents: """
516
+ <?xml version="1.0" encoding="utf-8"?>
517
+ <packages>
518
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
519
+ </packages>
520
+ """,
521
+ additionalFilesExpected: [
522
+ ("app.config", """
523
+ <configuration>
524
+ <runtime>
525
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
526
+ <dependentAssembly>
527
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
528
+ <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
529
+ </dependentAssembly>
530
+ </assemblyBinding>
531
+ </runtime>
532
+ </configuration>
533
+ """)
534
+ ],
535
+ expectedUpdateOperations: [
536
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config", "/app.config"] },
537
+ ]
538
+ );
539
+ }
540
+
541
+ // the xml can take various shapes and they're all formatted, so we need very specific values here
542
+ [Theory]
543
+ [InlineData("<Content Include=\"web.config\" />")]
544
+ [InlineData("<Content Include=\"web.config\">\n </Content>")]
545
+ [InlineData("<Content Include=\"web.config\">\n <SubType>Designer</SubType>\n </Content>")]
546
+ public async Task UpdateBindingRedirectInWebConfig(string webConfigXml)
547
+ {
548
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
549
+ packages: [
550
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
551
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
552
+ ],
553
+ projectContents: $$"""
554
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
555
+ <PropertyGroup>
556
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
557
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
558
+ <ProductVersion>
559
+ </ProductVersion>
560
+ <SchemaVersion>2.0</SchemaVersion>
561
+ <ProjectGuid>ac83fc79-b637-445b-acb0-9be238ad077f</ProjectGuid>
562
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
563
+ <OutputType>Library</OutputType>
564
+ <AppDesignerFolder>Properties</AppDesignerFolder>
565
+ <RootNamespace>TestProject</RootNamespace>
566
+ <AssemblyName>TestProject</AssemblyName>
567
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
568
+ </PropertyGroup>
569
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
570
+ <DebugSymbols>true</DebugSymbols>
571
+ <DebugType>full</DebugType>
572
+ <Optimize>false</Optimize>
573
+ <OutputPath>bin\</OutputPath>
574
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
575
+ <ErrorReport>prompt</ErrorReport>
576
+ <WarningLevel>4</WarningLevel>
577
+ </PropertyGroup>
578
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
579
+ <DebugType>pdbonly</DebugType>
580
+ <Optimize>true</Optimize>
581
+ <OutputPath>bin\</OutputPath>
582
+ <DefineConstants>TRACE</DefineConstants>
583
+ <ErrorReport>prompt</ErrorReport>
584
+ <WarningLevel>4</WarningLevel>
585
+ </PropertyGroup>
586
+ <ItemGroup>
587
+ <Reference Include="Microsoft.CSharp" />
588
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
589
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
590
+ <Private>True</Private>
591
+ </Reference>
592
+ <Reference Include="System.Web.DynamicData" />
593
+ <Reference Include="System.Web.Entity" />
594
+ <Reference Include="System.Web.ApplicationServices" />
595
+ <Reference Include="System" />
596
+ <Reference Include="System.Data" />
597
+ <Reference Include="System.Core" />
598
+ <Reference Include="System.Data.DataSetExtensions" />
599
+ <Reference Include="System.Web.Extensions" />
600
+ <Reference Include="System.Xml.Linq" />
601
+ <Reference Include="System.Drawing" />
602
+ <Reference Include="System.Web" />
603
+ <Reference Include="System.Xml" />
604
+ <Reference Include="System.Configuration" />
605
+ <Reference Include="System.Web.Services" />
606
+ <Reference Include="System.EnterpriseServices" />
607
+ </ItemGroup>
608
+ <ItemGroup>
609
+ <None Include="packages.config" />
610
+ {{webConfigXml}}
611
+ <Content Include="web.Debug.config">
612
+ <DependentUpon>web.config</DependentUpon>
613
+ </Content>
614
+ <Content Include="web.Release.config">
615
+ <DependentUpon>web.config</DependentUpon>
616
+ </Content>
617
+ </ItemGroup>
618
+ <ItemGroup>
619
+ <Compile Include="Properties\AssemblyInfo.cs" />
620
+ </ItemGroup>
621
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
622
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
623
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
624
+ Other similar extension points exist, see Microsoft.Common.targets.
625
+ <Target Name="BeforeBuild">
626
+ </Target>
627
+ <Target Name="AfterBuild">
628
+ </Target>
629
+ -->
630
+ </Project>
631
+ """,
632
+ packagesConfigContents: """
633
+ <packages>
634
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
635
+ </packages>
636
+ """,
637
+ additionalFiles:
638
+ [
639
+ ("web.config", """
640
+ <configuration>
641
+ <runtime>
642
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
643
+ <dependentAssembly>
644
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
645
+ <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
646
+ </dependentAssembly>
647
+ </assemblyBinding>
648
+ </runtime>
649
+ </configuration>
650
+ """)
651
+ ],
652
+ expectedProjectContents: $$"""
653
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
654
+ <PropertyGroup>
655
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
656
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
657
+ <ProductVersion>
658
+ </ProductVersion>
659
+ <SchemaVersion>2.0</SchemaVersion>
660
+ <ProjectGuid>ac83fc79-b637-445b-acb0-9be238ad077f</ProjectGuid>
661
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
662
+ <OutputType>Library</OutputType>
663
+ <AppDesignerFolder>Properties</AppDesignerFolder>
664
+ <RootNamespace>TestProject</RootNamespace>
665
+ <AssemblyName>TestProject</AssemblyName>
666
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
667
+ </PropertyGroup>
668
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
669
+ <DebugSymbols>true</DebugSymbols>
670
+ <DebugType>full</DebugType>
671
+ <Optimize>false</Optimize>
672
+ <OutputPath>bin\</OutputPath>
673
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
674
+ <ErrorReport>prompt</ErrorReport>
675
+ <WarningLevel>4</WarningLevel>
676
+ </PropertyGroup>
677
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
678
+ <DebugType>pdbonly</DebugType>
679
+ <Optimize>true</Optimize>
680
+ <OutputPath>bin\</OutputPath>
681
+ <DefineConstants>TRACE</DefineConstants>
682
+ <ErrorReport>prompt</ErrorReport>
683
+ <WarningLevel>4</WarningLevel>
684
+ </PropertyGroup>
685
+ <ItemGroup>
686
+ <Reference Include="Microsoft.CSharp" />
687
+ <Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
688
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
689
+ <Private>True</Private>
690
+ </Reference>
691
+ <Reference Include="System.Web.DynamicData" />
692
+ <Reference Include="System.Web.Entity" />
693
+ <Reference Include="System.Web.ApplicationServices" />
694
+ <Reference Include="System" />
695
+ <Reference Include="System.Data" />
696
+ <Reference Include="System.Core" />
697
+ <Reference Include="System.Data.DataSetExtensions" />
698
+ <Reference Include="System.Web.Extensions" />
699
+ <Reference Include="System.Xml.Linq" />
700
+ <Reference Include="System.Drawing" />
701
+ <Reference Include="System.Web" />
702
+ <Reference Include="System.Xml" />
703
+ <Reference Include="System.Configuration" />
704
+ <Reference Include="System.Web.Services" />
705
+ <Reference Include="System.EnterpriseServices" />
706
+ </ItemGroup>
707
+ <ItemGroup>
708
+ <None Include="packages.config" />
709
+ {{webConfigXml}}
710
+ <Content Include="web.Debug.config">
711
+ <DependentUpon>web.config</DependentUpon>
712
+ </Content>
713
+ <Content Include="web.Release.config">
714
+ <DependentUpon>web.config</DependentUpon>
715
+ </Content>
716
+ </ItemGroup>
717
+ <ItemGroup>
718
+ <Compile Include="Properties\AssemblyInfo.cs" />
719
+ </ItemGroup>
720
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
721
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
722
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
723
+ Other similar extension points exist, see Microsoft.Common.targets.
724
+ <Target Name="BeforeBuild">
725
+ </Target>
726
+ <Target Name="AfterBuild">
727
+ </Target>
728
+ -->
729
+ </Project>
730
+ """,
731
+ expectedPackagesConfigContents: """
732
+ <?xml version="1.0" encoding="utf-8"?>
733
+ <packages>
734
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
735
+ </packages>
736
+ """,
737
+ additionalFilesExpected: [
738
+ ("web.config", """
739
+ <configuration>
740
+ <runtime>
741
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
742
+ <dependentAssembly>
743
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
744
+ <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
745
+ </dependentAssembly>
746
+ </assemblyBinding>
747
+ </runtime>
748
+ </configuration>
749
+ """)
750
+ ],
751
+ expectedUpdateOperations: [
752
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config", "/web.config"] },
753
+ ]
754
+ );
755
+ }
756
+
757
+ [Fact]
758
+ public async Task UpdateBindingRedirect_DuplicateRedirectsForTheSameAssemblyAreRemoved()
759
+ {
760
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
761
+ packages: [
762
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
763
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
764
+ ],
765
+ projectContents: """
766
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
767
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
768
+ <PropertyGroup>
769
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
770
+ </PropertyGroup>
771
+ <ItemGroup>
772
+ <None Include="packages.config" />
773
+ </ItemGroup>
774
+ <ItemGroup>
775
+ <None Include="app.config" />
776
+ </ItemGroup>
777
+ <ItemGroup>
778
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
779
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
780
+ <Private>True</Private>
781
+ </Reference>
782
+ </ItemGroup>
783
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
784
+ </Project>
785
+ """,
786
+ packagesConfigContents: """
787
+ <packages>
788
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
789
+ </packages>
790
+ """,
791
+ additionalFiles: [
792
+ ("app.config", """
793
+ <configuration>
794
+ <runtime>
795
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
796
+ <dependentAssembly>
797
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
798
+ <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
799
+ </dependentAssembly>
800
+ <dependentAssembly>
801
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
802
+ <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
803
+ </dependentAssembly>
804
+ </assemblyBinding>
805
+ </runtime>
806
+ </configuration>
807
+ """)
808
+ ],
809
+ expectedProjectContents: """
810
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
811
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
812
+ <PropertyGroup>
813
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
814
+ </PropertyGroup>
815
+ <ItemGroup>
816
+ <None Include="packages.config" />
817
+ </ItemGroup>
818
+ <ItemGroup>
819
+ <None Include="app.config" />
820
+ </ItemGroup>
821
+ <ItemGroup>
822
+ <Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
823
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
824
+ <Private>True</Private>
825
+ </Reference>
826
+ </ItemGroup>
827
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
828
+ </Project>
829
+ """,
830
+ expectedPackagesConfigContents: """
831
+ <?xml version="1.0" encoding="utf-8"?>
832
+ <packages>
833
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
834
+ </packages>
835
+ """,
836
+ additionalFilesExpected: [
837
+ ("app.config", """
838
+ <configuration>
839
+ <runtime>
840
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
841
+ <dependentAssembly>
842
+ <assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
843
+ <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
844
+ </dependentAssembly>
845
+ </assemblyBinding>
846
+ </runtime>
847
+ </configuration>
848
+ """)
849
+ ],
850
+ expectedUpdateOperations: [
851
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config", "/app.config"] },
852
+ ]
853
+ );
854
+ }
855
+
856
+ [Fact]
857
+ public async Task UpdateBindingRedirect_ExistingRedirectForAssemblyPublicKeyTokenDiffersByCase()
858
+ {
859
+ // Generated using "sn -k keypair.snk && sn -p keypair.snk public.snk" then converting public.snk to base64
860
+ // https://learn.microsoft.com/en-us/dotnet/standard/assembly/create-public-private-key-pair
861
+ var assemblyStrongNamePublicKey = Convert.FromBase64String(
862
+ "ACQAAASAAACUAAAABgIAAAAkAABSU0ExAAQAAAEAAQAJJW4hmKpxa9pU0JPDvJ9KqjvfQuMUovGtFjkZ9b0i1KQ/7kqEOjW3Va0eGpU7Kz0qHp14iYQ3SsMzBZU3mZ2Ezeqg+dCVuDk7o2lp++4m1FstHsebtXBetyOzWkneo+3iKSzOQ7bOXj2s5M9umqRPk+yj0ZBILf+HvfAd07iIuQ=="
863
+ ).ToImmutableArray();
864
+
865
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
866
+ packages: [
867
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0", assemblyPublicKey: assemblyStrongNamePublicKey),
868
+ MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0", assemblyPublicKey: assemblyStrongNamePublicKey),
869
+ ],
870
+ projectContents: """
871
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
872
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
873
+ <PropertyGroup>
874
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
875
+ </PropertyGroup>
876
+ <ItemGroup>
877
+ <None Include="packages.config" />
878
+ </ItemGroup>
879
+ <ItemGroup>
880
+ <None Include="app.config" />
881
+ </ItemGroup>
882
+ <ItemGroup>
883
+ <Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=13523fc3be375af1">
884
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
885
+ <Private>True</Private>
886
+ </Reference>
887
+ </ItemGroup>
888
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
889
+ </Project>
890
+ """,
891
+ packagesConfigContents: """
892
+ <packages>
893
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
894
+ </packages>
895
+ """,
896
+ additionalFiles: [
897
+ ("app.config", """
898
+ <configuration>
899
+ <runtime>
900
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
901
+ <dependentAssembly>
902
+ <assemblyIdentity name="Some.Package" publicKeyToken="13523FC3BE375AF1" culture="neutral" />
903
+ <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
904
+ </dependentAssembly>
905
+ </assemblyBinding>
906
+ </runtime>
907
+ </configuration>
908
+ """)
909
+ ],
910
+ expectedProjectContents: """
911
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
912
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
913
+ <PropertyGroup>
914
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
915
+ </PropertyGroup>
916
+ <ItemGroup>
917
+ <None Include="packages.config" />
918
+ </ItemGroup>
919
+ <ItemGroup>
920
+ <None Include="app.config" />
921
+ </ItemGroup>
922
+ <ItemGroup>
923
+ <Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=13523fc3be375af1">
924
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
925
+ <Private>True</Private>
926
+ </Reference>
927
+ </ItemGroup>
928
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
929
+ </Project>
930
+ """,
931
+ expectedPackagesConfigContents: """
932
+ <?xml version="1.0" encoding="utf-8"?>
933
+ <packages>
934
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
935
+ </packages>
936
+ """,
937
+ additionalFilesExpected: [
938
+ ("app.config", """
939
+ <configuration>
940
+ <runtime>
941
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
942
+ <dependentAssembly>
943
+ <assemblyIdentity name="Some.Package" publicKeyToken="13523FC3BE375AF1" culture="neutral" />
944
+ <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
945
+ </dependentAssembly>
946
+ </assemblyBinding>
947
+ </runtime>
948
+ </configuration>
949
+ """)
950
+ ],
951
+ expectedUpdateOperations: [
952
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config", "/app.config"] },
953
+ ]
954
+ );
955
+ }
956
+
957
+ [Fact]
958
+ public async Task PackagesConfigUpdateCanHappenEvenWithMismatchedVersionNumbers()
959
+ {
960
+ // `packages.config` reports `7.0.1` and that's what we want to update, but the project file has a mismatch that's corrected
961
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
962
+ packages: [
963
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
964
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net45"),
965
+ ],
966
+ projectContents: """
967
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
968
+ <PropertyGroup>
969
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
970
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
971
+ <ProductVersion>
972
+ </ProductVersion>
973
+ <SchemaVersion>2.0</SchemaVersion>
974
+ <ProjectGuid>ac83fc79-b637-445b-acb0-9be238ad077f</ProjectGuid>
975
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
976
+ <OutputType>Library</OutputType>
977
+ <AppDesignerFolder>Properties</AppDesignerFolder>
978
+ <RootNamespace>TestProject</RootNamespace>
979
+ <AssemblyName>TestProject</AssemblyName>
980
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
981
+ </PropertyGroup>
982
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
983
+ <DebugSymbols>true</DebugSymbols>
984
+ <DebugType>full</DebugType>
985
+ <Optimize>false</Optimize>
986
+ <OutputPath>bin\</OutputPath>
987
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
988
+ <ErrorReport>prompt</ErrorReport>
989
+ <WarningLevel>4</WarningLevel>
990
+ </PropertyGroup>
991
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
992
+ <DebugType>pdbonly</DebugType>
993
+ <Optimize>true</Optimize>
994
+ <OutputPath>bin\</OutputPath>
995
+ <DefineConstants>TRACE</DefineConstants>
996
+ <ErrorReport>prompt</ErrorReport>
997
+ <WarningLevel>4</WarningLevel>
998
+ </PropertyGroup>
999
+ <ItemGroup>
1000
+ <Reference Include="Microsoft.CSharp" />
1001
+ <Reference Include="Some.Package, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1002
+ <HintPath>packages\Some.Package.6.0.8\lib\net45\Some.Package.dll</HintPath>
1003
+ <Private>True</Private>
1004
+ </Reference>
1005
+ <Reference Include="System.Web.DynamicData" />
1006
+ <Reference Include="System.Web.Entity" />
1007
+ <Reference Include="System.Web.ApplicationServices" />
1008
+ <Reference Include="System" />
1009
+ <Reference Include="System.Data" />
1010
+ <Reference Include="System.Core" />
1011
+ <Reference Include="System.Data.DataSetExtensions" />
1012
+ <Reference Include="System.Web.Extensions" />
1013
+ <Reference Include="System.Xml.Linq" />
1014
+ <Reference Include="System.Drawing" />
1015
+ <Reference Include="System.Web" />
1016
+ <Reference Include="System.Xml" />
1017
+ <Reference Include="System.Configuration" />
1018
+ <Reference Include="System.Web.Services" />
1019
+ <Reference Include="System.EnterpriseServices" />
1020
+ </ItemGroup>
1021
+ <ItemGroup>
1022
+ <None Include="packages.config" />
1023
+ </ItemGroup>
1024
+ <ItemGroup>
1025
+ <Compile Include="Properties\AssemblyInfo.cs" />
1026
+ </ItemGroup>
1027
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
1028
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
1029
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
1030
+ Other similar extension points exist, see Microsoft.Common.targets.
1031
+ <Target Name="BeforeBuild">
1032
+ </Target>
1033
+ <Target Name="AfterBuild">
1034
+ </Target>
1035
+ -->
1036
+ </Project>
1037
+ """,
1038
+ packagesConfigContents: """
1039
+ <packages>
1040
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
1041
+ </packages>
1042
+ """,
1043
+ expectedProjectContents: """
1044
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1045
+ <PropertyGroup>
1046
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
1047
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
1048
+ <ProductVersion>
1049
+ </ProductVersion>
1050
+ <SchemaVersion>2.0</SchemaVersion>
1051
+ <ProjectGuid>ac83fc79-b637-445b-acb0-9be238ad077f</ProjectGuid>
1052
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
1053
+ <OutputType>Library</OutputType>
1054
+ <AppDesignerFolder>Properties</AppDesignerFolder>
1055
+ <RootNamespace>TestProject</RootNamespace>
1056
+ <AssemblyName>TestProject</AssemblyName>
1057
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1058
+ </PropertyGroup>
1059
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1060
+ <DebugSymbols>true</DebugSymbols>
1061
+ <DebugType>full</DebugType>
1062
+ <Optimize>false</Optimize>
1063
+ <OutputPath>bin\</OutputPath>
1064
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
1065
+ <ErrorReport>prompt</ErrorReport>
1066
+ <WarningLevel>4</WarningLevel>
1067
+ </PropertyGroup>
1068
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
1069
+ <DebugType>pdbonly</DebugType>
1070
+ <Optimize>true</Optimize>
1071
+ <OutputPath>bin\</OutputPath>
1072
+ <DefineConstants>TRACE</DefineConstants>
1073
+ <ErrorReport>prompt</ErrorReport>
1074
+ <WarningLevel>4</WarningLevel>
1075
+ </PropertyGroup>
1076
+ <ItemGroup>
1077
+ <Reference Include="Microsoft.CSharp" />
1078
+ <Reference Include="Some.Package">
1079
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
1080
+ <Private>True</Private>
1081
+ </Reference>
1082
+ <Reference Include="System.Web.DynamicData" />
1083
+ <Reference Include="System.Web.Entity" />
1084
+ <Reference Include="System.Web.ApplicationServices" />
1085
+ <Reference Include="System" />
1086
+ <Reference Include="System.Data" />
1087
+ <Reference Include="System.Core" />
1088
+ <Reference Include="System.Data.DataSetExtensions" />
1089
+ <Reference Include="System.Web.Extensions" />
1090
+ <Reference Include="System.Xml.Linq" />
1091
+ <Reference Include="System.Drawing" />
1092
+ <Reference Include="System.Web" />
1093
+ <Reference Include="System.Xml" />
1094
+ <Reference Include="System.Configuration" />
1095
+ <Reference Include="System.Web.Services" />
1096
+ <Reference Include="System.EnterpriseServices" />
1097
+ </ItemGroup>
1098
+ <ItemGroup>
1099
+ <None Include="packages.config" />
1100
+ </ItemGroup>
1101
+ <ItemGroup>
1102
+ <Compile Include="Properties\AssemblyInfo.cs" />
1103
+ </ItemGroup>
1104
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
1105
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
1106
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
1107
+ Other similar extension points exist, see Microsoft.Common.targets.
1108
+ <Target Name="BeforeBuild">
1109
+ </Target>
1110
+ <Target Name="AfterBuild">
1111
+ </Target>
1112
+ -->
1113
+ </Project>
1114
+ """,
1115
+ expectedPackagesConfigContents: """
1116
+ <?xml version="1.0" encoding="utf-8"?>
1117
+ <packages>
1118
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
1119
+ </packages>
1120
+ """,
1121
+ expectedUpdateOperations: [
1122
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
1123
+ ]
1124
+ );
1125
+ }
1126
+
1127
+ [Fact]
1128
+ public async Task WellKnownMissingTargetsFileThatIsExplicitlyImportedDoesNotPreventUpdate()
1129
+ {
1130
+ // the file `Microsoft.WebApplication.targets` is not present in the test or prod environment, but it is explicitly imported in the project file
1131
+ // the supplied `Condition` attribute is always true, so the import will always fail, but it should not prevent the update from happening
1132
+ await TestAsync("Some.Package", "7.0.1", "13.0.1",
1133
+ packages: [
1134
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
1135
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net45"),
1136
+ ],
1137
+ projectContents: """
1138
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1139
+ <PropertyGroup>
1140
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
1141
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
1142
+ <ProductVersion>
1143
+ </ProductVersion>
1144
+ <SchemaVersion>2.0</SchemaVersion>
1145
+ <ProjectGuid>68ed3303-52a0-47b8-a687-3abbb07530da</ProjectGuid>
1146
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
1147
+ <OutputType>Library</OutputType>
1148
+ <AppDesignerFolder>Properties</AppDesignerFolder>
1149
+ <RootNamespace>TestProject</RootNamespace>
1150
+ <AssemblyName>TestProject</AssemblyName>
1151
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1152
+ </PropertyGroup>
1153
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1154
+ <DebugSymbols>true</DebugSymbols>
1155
+ <DebugType>full</DebugType>
1156
+ <Optimize>false</Optimize>
1157
+ <OutputPath>bin\</OutputPath>
1158
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
1159
+ <ErrorReport>prompt</ErrorReport>
1160
+ <WarningLevel>4</WarningLevel>
1161
+ </PropertyGroup>
1162
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
1163
+ <DebugType>pdbonly</DebugType>
1164
+ <Optimize>true</Optimize>
1165
+ <OutputPath>bin\</OutputPath>
1166
+ <DefineConstants>TRACE</DefineConstants>
1167
+ <ErrorReport>prompt</ErrorReport>
1168
+ <WarningLevel>4</WarningLevel>
1169
+ </PropertyGroup>
1170
+ <ItemGroup>
1171
+ <Reference Include="Microsoft.CSharp" />
1172
+ <Reference Include="Some.Package">
1173
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
1174
+ <Private>True</Private>
1175
+ </Reference>
1176
+ <Reference Include="System.Web.DynamicData" />
1177
+ <Reference Include="System.Web.Entity" />
1178
+ <Reference Include="System.Web.ApplicationServices" />
1179
+ <Reference Include="System" />
1180
+ <Reference Include="System.Data" />
1181
+ <Reference Include="System.Core" />
1182
+ <Reference Include="System.Data.DataSetExtensions" />
1183
+ <Reference Include="System.Web.Extensions" />
1184
+ <Reference Include="System.Xml.Linq" />
1185
+ <Reference Include="System.Drawing" />
1186
+ <Reference Include="System.Web" />
1187
+ <Reference Include="System.Xml" />
1188
+ <Reference Include="System.Configuration" />
1189
+ <Reference Include="System.Web.Services" />
1190
+ <Reference Include="System.EnterpriseServices" />
1191
+ </ItemGroup>
1192
+ <ItemGroup>
1193
+ <None Include="packages.config" />
1194
+ </ItemGroup>
1195
+ <ItemGroup>
1196
+ <Compile Include="Properties\AssemblyInfo.cs" />
1197
+ </ItemGroup>
1198
+ <ItemGroup>
1199
+ <ProjectReference Include="other-project\other-project.csproj" />
1200
+ </ItemGroup>
1201
+ <PropertyGroup>
1202
+ <!-- some project files set this property which makes the Microsoft.WebApplication.targets import a few lines down always fail -->
1203
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">C:\some\path\that\does\not\exist</VSToolsPath>
1204
+ </PropertyGroup>
1205
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
1206
+ <Import Project="$(VSToolsPath)\SomeSubPath\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
1207
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
1208
+ Other similar extension points exist, see Microsoft.Common.targets.
1209
+ <Target Name="BeforeBuild">
1210
+ </Target>
1211
+ <Target Name="AfterBuild">
1212
+ </Target>
1213
+ -->
1214
+ </Project>
1215
+ """,
1216
+ packagesConfigContents: """
1217
+ <packages>
1218
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
1219
+ </packages>
1220
+ """,
1221
+ additionalFiles: [
1222
+ ("other-project/other-project.csproj", """
1223
+ <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1224
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1225
+ <PropertyGroup>
1226
+ <OutputType>Library</OutputType>
1227
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1228
+ </PropertyGroup>
1229
+ <Import Project="$(VSToolsPath)\SomeSubPath\WebApplications\Microsoft.WebApplication.targets" />
1230
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1231
+ </Project>
1232
+ """)
1233
+ ],
1234
+ expectedProjectContents: """
1235
+ <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1236
+ <PropertyGroup>
1237
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
1238
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
1239
+ <ProductVersion>
1240
+ </ProductVersion>
1241
+ <SchemaVersion>2.0</SchemaVersion>
1242
+ <ProjectGuid>68ed3303-52a0-47b8-a687-3abbb07530da</ProjectGuid>
1243
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
1244
+ <OutputType>Library</OutputType>
1245
+ <AppDesignerFolder>Properties</AppDesignerFolder>
1246
+ <RootNamespace>TestProject</RootNamespace>
1247
+ <AssemblyName>TestProject</AssemblyName>
1248
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1249
+ </PropertyGroup>
1250
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1251
+ <DebugSymbols>true</DebugSymbols>
1252
+ <DebugType>full</DebugType>
1253
+ <Optimize>false</Optimize>
1254
+ <OutputPath>bin\</OutputPath>
1255
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
1256
+ <ErrorReport>prompt</ErrorReport>
1257
+ <WarningLevel>4</WarningLevel>
1258
+ </PropertyGroup>
1259
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
1260
+ <DebugType>pdbonly</DebugType>
1261
+ <Optimize>true</Optimize>
1262
+ <OutputPath>bin\</OutputPath>
1263
+ <DefineConstants>TRACE</DefineConstants>
1264
+ <ErrorReport>prompt</ErrorReport>
1265
+ <WarningLevel>4</WarningLevel>
1266
+ </PropertyGroup>
1267
+ <ItemGroup>
1268
+ <Reference Include="Microsoft.CSharp" />
1269
+ <Reference Include="Some.Package">
1270
+ <HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
1271
+ <Private>True</Private>
1272
+ </Reference>
1273
+ <Reference Include="System.Web.DynamicData" />
1274
+ <Reference Include="System.Web.Entity" />
1275
+ <Reference Include="System.Web.ApplicationServices" />
1276
+ <Reference Include="System" />
1277
+ <Reference Include="System.Data" />
1278
+ <Reference Include="System.Core" />
1279
+ <Reference Include="System.Data.DataSetExtensions" />
1280
+ <Reference Include="System.Web.Extensions" />
1281
+ <Reference Include="System.Xml.Linq" />
1282
+ <Reference Include="System.Drawing" />
1283
+ <Reference Include="System.Web" />
1284
+ <Reference Include="System.Xml" />
1285
+ <Reference Include="System.Configuration" />
1286
+ <Reference Include="System.Web.Services" />
1287
+ <Reference Include="System.EnterpriseServices" />
1288
+ </ItemGroup>
1289
+ <ItemGroup>
1290
+ <None Include="packages.config" />
1291
+ </ItemGroup>
1292
+ <ItemGroup>
1293
+ <Compile Include="Properties\AssemblyInfo.cs" />
1294
+ </ItemGroup>
1295
+ <ItemGroup>
1296
+ <ProjectReference Include="other-project\other-project.csproj" />
1297
+ </ItemGroup>
1298
+ <PropertyGroup>
1299
+ <!-- some project files set this property which makes the Microsoft.WebApplication.targets import a few lines down always fail -->
1300
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">C:\some\path\that\does\not\exist</VSToolsPath>
1301
+ </PropertyGroup>
1302
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
1303
+ <Import Project="$(VSToolsPath)\SomeSubPath\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
1304
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
1305
+ Other similar extension points exist, see Microsoft.Common.targets.
1306
+ <Target Name="BeforeBuild">
1307
+ </Target>
1308
+ <Target Name="AfterBuild">
1309
+ </Target>
1310
+ -->
1311
+ </Project>
1312
+ """,
1313
+ expectedPackagesConfigContents: """
1314
+ <?xml version="1.0" encoding="utf-8"?>
1315
+ <packages>
1316
+ <package id="Some.Package" version="13.0.1" targetFramework="net45" />
1317
+ </packages>
1318
+ """,
1319
+ expectedUpdateOperations: [
1320
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("13.0.1"), UpdatedFiles = ["/project.csproj", "/packages.config"] },
1321
+ ]
1322
+ );
1323
+ }
1324
+
1325
+ [Fact]
1326
+ public async Task PackageCanBeUpdatedWhenAnotherInstalledPackageHasBeenDelisted()
1327
+ {
1328
+ // updating one package (Some.Package) when another installed package (Delisted.Package/5.0.0) has been delisted
1329
+ // this test can't be faked with a local package source and requires an HTTP endpoint; the important part is
1330
+ // the `"listed": false` in the registration index
1331
+ static (int, byte[]) TestHttpHandler(string uriString)
1332
+ {
1333
+ var uri = new Uri(uriString, UriKind.Absolute);
1334
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
1335
+ return uri.PathAndQuery switch
1336
+ {
1337
+ "/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1338
+ {
1339
+ "version": "3.0.0",
1340
+ "resources": [
1341
+ {
1342
+ "@id": "{{baseUrl}}/download",
1343
+ "@type": "PackageBaseAddress/3.0.0"
1344
+ },
1345
+ {
1346
+ "@id": "{{baseUrl}}/query",
1347
+ "@type": "SearchQueryService"
1348
+ },
1349
+ {
1350
+ "@id": "{{baseUrl}}/registrations",
1351
+ "@type": "RegistrationsBaseUrl"
1352
+ }
1353
+ ]
1354
+ }
1355
+ """)),
1356
+ "/registrations/delisted.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1357
+ {
1358
+ "count": 1,
1359
+ "items": [
1360
+ {
1361
+ "lower": "5.0.0",
1362
+ "upper": "5.0.0",
1363
+ "items": [
1364
+ {
1365
+ "catalogEntry": {
1366
+ "id": "Delisted.Package",
1367
+ "listed": false,
1368
+ "version": "5.0.0"
1369
+ },
1370
+ "packageContent": "{{baseUrl}}/download/delisted.package/5.0.0/delisted.package.5.0.0.nupkg",
1371
+ }
1372
+ ]
1373
+ }
1374
+ ]
1375
+ }
1376
+ """)),
1377
+ "/registrations/some.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1378
+ {
1379
+ "count": 1,
1380
+ "items": [
1381
+ {
1382
+ "lower": "1.0.0",
1383
+ "upper": "2.0.0",
1384
+ "items": [
1385
+ {
1386
+ "catalogEntry": {
1387
+ "id": "Some.Package",
1388
+ "listed": true,
1389
+ "version": "1.0.0"
1390
+ },
1391
+ "packageContent": "{{baseUrl}}/download/some.package/1.0.0/some.package.1.0.0.nupkg",
1392
+ },
1393
+ {
1394
+ "catalogEntry": {
1395
+ "id": "Some.Package",
1396
+ "listed": true,
1397
+ "version": "2.0.0"
1398
+ },
1399
+ "packageContent": "{{baseUrl}}/download/some.package/2.0.0/some.package.2.0.0.nupkg",
1400
+ }
1401
+ ]
1402
+ }
1403
+ ]
1404
+ }
1405
+ """)),
1406
+ "/download/delisted.package/5.0.0/delisted.package.5.0.0.nupkg" =>
1407
+ (200, MockNuGetPackage.CreateSimplePackage("Delisted.Package", "5.0.0", "net45").GetZipStream().ReadAllBytes()),
1408
+ "/download/some.package/1.0.0/some.package.1.0.0.nupkg" =>
1409
+ (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net45").GetZipStream().ReadAllBytes()),
1410
+ "/download/some.package/2.0.0/some.package.2.0.0.nupkg" =>
1411
+ (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net45").GetZipStream().ReadAllBytes()),
1412
+ _ => (404, Encoding.UTF8.GetBytes("{}")), // everything is missing
1413
+ };
1414
+ }
1415
+ using var cache = new TemporaryDirectory();
1416
+ using var http = TestHttpServer.CreateTestServer(TestHttpHandler);
1417
+ await TestAsync("Some.Package", "1.0.0", "2.0.0",
1418
+ projectContents: """
1419
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1420
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1421
+ <PropertyGroup>
1422
+ <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1423
+ </PropertyGroup>
1424
+ <ItemGroup>
1425
+ <None Include="packages.config" />
1426
+ </ItemGroup>
1427
+ <ItemGroup>
1428
+ <Reference Include="Delisted.Package">
1429
+ <HintPath>packages\Delisted.Package.5.0.0\lib\net45\Delisted.Package.dll</HintPath>
1430
+ <Private>True</Private>
1431
+ </Reference>
1432
+ <Reference Include="Some.Package">
1433
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1434
+ <Private>True</Private>
1435
+ </Reference>
1436
+ </ItemGroup>
1437
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1438
+ </Project>
1439
+ """,
1440
+ packagesConfigContents: """
1441
+ <packages>
1442
+ <package id="Delisted.Package" version="5.0.0" targetFramework="net462" />
1443
+ <package id="Some.Package" version="1.0.0" targetFramework="net462" />
1444
+ </packages>
1445
+ """,
1446
+ additionalFiles:
1447
+ [
1448
+ ("NuGet.Config", $"""
1449
+ <configuration>
1450
+ <packageSources>
1451
+ <clear />
1452
+ <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
1453
+ </packageSources>
1454
+ </configuration>
1455
+ """)
1456
+ ],
1457
+ expectedProjectContents: """
1458
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1459
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1460
+ <PropertyGroup>
1461
+ <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1462
+ </PropertyGroup>
1463
+ <ItemGroup>
1464
+ <None Include="packages.config" />
1465
+ </ItemGroup>
1466
+ <ItemGroup>
1467
+ <Reference Include="Delisted.Package">
1468
+ <HintPath>packages\Delisted.Package.5.0.0\lib\net45\Delisted.Package.dll</HintPath>
1469
+ <Private>True</Private>
1470
+ </Reference>
1471
+ <Reference Include="Some.Package">
1472
+ <HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
1473
+ <Private>True</Private>
1474
+ </Reference>
1475
+ </ItemGroup>
1476
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1477
+ </Project>
1478
+ """,
1479
+ expectedPackagesConfigContents: """
1480
+ <?xml version="1.0" encoding="utf-8"?>
1481
+ <packages>
1482
+ <package id="Delisted.Package" version="5.0.0" targetFramework="net462" />
1483
+ <package id="Some.Package" version="2.0.0" targetFramework="net462" />
1484
+ </packages>
1485
+ """,
1486
+ expectedUpdateOperations: [
1487
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/project.csproj", "/packages.config"] }
1488
+ ]
1489
+ );
1490
+ }
1491
+
1492
+ [Fact]
1493
+ public async Task MissingTargetsAreReported()
1494
+ {
1495
+ // arrange
1496
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(
1497
+ [
1498
+ ("project.csproj", """
1499
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1500
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1501
+ <Import Project="this.file.does.not.exist.targets" />
1502
+ <PropertyGroup>
1503
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1504
+ </PropertyGroup>
1505
+ <ItemGroup>
1506
+ <None Include="packages.config" />
1507
+ </ItemGroup>
1508
+ <ItemGroup>
1509
+ <Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1510
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1511
+ <Private>True</Private>
1512
+ </Reference>
1513
+ </ItemGroup>
1514
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1515
+ </Project>
1516
+ """),
1517
+ ("packages.config", """
1518
+ <packages>
1519
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
1520
+ </packages>
1521
+ """),
1522
+ ("NuGet.Config", """
1523
+ <configuration>
1524
+ <packageSources>
1525
+ <clear />
1526
+ <add key="private_feed" value="packages" />
1527
+ </packageSources>
1528
+ </configuration>
1529
+ """)
1530
+ ]
1531
+ );
1532
+ var packages = new[] {
1533
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net45"),
1534
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", "net45"),
1535
+ };
1536
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, temporaryDirectory.DirectoryPath);
1537
+
1538
+ // act
1539
+ var fileNotFoundException = await Assert.ThrowsAsync<MissingFileException>(() => PackagesConfigUpdater.UpdateDependencyAsync(
1540
+ temporaryDirectory.DirectoryPath,
1541
+ Path.Join(temporaryDirectory.DirectoryPath, "project.csproj"),
1542
+ "Some.Package",
1543
+ "1.0.0",
1544
+ "1.1.0",
1545
+ Path.Join(temporaryDirectory.DirectoryPath, "packages.config"),
1546
+ new TestLogger()
1547
+ ));
1548
+
1549
+ // assert
1550
+ var error = JobErrorBase.ErrorFromException(fileNotFoundException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1551
+ var fileNotFound = Assert.IsType<DependencyFileNotFound>(error);
1552
+ var filePath = Assert.IsType<string>(fileNotFound.Details["file-path"]);
1553
+ Assert.Equal(Path.Combine(temporaryDirectory.DirectoryPath, "this.file.does.not.exist.targets").NormalizePathToUnix(), filePath);
1554
+ }
1555
+
1556
+ [Fact]
1557
+ public async Task MissingVisualStudioComponentTargetsAreReportedAsMissingFiles()
1558
+ {
1559
+ // arrange
1560
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(
1561
+ [
1562
+ ("project.csproj", """
1563
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1564
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1565
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Some.Visual.Studio.Component.props" />
1566
+ <PropertyGroup>
1567
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1568
+ </PropertyGroup>
1569
+ <ItemGroup>
1570
+ <None Include="packages.config" />
1571
+ </ItemGroup>
1572
+ <ItemGroup>
1573
+ <Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1574
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1575
+ <Private>True</Private>
1576
+ </Reference>
1577
+ </ItemGroup>
1578
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1579
+ </Project>
1580
+ """),
1581
+ ("packages.config", """
1582
+ <packages>
1583
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
1584
+ </packages>
1585
+ """),
1586
+ ("NuGet.Config", """
1587
+ <configuration>
1588
+ <packageSources>
1589
+ <clear />
1590
+ <add key="private_feed" value="packages" />
1591
+ </packageSources>
1592
+ </configuration>
1593
+ """)
1594
+ ]
1595
+ );
1596
+ var packages = new[]
1597
+ {
1598
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net45"),
1599
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", "net45"),
1600
+ };
1601
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, temporaryDirectory.DirectoryPath);
1602
+
1603
+ // act
1604
+ var fileNotFoundException = await Assert.ThrowsAsync<MissingFileException>(() => PackagesConfigUpdater.UpdateDependencyAsync(
1605
+ temporaryDirectory.DirectoryPath,
1606
+ Path.Join(temporaryDirectory.DirectoryPath, "project.csproj"),
1607
+ "Some.Package",
1608
+ "1.0.0",
1609
+ "1.1.0",
1610
+ Path.Join(temporaryDirectory.DirectoryPath, "packages.config"),
1611
+ new TestLogger()
1612
+ ));
1613
+
1614
+ // assert
1615
+ var error = JobErrorBase.ErrorFromException(fileNotFoundException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1616
+ var fileNotFound = Assert.IsType<DependencyFileNotFound>(error);
1617
+ var filePath = Assert.IsType<string>(fileNotFound.Details["file-path"]);
1618
+ Assert.Equal("$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v$(VisualStudioVersion)/Some.Visual.Studio.Component.props", filePath);
1619
+ }
1620
+
1621
+ [Theory]
1622
+ [InlineData(401)]
1623
+ [InlineData(403)]
1624
+ public async Task ReportsPrivateSourceAuthenticationFailure(int httpStatusCode)
1625
+ {
1626
+ // arrange
1627
+ (int, string) TestHttpHandler(string uriString)
1628
+ {
1629
+ var uri = new Uri(uriString, UriKind.Absolute);
1630
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
1631
+ return uri.PathAndQuery switch
1632
+ {
1633
+ _ => (httpStatusCode, "{}"), // everything is unauthorized
1634
+ };
1635
+ }
1636
+ using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
1637
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(
1638
+ [
1639
+ ("project.csproj", """
1640
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1641
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1642
+ <PropertyGroup>
1643
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1644
+ </PropertyGroup>
1645
+ <ItemGroup>
1646
+ <None Include="packages.config" />
1647
+ </ItemGroup>
1648
+ <ItemGroup>
1649
+ <Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1650
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1651
+ <Private>True</Private>
1652
+ </Reference>
1653
+ </ItemGroup>
1654
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1655
+ </Project>
1656
+ """),
1657
+ ("packages.config", """
1658
+ <packages>
1659
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
1660
+ </packages>
1661
+ """),
1662
+ ("NuGet.Config", $"""
1663
+ <configuration>
1664
+ <packageSources>
1665
+ <clear />
1666
+ <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
1667
+ </packageSources>
1668
+ </configuration>
1669
+ """)
1670
+ ]
1671
+ );
1672
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory([], Path.Combine(temporaryDirectory.DirectoryPath, "packages"));
1673
+
1674
+ // act
1675
+ var requestException = await Assert.ThrowsAsync<HttpRequestException>(() => PackagesConfigUpdater.UpdateDependencyAsync(
1676
+ temporaryDirectory.DirectoryPath,
1677
+ Path.Join(temporaryDirectory.DirectoryPath, "project.csproj"),
1678
+ "Some.Package",
1679
+ "1.0.0",
1680
+ "1.1.0",
1681
+ Path.Join(temporaryDirectory.DirectoryPath, "packages.config"),
1682
+ new TestLogger()
1683
+ ));
1684
+
1685
+ // assert
1686
+ var error = JobErrorBase.ErrorFromException(requestException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1687
+ var privateSourceAuthError = Assert.IsType<PrivateSourceAuthenticationFailure>(error);
1688
+ var urls = Assert.IsType<string>(privateSourceAuthError.Details["source"]);
1689
+ Assert.Equal($"({http.BaseUrl.TrimEnd('/')}/index.json)", urls);
1690
+ }
1691
+
1692
+ [Fact]
1693
+ public async Task ReportsUnexpectedResponseFromNuGetServer()
1694
+ {
1695
+ // arrange
1696
+ static (int, string) TestHttpHandler(string uriString)
1697
+ {
1698
+ var uri = new Uri(uriString, UriKind.Absolute);
1699
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
1700
+ return uri.PathAndQuery switch
1701
+ {
1702
+ // initial and search query are good, update should be possible...
1703
+ "/index.json" => (200, $$"""
1704
+ {
1705
+ "version": "3.0.0",
1706
+ "resources": [
1707
+ {
1708
+ "@id": "{{baseUrl}}/download",
1709
+ "@type": "PackageBaseAddress/3.0.0"
1710
+ },
1711
+ {
1712
+ "@id": "{{baseUrl}}/query",
1713
+ "@type": "SearchQueryService"
1714
+ },
1715
+ {
1716
+ "@id": "{{baseUrl}}/registrations",
1717
+ "@type": "RegistrationsBaseUrl"
1718
+ }
1719
+ ]
1720
+ }
1721
+ """),
1722
+ "/registrations/some.package/index.json" => (200, $$"""
1723
+ {
1724
+ "count": 1,
1725
+ "items": [
1726
+ {
1727
+ "lower": "1.0.0",
1728
+ "upper": "1.1.0",
1729
+ "items": [
1730
+ {
1731
+ "catalogEntry": {
1732
+ "id": "Some.Package",
1733
+ "listed": true,
1734
+ "version": "1.0.0"
1735
+ },
1736
+ "packageContent": "{{baseUrl}}/download/some.package/1.0.0/some.package.1.0.0.nupkg",
1737
+ },
1738
+ {
1739
+ "catalogEntry": {
1740
+ "id": "Some.Package",
1741
+ "listed": true,
1742
+ "version": "1.1.0"
1743
+ },
1744
+ "packageContent": "{{baseUrl}}/download/some.package/1.1.0/some.package.1.1.0.nupkg",
1745
+ }
1746
+ ]
1747
+ }
1748
+ ]
1749
+ }
1750
+ """),
1751
+ // ...but all other calls to the server fail
1752
+ _ => (500, "{}"),
1753
+ };
1754
+ }
1755
+ using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
1756
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(
1757
+ [
1758
+ ("project.csproj", """
1759
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1760
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1761
+ <PropertyGroup>
1762
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1763
+ </PropertyGroup>
1764
+ <ItemGroup>
1765
+ <None Include="packages.config" />
1766
+ </ItemGroup>
1767
+ <ItemGroup>
1768
+ <Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1769
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1770
+ <Private>True</Private>
1771
+ </Reference>
1772
+ </ItemGroup>
1773
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1774
+ </Project>
1775
+ """),
1776
+ ("packages.config", """
1777
+ <packages>
1778
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
1779
+ </packages>
1780
+ """),
1781
+ ("NuGet.Config", $"""
1782
+ <configuration>
1783
+ <packageSources>
1784
+ <clear />
1785
+ <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
1786
+ </packageSources>
1787
+ </configuration>
1788
+ """)
1789
+ ]
1790
+ );
1791
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory([], Path.Combine(temporaryDirectory.DirectoryPath, "packages"));
1792
+
1793
+ // act
1794
+ var requestException = await Assert.ThrowsAsync<HttpRequestException>(() => PackagesConfigUpdater.UpdateDependencyAsync(
1795
+ temporaryDirectory.DirectoryPath,
1796
+ Path.Join(temporaryDirectory.DirectoryPath, "project.csproj"),
1797
+ "Some.Package",
1798
+ "1.0.0",
1799
+ "1.1.0",
1800
+ Path.Join(temporaryDirectory.DirectoryPath, "packages.config"),
1801
+ new TestLogger()
1802
+ ));
1803
+
1804
+ // assert
1805
+ var error = JobErrorBase.ErrorFromException(requestException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1806
+ var badResponse = Assert.IsType<PrivateSourceBadResponse>(error);
1807
+ var urls = Assert.IsType<string>(badResponse.Details["source"]);
1808
+ Assert.Equal($"({http.BaseUrl.TrimEnd('/')}/index.json)", urls);
1809
+ }
1810
+
1811
+ [Fact]
1812
+ public async Task MissingDependencyErrorIsReported()
1813
+ {
1814
+ // trying to update Some.Package from 1.0.1 to 1.0.2, but another package isn't available; update fails
1815
+ // arrange
1816
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync(
1817
+ [
1818
+ ("project.csproj", """
1819
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1820
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1821
+ <PropertyGroup>
1822
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1823
+ </PropertyGroup>
1824
+ <ItemGroup>
1825
+ <None Include="packages.config" />
1826
+ </ItemGroup>
1827
+ <ItemGroup>
1828
+ <Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1829
+ <HintPath>packages\Some.Package.1.0.1\lib\net45\Some.Package.dll</HintPath>
1830
+ <Private>True</Private>
1831
+ </Reference>
1832
+ <Reference Include="Unrelated.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1833
+ <HintPath>packages\Unrelated.Package.1.0.0\lib\net45\Unrelated.Package.dll</HintPath>
1834
+ <Private>True</Private>
1835
+ </Reference>
1836
+ </ItemGroup>
1837
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1838
+ </Project>
1839
+ """),
1840
+ ("packages.config", """
1841
+ <packages>
1842
+ <package id="Some.Package" version="1.0.1" targetFramework="net45" />
1843
+ <package id="Unrelated.Package" version="1.0.0" targetFramework="net45" />
1844
+ </packages>
1845
+ """)
1846
+ ]
1847
+ );
1848
+ var packages = new[]
1849
+ {
1850
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net45"),
1851
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.2", "net45"),
1852
+ // the package `Unrelated.Package/1.0.0` is missing and will cause the update to fail
1853
+ };
1854
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, temporaryDirectory.DirectoryPath);
1855
+
1856
+ // act
1857
+ var notFoundException = await Assert.ThrowsAsync<DependencyNotFoundException>(() => PackagesConfigUpdater.UpdateDependencyAsync(
1858
+ temporaryDirectory.DirectoryPath,
1859
+ Path.Join(temporaryDirectory.DirectoryPath, "project.csproj"),
1860
+ "Some.Package",
1861
+ "1.0.1",
1862
+ "1.0.2",
1863
+ Path.Join(temporaryDirectory.DirectoryPath, "packages.config"),
1864
+ new TestLogger()
1865
+ ));
1866
+
1867
+ // assert
1868
+ var error = JobErrorBase.ErrorFromException(notFoundException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1869
+ var notFound = Assert.IsType<DependencyNotFound>(error);
1870
+ var depName = Assert.IsType<string>(notFound.Details["source"]);
1871
+ Assert.Equal("Unrelated.Package", depName);
1872
+ }
1873
+
7
1874
  [Theory]
8
1875
  [MemberData(nameof(PackagesDirectoryPathTestData))]
9
1876
  public async Task PathToPackagesDirectoryCanBeDetermined(string projectContents, string? packagesConfigContents, string dependencyName, string dependencyVersion, string expectedPackagesDirectoryPath)
@@ -13,7 +1880,7 @@ public class PackagesConfigUpdaterTests : TestBase
13
1880
  if (packagesConfigContents is not null)
14
1881
  {
15
1882
  packagesConfigPath = Path.Join(tempDir.DirectoryPath, "packages.config");
16
- await File.WriteAllTextAsync(packagesConfigPath, packagesConfigContents);
1883
+ await File.WriteAllTextAsync(packagesConfigPath, packagesConfigContents, TestContext.Current.CancellationToken);
17
1884
  }
18
1885
 
19
1886
  var projectBuildFile = ProjectBuildFile.Parse("/", "project.csproj", projectContents);
@@ -193,5 +2060,98 @@ public class PackagesConfigUpdaterTests : TestBase
193
2060
  // expected packages directory path
194
2061
  "../packages"
195
2062
  ];
2063
+
2064
+ // package has no assembly version
2065
+ yield return
2066
+ [
2067
+ // project contents
2068
+ """
2069
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2070
+ <ItemGroup>
2071
+ <Reference Include="Some.Package">
2072
+ <HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
2073
+ <Private>True</Private>
2074
+ </Reference>
2075
+ </ItemGroup>
2076
+ </Project>
2077
+ """,
2078
+ // packages.config contents
2079
+ """
2080
+ <packages>
2081
+ <package id="Some.Package" version="7.0.1" targetFramework="net45" />
2082
+ </packages>
2083
+ """,
2084
+ // dependency name
2085
+ "Some.Package",
2086
+ // dependency version
2087
+ "7.0.1",
2088
+ // expected packages directory path
2089
+ "packages"
2090
+ ];
2091
+ }
2092
+
2093
+ private static async Task TestAsync(
2094
+ string dependencyName,
2095
+ string previousDependencyVersion,
2096
+ string newDependencyVersion,
2097
+ string projectContents,
2098
+ string packagesConfigContents,
2099
+ string expectedProjectContents,
2100
+ string expectedPackagesConfigContents,
2101
+ ImmutableArray<UpdateOperationBase> expectedUpdateOperations,
2102
+ (string Path, string Content)[]? additionalFiles = null,
2103
+ (string Path, string Content)[]? additionalFilesExpected = null,
2104
+ string projectPath = "project.csproj",
2105
+ string packagesConfigPath = "packages.config",
2106
+ MockNuGetPackage[]? packages = null
2107
+ )
2108
+ {
2109
+ // arrange
2110
+ var allFiles = new List<(string Path, string Content)>
2111
+ {
2112
+ (projectPath, projectContents),
2113
+ (packagesConfigPath, packagesConfigContents)
2114
+ };
2115
+ allFiles.AddRange(additionalFiles ?? []);
2116
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync([.. allFiles]);
2117
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDir.DirectoryPath);
2118
+ var logger = new TestLogger();
2119
+
2120
+ // act
2121
+ var updateOperations = await PackagesConfigUpdater.UpdateDependencyAsync(
2122
+ tempDir.DirectoryPath,
2123
+ Path.Join(tempDir.DirectoryPath, projectPath),
2124
+ dependencyName,
2125
+ previousDependencyVersion,
2126
+ newDependencyVersion,
2127
+ Path.Join(tempDir.DirectoryPath, packagesConfigPath),
2128
+ logger
2129
+ );
2130
+
2131
+ // assert
2132
+ var expectedFilePaths = new[] { projectPath, packagesConfigPath }
2133
+ .Concat(additionalFilesExpected?.Select(f => f.Path) ?? [])
2134
+ .ToHashSet(StringComparer.OrdinalIgnoreCase);
2135
+ var actualFiles = await tempDir.ReadFileContentsAsync(expectedFilePaths);
2136
+ foreach (var expectedFilePath in expectedFilePaths)
2137
+ {
2138
+ var expectedFileContent = await File.ReadAllTextAsync(Path.Join(tempDir.DirectoryPath, expectedFilePath));
2139
+ var actualFile = actualFiles.FirstOrDefault(f => f.Path.Equals(expectedFilePath, StringComparison.OrdinalIgnoreCase));
2140
+ if (actualFile != default)
2141
+ {
2142
+ Assert.Equal(expectedFileContent.Replace("\r", ""), actualFile.Contents.Replace("\r", ""));
2143
+ }
2144
+ else
2145
+ {
2146
+ Assert.Fail($"Unexpected file found: {actualFile.Path}");
2147
+ }
2148
+ }
2149
+
2150
+ var actualUpdateOperationsJson = updateOperations
2151
+ .Select(u => u with { UpdatedFiles = [.. u.UpdatedFiles.Select(f => Path.GetRelativePath(tempDir.DirectoryPath, f).FullyNormalizedRootedPath())] })
2152
+ .Select(u => JsonSerializer.Serialize(u, RunWorker.SerializerOptions))
2153
+ .ToImmutableArray();
2154
+ var expectedUpdateOperationsJson = expectedUpdateOperations.Select(u => JsonSerializer.Serialize(u, RunWorker.SerializerOptions)).ToImmutableArray();
2155
+ AssertEx.Equal(expectedUpdateOperationsJson, actualUpdateOperationsJson);
196
2156
  }
197
2157
  }