dependabot-nuget 0.264.0 → 0.266.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +6 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalysisResult.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +73 -77
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +21 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +24 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +33 -16
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +44 -25
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NativeResult.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +18 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationResult.cs +5 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +62 -22
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +19 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +6 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +448 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/CompatibilityCheckerTests.cs +23 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +148 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +81 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +27 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +32 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +87 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +88 -0
- data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -0
- data/lib/dependabot/nuget/file_fetcher.rb +1 -1
- data/lib/dependabot/nuget/metadata_finder.rb +160 -2
- data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +3 -0
- data/lib/dependabot/nuget/native_helpers.rb +34 -3
- data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +1 -0
- data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +3 -0
- metadata +11 -7
@@ -142,4 +142,27 @@ public class CompatibilityCheckerTests
|
|
142
142
|
|
143
143
|
Assert.False(result);
|
144
144
|
}
|
145
|
+
|
146
|
+
[Theory]
|
147
|
+
[InlineData("netstandard2.0")]
|
148
|
+
[InlineData("net472")]
|
149
|
+
[InlineData("net6.0")]
|
150
|
+
[InlineData("net7.0")]
|
151
|
+
[InlineData("net8.0")]
|
152
|
+
public void EverythingIsCompatibleWithAnyVersion0Framework(string projectFramework)
|
153
|
+
{
|
154
|
+
var package = new PackageIdentity("Dependency", NuGetVersion.Parse("1.0.0"));
|
155
|
+
ImmutableArray<NuGetFramework> projectFrameworks = [NuGetFramework.Parse(projectFramework)];
|
156
|
+
var isDevDependency = false;
|
157
|
+
ImmutableArray<NuGetFramework> packageFrameworks = [NuGetFramework.Parse("Any,Version=v0.0")];
|
158
|
+
|
159
|
+
var result = CompatibilityChecker.PerformCheck(
|
160
|
+
package,
|
161
|
+
projectFrameworks,
|
162
|
+
isDevDependency,
|
163
|
+
packageFrameworks,
|
164
|
+
new Logger(verbose: false));
|
165
|
+
|
166
|
+
Assert.True(result);
|
167
|
+
}
|
145
168
|
}
|
@@ -40,6 +40,8 @@ public class DiscoveryWorkerTestBase
|
|
40
40
|
ValidateResultWithDependencies(expectedResult.DotNetToolsJson, actualResult.DotNetToolsJson);
|
41
41
|
ValidateProjectResults(expectedResult.Projects, actualResult.Projects);
|
42
42
|
Assert.Equal(expectedResult.ExpectedProjectCount ?? expectedResult.Projects.Length, actualResult.Projects.Length);
|
43
|
+
Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
|
44
|
+
Assert.Equal(expectedResult.ErrorDetails, actualResult.ErrorDetails);
|
43
45
|
|
44
46
|
return;
|
45
47
|
|
@@ -1,3 +1,7 @@
|
|
1
|
+
using System.Text.Json;
|
2
|
+
|
3
|
+
using NuGetUpdater.Core.Discover;
|
4
|
+
|
1
5
|
using Xunit;
|
2
6
|
|
3
7
|
namespace NuGetUpdater.Core.Test.Discover;
|
@@ -55,6 +59,54 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
55
59
|
);
|
56
60
|
}
|
57
61
|
|
62
|
+
[Fact]
|
63
|
+
public async Task TestDependencyWithTrailingSpacesInAttribute()
|
64
|
+
{
|
65
|
+
await TestDiscoveryAsync(
|
66
|
+
packages:
|
67
|
+
[
|
68
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
|
69
|
+
],
|
70
|
+
workspacePath: "src",
|
71
|
+
files: new[]
|
72
|
+
{
|
73
|
+
("src/project.csproj", """
|
74
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
75
|
+
<PropertyGroup>
|
76
|
+
<TargetFramework>net8.0</TargetFramework>
|
77
|
+
<SomePackageVersion>9.0.1</SomePackageVersion>
|
78
|
+
</PropertyGroup>
|
79
|
+
|
80
|
+
<ItemGroup>
|
81
|
+
<PackageReference Include=" Some.Package " Version="$(SomePackageVersion)" />
|
82
|
+
</ItemGroup>
|
83
|
+
</Project>
|
84
|
+
""")
|
85
|
+
},
|
86
|
+
expectedResult: new()
|
87
|
+
{
|
88
|
+
Path = "src",
|
89
|
+
Projects = [
|
90
|
+
new()
|
91
|
+
{
|
92
|
+
FilePath = "project.csproj",
|
93
|
+
TargetFrameworks = ["net8.0"],
|
94
|
+
ReferencedProjectPaths = [],
|
95
|
+
ExpectedDependencyCount = 2,
|
96
|
+
Dependencies = [
|
97
|
+
new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
|
98
|
+
new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true)
|
99
|
+
],
|
100
|
+
Properties = [
|
101
|
+
new("SomePackageVersion", "9.0.1", "src/project.csproj"),
|
102
|
+
new("TargetFramework", "net8.0", "src/project.csproj"),
|
103
|
+
]
|
104
|
+
}
|
105
|
+
]
|
106
|
+
}
|
107
|
+
);
|
108
|
+
}
|
109
|
+
|
58
110
|
[Fact]
|
59
111
|
public async Task TestPackageConfig()
|
60
112
|
{
|
@@ -322,4 +374,100 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
322
374
|
}
|
323
375
|
);
|
324
376
|
}
|
377
|
+
|
378
|
+
[Fact]
|
379
|
+
public async Task ResultFileHasCorrectShapeForAuthenticationFailure()
|
380
|
+
{
|
381
|
+
using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync([]);
|
382
|
+
var discoveryResultPath = Path.Combine(temporaryDirectory.DirectoryPath, DiscoveryWorker.DiscoveryResultFileName);
|
383
|
+
await DiscoveryWorker.WriteResultsAsync(temporaryDirectory.DirectoryPath, discoveryResultPath, new()
|
384
|
+
{
|
385
|
+
ErrorType = ErrorType.AuthenticationFailure,
|
386
|
+
ErrorDetails = "<some package feed>",
|
387
|
+
Path = "/",
|
388
|
+
Projects = [],
|
389
|
+
});
|
390
|
+
var discoveryContents = await File.ReadAllTextAsync(discoveryResultPath);
|
391
|
+
|
392
|
+
// raw result file should look like this:
|
393
|
+
// {
|
394
|
+
// ...
|
395
|
+
// "ErrorType": "AuthenticationFailure",
|
396
|
+
// "ErrorDetails": "<some package feed>",
|
397
|
+
// ...
|
398
|
+
// }
|
399
|
+
var jsonDocument = JsonDocument.Parse(discoveryContents);
|
400
|
+
var errorType = jsonDocument.RootElement.GetProperty("ErrorType");
|
401
|
+
var errorDetails = jsonDocument.RootElement.GetProperty("ErrorDetails");
|
402
|
+
|
403
|
+
Assert.Equal("AuthenticationFailure", errorType.GetString());
|
404
|
+
Assert.Equal("<some package feed>", errorDetails.GetString());
|
405
|
+
}
|
406
|
+
|
407
|
+
[Fact]
|
408
|
+
public async Task ReportsPrivateSourceAuthenticationFailure()
|
409
|
+
{
|
410
|
+
static (int, string) TestHttpHandler(string uriString)
|
411
|
+
{
|
412
|
+
var uri = new Uri(uriString, UriKind.Absolute);
|
413
|
+
var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
|
414
|
+
return uri.PathAndQuery switch
|
415
|
+
{
|
416
|
+
// initial request is good
|
417
|
+
"/index.json" => (200, $$"""
|
418
|
+
{
|
419
|
+
"version": "3.0.0",
|
420
|
+
"resources": [
|
421
|
+
{
|
422
|
+
"@id": "{{baseUrl}}/download",
|
423
|
+
"@type": "PackageBaseAddress/3.0.0"
|
424
|
+
},
|
425
|
+
{
|
426
|
+
"@id": "{{baseUrl}}/query",
|
427
|
+
"@type": "SearchQueryService"
|
428
|
+
},
|
429
|
+
{
|
430
|
+
"@id": "{{baseUrl}}/registrations",
|
431
|
+
"@type": "RegistrationsBaseUrl"
|
432
|
+
}
|
433
|
+
]
|
434
|
+
}
|
435
|
+
"""),
|
436
|
+
// all other requests are unauthorized
|
437
|
+
_ => (401, "{}"),
|
438
|
+
};
|
439
|
+
}
|
440
|
+
using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
|
441
|
+
await TestDiscoveryAsync(
|
442
|
+
workspacePath: "",
|
443
|
+
files:
|
444
|
+
[
|
445
|
+
("project.csproj", """
|
446
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
447
|
+
<PropertyGroup>
|
448
|
+
<TargetFramework>net8.0</TargetFramework>
|
449
|
+
</PropertyGroup>
|
450
|
+
<ItemGroup>
|
451
|
+
<PackageReference Include="Some.Package" Version="1.2.3" />
|
452
|
+
</ItemGroup>
|
453
|
+
</Project>
|
454
|
+
"""),
|
455
|
+
("NuGet.Config", $"""
|
456
|
+
<configuration>
|
457
|
+
<packageSources>
|
458
|
+
<clear />
|
459
|
+
<add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
|
460
|
+
</packageSources>
|
461
|
+
</configuration>
|
462
|
+
"""),
|
463
|
+
],
|
464
|
+
expectedResult: new()
|
465
|
+
{
|
466
|
+
ErrorType = ErrorType.AuthenticationFailure,
|
467
|
+
ErrorDetails = $"({http.BaseUrl.TrimEnd('/')}/index.json)",
|
468
|
+
Path = "",
|
469
|
+
Projects = [],
|
470
|
+
}
|
471
|
+
);
|
472
|
+
}
|
325
473
|
}
|
@@ -4,7 +4,7 @@ using NuGetUpdater.Core.Discover;
|
|
4
4
|
|
5
5
|
namespace NuGetUpdater.Core.Test.Discover;
|
6
6
|
|
7
|
-
public record ExpectedWorkspaceDiscoveryResult
|
7
|
+
public record ExpectedWorkspaceDiscoveryResult : NativeResult
|
8
8
|
{
|
9
9
|
public required string Path { get; init; }
|
10
10
|
public bool IsSuccess { get; init; } = true;
|
@@ -0,0 +1,81 @@
|
|
1
|
+
using System.Net;
|
2
|
+
using System.Net.Sockets;
|
3
|
+
using System.Text;
|
4
|
+
|
5
|
+
namespace NuGetUpdater.Core.Test
|
6
|
+
{
|
7
|
+
public class TestHttpServer : IDisposable
|
8
|
+
{
|
9
|
+
private readonly Func<string, (int, byte[])> _requestHandler;
|
10
|
+
private readonly HttpListener _listener;
|
11
|
+
private bool _runServer = true;
|
12
|
+
|
13
|
+
public string BaseUrl { get; }
|
14
|
+
|
15
|
+
private TestHttpServer(string baseurl, Func<string, (int, byte[])> requestHandler)
|
16
|
+
{
|
17
|
+
BaseUrl = baseurl;
|
18
|
+
_requestHandler = requestHandler;
|
19
|
+
_listener = new HttpListener();
|
20
|
+
_listener.Prefixes.Add(baseurl);
|
21
|
+
}
|
22
|
+
|
23
|
+
private void Start()
|
24
|
+
{
|
25
|
+
_listener.Start();
|
26
|
+
Task.Factory.StartNew(HandleResponses);
|
27
|
+
}
|
28
|
+
|
29
|
+
public void Dispose()
|
30
|
+
{
|
31
|
+
_runServer = false;
|
32
|
+
_listener.Stop();
|
33
|
+
}
|
34
|
+
|
35
|
+
private async Task HandleResponses()
|
36
|
+
{
|
37
|
+
while (_runServer)
|
38
|
+
{
|
39
|
+
var context = await _listener.GetContextAsync();
|
40
|
+
var (statusCode, response) = _requestHandler(context.Request.Url!.AbsoluteUri);
|
41
|
+
context.Response.StatusCode = statusCode;
|
42
|
+
await context.Response.OutputStream.WriteAsync(response);
|
43
|
+
context.Response.Close();
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
private static readonly object PortGate = new();
|
48
|
+
|
49
|
+
public static TestHttpServer CreateTestServer(Func<string, (int, byte[])> requestHandler)
|
50
|
+
{
|
51
|
+
// static lock to ensure the port is not recycled after `FindFreePort()` and before we can start the real server
|
52
|
+
lock (PortGate)
|
53
|
+
{
|
54
|
+
var port = FindFreePort();
|
55
|
+
var baseUrl = $"http://localhost:{port}/";
|
56
|
+
var server = new TestHttpServer(baseUrl, requestHandler);
|
57
|
+
server.Start();
|
58
|
+
return server;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
public static TestHttpServer CreateTestStringServer(Func<string, (int, string)> requestHandler)
|
63
|
+
{
|
64
|
+
Func<string, (int, byte[])> bytesRequestHandler = url =>
|
65
|
+
{
|
66
|
+
var (statusCode, response) = requestHandler(url);
|
67
|
+
return (statusCode, Encoding.UTF8.GetBytes(response));
|
68
|
+
};
|
69
|
+
return CreateTestServer(bytesRequestHandler);
|
70
|
+
}
|
71
|
+
|
72
|
+
private static int FindFreePort()
|
73
|
+
{
|
74
|
+
var tcpListener = new TcpListener(IPAddress.Loopback, 0);
|
75
|
+
tcpListener.Start();
|
76
|
+
var port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
|
77
|
+
tcpListener.Stop();
|
78
|
+
return port;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
@@ -1,3 +1,7 @@
|
|
1
|
+
using System.Text.Json;
|
2
|
+
|
3
|
+
using NuGetUpdater.Core.Updater;
|
4
|
+
|
1
5
|
using Xunit;
|
2
6
|
|
3
7
|
namespace NuGetUpdater.Core.Test.Update;
|
@@ -88,7 +92,8 @@ public abstract class UpdateWorkerTestBase : TestBase
|
|
88
92
|
TestFile[]? additionalFiles = null,
|
89
93
|
TestFile[]? additionalFilesExpected = null,
|
90
94
|
MockNuGetPackage[]? packages = null,
|
91
|
-
string projectFilePath = "test-project.csproj"
|
95
|
+
string projectFilePath = "test-project.csproj",
|
96
|
+
UpdateOperationResult? expectedResult = null)
|
92
97
|
=> TestUpdateForProject(
|
93
98
|
dependencyName,
|
94
99
|
oldVersion,
|
@@ -98,7 +103,8 @@ public abstract class UpdateWorkerTestBase : TestBase
|
|
98
103
|
isTransitive,
|
99
104
|
additionalFiles,
|
100
105
|
additionalFilesExpected,
|
101
|
-
packages
|
106
|
+
packages,
|
107
|
+
expectedResult);
|
102
108
|
|
103
109
|
protected static async Task TestUpdateForProject(
|
104
110
|
string dependencyName,
|
@@ -109,7 +115,8 @@ public abstract class UpdateWorkerTestBase : TestBase
|
|
109
115
|
bool isTransitive = false,
|
110
116
|
TestFile[]? additionalFiles = null,
|
111
117
|
TestFile[]? additionalFilesExpected = null,
|
112
|
-
MockNuGetPackage[]? packages = null
|
118
|
+
MockNuGetPackage[]? packages = null,
|
119
|
+
UpdateOperationResult? expectedResult = null)
|
113
120
|
{
|
114
121
|
additionalFiles ??= [];
|
115
122
|
additionalFilesExpected ??= [];
|
@@ -130,16 +137,29 @@ public abstract class UpdateWorkerTestBase : TestBase
|
|
130
137
|
// run update
|
131
138
|
var worker = new UpdaterWorker(new Logger(verbose: true));
|
132
139
|
var projectPath = placeFilesInSrc ? $"src/{projectFilePath}" : projectFilePath;
|
133
|
-
|
140
|
+
var updateResultFile = Path.Combine(temporaryDirectory, "update-result.json");
|
141
|
+
await worker.RunAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive, updateResultFile);
|
142
|
+
var actualResultContents = await File.ReadAllTextAsync(updateResultFile);
|
143
|
+
var actualResult = JsonSerializer.Deserialize<UpdateOperationResult>(actualResultContents, UpdaterWorker.SerializerOptions);
|
144
|
+
if (expectedResult is { })
|
145
|
+
{
|
146
|
+
ValidateUpdateOperationResult(expectedResult, actualResult!);
|
147
|
+
}
|
134
148
|
});
|
135
149
|
|
136
|
-
var
|
150
|
+
var expectedResultFiles = additionalFilesExpected.Prepend((projectFilePath, expectedProjectContents)).ToArray();
|
137
151
|
if (placeFilesInSrc)
|
138
152
|
{
|
139
|
-
|
153
|
+
expectedResultFiles = expectedResultFiles.Select(er => ($"src/{er.Item1}", er.Item2)).ToArray();
|
140
154
|
}
|
141
155
|
|
142
|
-
AssertContainsFiles(
|
156
|
+
AssertContainsFiles(expectedResultFiles, actualResult);
|
157
|
+
}
|
158
|
+
|
159
|
+
protected static void ValidateUpdateOperationResult(UpdateOperationResult expectedResult, UpdateOperationResult actualResult)
|
160
|
+
{
|
161
|
+
Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
|
162
|
+
Assert.Equal(expectedResult.ErrorDetails, actualResult.ErrorDetails);
|
143
163
|
}
|
144
164
|
|
145
165
|
protected static Task TestNoChangeforSolution(
|
@@ -1,3 +1,7 @@
|
|
1
|
+
using System.Text.Json;
|
2
|
+
|
3
|
+
using NuGetUpdater.Core.Updater;
|
4
|
+
|
1
5
|
using Xunit;
|
2
6
|
|
3
7
|
namespace NuGetUpdater.Core.Test.Update;
|
@@ -6,6 +10,34 @@ public partial class UpdateWorkerTests
|
|
6
10
|
{
|
7
11
|
public class Mixed : UpdateWorkerTestBase
|
8
12
|
{
|
13
|
+
[Fact]
|
14
|
+
public async Task ResultFileHasCorrectShapeForAuthenticationFailure()
|
15
|
+
{
|
16
|
+
using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync([]);
|
17
|
+
var result = new UpdateOperationResult()
|
18
|
+
{
|
19
|
+
ErrorType = ErrorType.AuthenticationFailure,
|
20
|
+
ErrorDetails = "<some package feed>",
|
21
|
+
};
|
22
|
+
var resultFilePath = Path.Combine(temporaryDirectory.DirectoryPath, "update-result.json");
|
23
|
+
await UpdaterWorker.WriteResultFile(result, resultFilePath, new Logger(false));
|
24
|
+
var resultContent = await File.ReadAllTextAsync(resultFilePath);
|
25
|
+
|
26
|
+
// raw result file should look like this:
|
27
|
+
// {
|
28
|
+
// ...
|
29
|
+
// "ErrorType": "AuthenticationFailure",
|
30
|
+
// "ErrorDetails": "<some package feed>",
|
31
|
+
// ...
|
32
|
+
// }
|
33
|
+
var jsonDocument = JsonDocument.Parse(resultContent);
|
34
|
+
var errorType = jsonDocument.RootElement.GetProperty("ErrorType");
|
35
|
+
var errorDetails = jsonDocument.RootElement.GetProperty("ErrorDetails");
|
36
|
+
|
37
|
+
Assert.Equal("AuthenticationFailure", errorType.GetString());
|
38
|
+
Assert.Equal("<some package feed>", errorDetails.GetString());
|
39
|
+
}
|
40
|
+
|
9
41
|
[Fact]
|
10
42
|
public async Task ForPackagesProject_UpdatePackageReference_InBuildProps()
|
11
43
|
{
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
using NuGetUpdater.Core.Updater;
|
2
|
+
|
1
3
|
using Xunit;
|
2
4
|
|
3
5
|
namespace NuGetUpdater.Core.Test.Update;
|
@@ -1420,6 +1422,87 @@ public partial class UpdateWorkerTests
|
|
1420
1422
|
""");
|
1421
1423
|
}
|
1422
1424
|
|
1425
|
+
[Fact]
|
1426
|
+
public async Task ReportsPrivateSourceAuthenticationFailure()
|
1427
|
+
{
|
1428
|
+
static (int, string) TestHttpHandler(string uriString)
|
1429
|
+
{
|
1430
|
+
var uri = new Uri(uriString, UriKind.Absolute);
|
1431
|
+
var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
|
1432
|
+
return uri.PathAndQuery switch
|
1433
|
+
{
|
1434
|
+
_ => (401, "{}"), // everything is unauthorized
|
1435
|
+
};
|
1436
|
+
}
|
1437
|
+
using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
|
1438
|
+
await TestUpdateForProject("Some.Package", "1.0.0", "1.1.0",
|
1439
|
+
// existing
|
1440
|
+
projectContents: """
|
1441
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
1442
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
1443
|
+
<PropertyGroup>
|
1444
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
1445
|
+
</PropertyGroup>
|
1446
|
+
<ItemGroup>
|
1447
|
+
<None Include="packages.config" />
|
1448
|
+
</ItemGroup>
|
1449
|
+
<ItemGroup>
|
1450
|
+
<Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
|
1451
|
+
<HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
|
1452
|
+
<Private>True</Private>
|
1453
|
+
</Reference>
|
1454
|
+
</ItemGroup>
|
1455
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
1456
|
+
</Project>
|
1457
|
+
""",
|
1458
|
+
packagesConfigContents: """
|
1459
|
+
<packages>
|
1460
|
+
<package id="Some.Package" version="1.0.0" targetFramework="net45" />
|
1461
|
+
</packages>
|
1462
|
+
""",
|
1463
|
+
additionalFiles:
|
1464
|
+
[
|
1465
|
+
("NuGet.Config", $"""
|
1466
|
+
<configuration>
|
1467
|
+
<packageSources>
|
1468
|
+
<clear />
|
1469
|
+
<add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
|
1470
|
+
</packageSources>
|
1471
|
+
</configuration>
|
1472
|
+
""")
|
1473
|
+
],
|
1474
|
+
// expected
|
1475
|
+
expectedProjectContents: """
|
1476
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
1477
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
1478
|
+
<PropertyGroup>
|
1479
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
1480
|
+
</PropertyGroup>
|
1481
|
+
<ItemGroup>
|
1482
|
+
<None Include="packages.config" />
|
1483
|
+
</ItemGroup>
|
1484
|
+
<ItemGroup>
|
1485
|
+
<Reference Include="Some.Package, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
|
1486
|
+
<HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
|
1487
|
+
<Private>True</Private>
|
1488
|
+
</Reference>
|
1489
|
+
</ItemGroup>
|
1490
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
1491
|
+
</Project>
|
1492
|
+
""",
|
1493
|
+
expectedPackagesConfigContents: """
|
1494
|
+
<packages>
|
1495
|
+
<package id="Some.Package" version="1.0.0" targetFramework="net45" />
|
1496
|
+
</packages>
|
1497
|
+
""",
|
1498
|
+
expectedResult: new()
|
1499
|
+
{
|
1500
|
+
ErrorType = ErrorType.AuthenticationFailure,
|
1501
|
+
ErrorDetails = $"({http.BaseUrl.TrimEnd('/')}/index.json)",
|
1502
|
+
}
|
1503
|
+
);
|
1504
|
+
}
|
1505
|
+
|
1423
1506
|
protected static Task TestUpdateForProject(
|
1424
1507
|
string dependencyName,
|
1425
1508
|
string oldVersion,
|
@@ -1430,7 +1513,8 @@ public partial class UpdateWorkerTests
|
|
1430
1513
|
string expectedPackagesConfigContents,
|
1431
1514
|
(string Path, string Content)[]? additionalFiles = null,
|
1432
1515
|
(string Path, string Content)[]? additionalFilesExpected = null,
|
1433
|
-
MockNuGetPackage[]? packages = null
|
1516
|
+
MockNuGetPackage[]? packages = null,
|
1517
|
+
UpdateOperationResult? expectedResult = null)
|
1434
1518
|
{
|
1435
1519
|
var realizedAdditionalFiles = new List<(string Path, string Content)>
|
1436
1520
|
{
|
@@ -1458,7 +1542,8 @@ public partial class UpdateWorkerTests
|
|
1458
1542
|
expectedProjectContents,
|
1459
1543
|
additionalFiles: realizedAdditionalFiles.ToArray(),
|
1460
1544
|
additionalFilesExpected: realizedAdditionalFilesExpected.ToArray(),
|
1461
|
-
packages: packages
|
1545
|
+
packages: packages,
|
1546
|
+
expectedResult: expectedResult);
|
1462
1547
|
}
|
1463
1548
|
}
|
1464
1549
|
}
|
@@ -1,5 +1,8 @@
|
|
1
1
|
using System.Linq;
|
2
2
|
using System.Text;
|
3
|
+
using System.Text.Json;
|
4
|
+
|
5
|
+
using NuGetUpdater.Core.Updater;
|
3
6
|
|
4
7
|
using Xunit;
|
5
8
|
|
@@ -2898,5 +2901,90 @@ public partial class UpdateWorkerTests
|
|
2898
2901
|
"""
|
2899
2902
|
);
|
2900
2903
|
}
|
2904
|
+
|
2905
|
+
[Fact]
|
2906
|
+
public async Task UpdatePackageWithWhitespaceInTheXMLAttributeValue()
|
2907
|
+
{
|
2908
|
+
await TestUpdateForProject("Some.Package", "1.0.0", "1.1.0",
|
2909
|
+
packages:
|
2910
|
+
[
|
2911
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
|
2912
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", "net8.0"),
|
2913
|
+
],
|
2914
|
+
projectContents: """
|
2915
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
2916
|
+
<PropertyGroup>
|
2917
|
+
<TargetFramework>net8.0</TargetFramework>
|
2918
|
+
</PropertyGroup>
|
2919
|
+
<ItemGroup>
|
2920
|
+
<PackageReference Include=" Some.Package " Version="1.0.0" />
|
2921
|
+
</ItemGroup>
|
2922
|
+
</Project>
|
2923
|
+
""",
|
2924
|
+
expectedProjectContents: """
|
2925
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
2926
|
+
<PropertyGroup>
|
2927
|
+
<TargetFramework>net8.0</TargetFramework>
|
2928
|
+
</PropertyGroup>
|
2929
|
+
<ItemGroup>
|
2930
|
+
<PackageReference Include=" Some.Package " Version="1.1.0" />
|
2931
|
+
</ItemGroup>
|
2932
|
+
</Project>
|
2933
|
+
"""
|
2934
|
+
);
|
2935
|
+
}
|
2936
|
+
|
2937
|
+
[Fact]
|
2938
|
+
public async Task ReportsPrivateSourceAuthenticationFailure()
|
2939
|
+
{
|
2940
|
+
static (int, string) TestHttpHandler(string uriString)
|
2941
|
+
{
|
2942
|
+
var uri = new Uri(uriString, UriKind.Absolute);
|
2943
|
+
var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
|
2944
|
+
return uri.PathAndQuery switch
|
2945
|
+
{
|
2946
|
+
_ => (401, "{}"), // everything is unauthorized
|
2947
|
+
};
|
2948
|
+
}
|
2949
|
+
using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
|
2950
|
+
await TestUpdateForProject("Some.Package", "1.0.0", "1.1.0",
|
2951
|
+
projectContents: """
|
2952
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
2953
|
+
<PropertyGroup>
|
2954
|
+
<TargetFramework>net8.0</TargetFramework>
|
2955
|
+
</PropertyGroup>
|
2956
|
+
<ItemGroup>
|
2957
|
+
<PackageReference Include="Some.Package" Version="1.0.0" />
|
2958
|
+
</ItemGroup>
|
2959
|
+
</Project>
|
2960
|
+
""",
|
2961
|
+
additionalFiles:
|
2962
|
+
[
|
2963
|
+
("NuGet.Config", $"""
|
2964
|
+
<configuration>
|
2965
|
+
<packageSources>
|
2966
|
+
<clear />
|
2967
|
+
<add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
|
2968
|
+
</packageSources>
|
2969
|
+
</configuration>
|
2970
|
+
""")
|
2971
|
+
],
|
2972
|
+
expectedProjectContents: """
|
2973
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
2974
|
+
<PropertyGroup>
|
2975
|
+
<TargetFramework>net8.0</TargetFramework>
|
2976
|
+
</PropertyGroup>
|
2977
|
+
<ItemGroup>
|
2978
|
+
<PackageReference Include="Some.Package" Version="1.0.0" />
|
2979
|
+
</ItemGroup>
|
2980
|
+
</Project>
|
2981
|
+
""",
|
2982
|
+
expectedResult: new()
|
2983
|
+
{
|
2984
|
+
ErrorType = ErrorType.AuthenticationFailure,
|
2985
|
+
ErrorDetails = $"({http.BaseUrl.TrimEnd('/')}/index.json)",
|
2986
|
+
}
|
2987
|
+
);
|
2988
|
+
}
|
2901
2989
|
}
|
2902
2990
|
}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/nuget/version"
|
5
|
+
require "dependabot/nuget/native_helpers"
|
5
6
|
require "sorbet-runtime"
|
6
7
|
|
7
8
|
module Dependabot
|
@@ -11,6 +12,8 @@ module Dependabot
|
|
11
12
|
|
12
13
|
sig { params(json: T::Hash[String, T.untyped]).returns(DependencyAnalysis) }
|
13
14
|
def self.from_json(json)
|
15
|
+
Dependabot::Nuget::NativeHelpers.ensure_no_errors(json)
|
16
|
+
|
14
17
|
updated_version = T.let(json.fetch("UpdatedVersion"), String)
|
15
18
|
can_update = T.let(json.fetch("CanUpdate"), T::Boolean)
|
16
19
|
version_comes_from_multi_dependency_property = T.let(json.fetch("VersionComesFromMultiDependencyProperty"),
|
@@ -43,7 +43,7 @@ module Dependabot
|
|
43
43
|
).void
|
44
44
|
end
|
45
45
|
def initialize(source:, credentials:, repo_contents_path: nil, options: {})
|
46
|
-
super
|
46
|
+
super
|
47
47
|
|
48
48
|
@sln_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
49
49
|
@sln_project_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|