dependabot-nuget 0.293.0 → 0.295.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,286 @@
1
+ using System.Collections.Immutable;
2
+
3
+ using NuGetUpdater.Core.Analyze;
4
+ using NuGetUpdater.Core.Run;
5
+ using NuGetUpdater.Core.Run.ApiModel;
6
+
7
+ using Xunit;
8
+
9
+ using DepType = NuGetUpdater.Core.Run.ApiModel.DependencyType;
10
+
11
+ namespace NuGetUpdater.Core.Test.Run;
12
+
13
+ public class UpdateAllowedTests
14
+ {
15
+ [Theory]
16
+ [MemberData(nameof(IsUpdateAllowedTestData))]
17
+ public void IsUpdateAllowed(Job job, Dependency dependency, bool expectedResult)
18
+ {
19
+ var actualResult = RunWorker.IsUpdateAllowed(job, dependency);
20
+ Assert.Equal(expectedResult, actualResult);
21
+ }
22
+
23
+ public static IEnumerable<object[]> IsUpdateAllowedTestData()
24
+ {
25
+ // with default allowed updates on a transitive dependency
26
+ yield return
27
+ [
28
+ CreateJob(
29
+ allowedUpdates: [
30
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All }
31
+ ],
32
+ securityAdvisories: [
33
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
34
+ ],
35
+ securityUpdatesOnly: false),
36
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
37
+ // expectedResult
38
+ false,
39
+ ];
40
+
41
+ // when dealing with a security update
42
+ yield return
43
+ [
44
+ CreateJob(
45
+ allowedUpdates: [
46
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All }
47
+ ],
48
+ securityAdvisories: [
49
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
50
+ ],
51
+ securityUpdatesOnly: true),
52
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
53
+ // expectedResult
54
+ true,
55
+ ];
56
+
57
+ // with a top-level dependency
58
+ yield return
59
+ [
60
+ CreateJob(
61
+ allowedUpdates: [
62
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
63
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
64
+ ],
65
+ securityAdvisories: [],
66
+ securityUpdatesOnly: false),
67
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
68
+ // expectedResult
69
+ true,
70
+ ];
71
+
72
+ // with a sub-dependency
73
+ yield return
74
+ [
75
+ CreateJob(
76
+ allowedUpdates: [
77
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
78
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
79
+ ],
80
+ securityAdvisories: [],
81
+ securityUpdatesOnly: false),
82
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
83
+ // expectedResult
84
+ false,
85
+ ];
86
+
87
+ // when insecure
88
+ yield return
89
+ [
90
+ CreateJob(
91
+ allowedUpdates: [
92
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
93
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
94
+ ],
95
+ securityAdvisories: [
96
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
97
+ ],
98
+ securityUpdatesOnly: false),
99
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
100
+ // expectedResult
101
+ true,
102
+ ];
103
+
104
+ // when only security fixes are allowed
105
+ yield return
106
+ [
107
+ CreateJob(
108
+ allowedUpdates: [
109
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
110
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
111
+ ],
112
+ securityAdvisories: [],
113
+ securityUpdatesOnly: true),
114
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
115
+ // expectedResult
116
+ false,
117
+ ];
118
+
119
+ // when dealing with a security fix
120
+ yield return
121
+ [
122
+ CreateJob(
123
+ allowedUpdates: [
124
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
125
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
126
+ ],
127
+ securityAdvisories: [
128
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
129
+ ],
130
+ securityUpdatesOnly: true),
131
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
132
+ // expectedResult
133
+ true,
134
+ ];
135
+
136
+ // when dealing with a security fix that doesn't apply
137
+ yield return
138
+ [
139
+ CreateJob(
140
+ allowedUpdates: [
141
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
142
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
143
+ ],
144
+ securityAdvisories: [
145
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("> 1.8.0")], PatchedVersions = [], UnaffectedVersions = [] }
146
+ ],
147
+ securityUpdatesOnly: true),
148
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
149
+ // expectedResult
150
+ false,
151
+ ];
152
+
153
+ // when dealing with a security fix that doesn't apply to some versions
154
+ yield return
155
+ [
156
+ CreateJob(
157
+ allowedUpdates: [
158
+ new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
159
+ new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
160
+ ],
161
+ securityAdvisories: [
162
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("< 1.8.0"), Requirement.Parse("> 1.8.0")], PatchedVersions = [], UnaffectedVersions = [] }
163
+ ],
164
+ securityUpdatesOnly: true),
165
+ new Dependency("Some.Package", "1.8.1", DependencyType.PackageReference, IsTransitive: false),
166
+ // expectedResult
167
+ true,
168
+ ];
169
+
170
+ // when a dependency allow list that includes the dependency
171
+ yield return
172
+ [
173
+ CreateJob(
174
+ allowedUpdates: [
175
+ new AllowedUpdate() { DependencyName = "Some.Package" }
176
+ ],
177
+ securityAdvisories: [],
178
+ securityUpdatesOnly: false),
179
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
180
+ // expectedResult
181
+ true,
182
+ ];
183
+
184
+ // with a dependency allow list that uses a wildcard
185
+ yield return
186
+ [
187
+ CreateJob(
188
+ allowedUpdates: [
189
+ new AllowedUpdate() { DependencyName = "Some.*" }
190
+ ],
191
+ securityAdvisories: [],
192
+ securityUpdatesOnly: false),
193
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
194
+ // expectedResult
195
+ true,
196
+ ];
197
+
198
+ // when dependency allow list that excludes the dependency
199
+ yield return
200
+ [
201
+ CreateJob(
202
+ allowedUpdates: [
203
+ new AllowedUpdate() { DependencyName = "Unrelated.Package" }
204
+ ],
205
+ securityAdvisories: [],
206
+ securityUpdatesOnly: false),
207
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
208
+ // expectedResult
209
+ false,
210
+ ];
211
+
212
+ // when matching with an incomplete dependency name
213
+ yield return
214
+ [
215
+ CreateJob(
216
+ allowedUpdates: [
217
+ new AllowedUpdate() { DependencyName = "Some" }
218
+ ],
219
+ securityAdvisories: [],
220
+ securityUpdatesOnly: false),
221
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
222
+ // expectedResult
223
+ false,
224
+ ];
225
+
226
+ // with a dependency allow list that uses a wildcard
227
+ yield return
228
+ [
229
+ CreateJob(
230
+ allowedUpdates: [
231
+ new AllowedUpdate() { DependencyName = "Unrelated.*" }
232
+ ],
233
+ securityAdvisories: [],
234
+ securityUpdatesOnly: false),
235
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
236
+ // expectedResult
237
+ false,
238
+ ];
239
+
240
+ // when security fixes are also allowed
241
+ yield return
242
+ [
243
+ CreateJob(
244
+ allowedUpdates: [
245
+ new AllowedUpdate() { DependencyName = "Unrelated.Package" },
246
+ new AllowedUpdate() { UpdateType = UpdateType.Security }
247
+ ],
248
+ securityAdvisories: [],
249
+ securityUpdatesOnly: false),
250
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
251
+ // expectedResult
252
+ false,
253
+ ];
254
+
255
+ // when dealing with a security fix
256
+ yield return
257
+ [
258
+ CreateJob(
259
+ allowedUpdates: [
260
+ new AllowedUpdate() { DependencyName = "Unrelated.Package"}, new AllowedUpdate(){ UpdateType = UpdateType.Security }
261
+ ],
262
+ securityAdvisories: [
263
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
264
+ ],
265
+ securityUpdatesOnly: false),
266
+ new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
267
+ // expectedResult
268
+ true,
269
+ ];
270
+ }
271
+
272
+ private static Job CreateJob(AllowedUpdate[] allowedUpdates, Advisory[] securityAdvisories, bool securityUpdatesOnly)
273
+ {
274
+ return new Job()
275
+ {
276
+ AllowedUpdates = allowedUpdates.ToImmutableArray(),
277
+ SecurityAdvisories = securityAdvisories.ToImmutableArray(),
278
+ SecurityUpdatesOnly = securityUpdatesOnly,
279
+ Source = new()
280
+ {
281
+ Provider = "nuget",
282
+ Repo = "test/repo",
283
+ }
284
+ };
285
+ }
286
+ }
@@ -94,7 +94,15 @@ public class UpdatedDependencyListTests
94
94
  {
95
95
  Name = "System.Text.Json",
96
96
  Version = "6.0.0",
97
- Requirements = [],
97
+ Requirements =
98
+ [
99
+ new ReportedRequirement()
100
+ {
101
+ Requirement = "6.0.0",
102
+ File = "/src/c/project.csproj",
103
+ Groups = ["dependencies"],
104
+ }
105
+ ],
98
106
  },
99
107
  new ReportedDependency()
100
108
  {
@@ -1,7 +1,8 @@
1
1
  using System.Collections.Immutable;
2
+ using System.Text.Json;
2
3
 
3
- using NuGet.Build.Tasks;
4
-
4
+ using NuGetUpdater.Core.Run;
5
+ using NuGetUpdater.Core.Run.ApiModel;
5
6
  using NuGetUpdater.Core.Test.Update;
6
7
 
7
8
  using Xunit;
@@ -1366,6 +1367,91 @@ public class MSBuildHelperTests : TestBase
1366
1367
  }
1367
1368
  #endregion
1368
1369
 
1370
+ [Theory]
1371
+ [MemberData(nameof(GenerateErrorFromToolOutputTestData))]
1372
+ public async Task GenerateErrorFromToolOutput(string output, JobErrorBase? expectedError)
1373
+ {
1374
+ Exception? exception = null;
1375
+ try
1376
+ {
1377
+ MSBuildHelper.ThrowOnError(output);
1378
+ }
1379
+ catch (Exception ex)
1380
+ {
1381
+ exception = ex;
1382
+ }
1383
+
1384
+ if (expectedError is null)
1385
+ {
1386
+ Assert.Null(exception);
1387
+ }
1388
+ else
1389
+ {
1390
+ Assert.NotNull(exception);
1391
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync([("NuGet.Config", """
1392
+ <configuration>
1393
+ <packageSources>
1394
+ <clear />
1395
+ <add key="test-feed" value="http://localhost/test-feed" />
1396
+ </packageSources>
1397
+ </configuration>
1398
+ """)]);
1399
+ var actualError = JobErrorBase.ErrorFromException(exception, "TEST-JOB-ID", tempDir.DirectoryPath);
1400
+ if (actualError is DependencyFileNotFound notFound)
1401
+ {
1402
+ // normalize default message for the test
1403
+ actualError = new DependencyFileNotFound(notFound.Details["file-path"].ToString()!, "test message");
1404
+ }
1405
+
1406
+ var actualErrorJson = JsonSerializer.Serialize(actualError, RunWorker.SerializerOptions);
1407
+ var expectedErrorJson = JsonSerializer.Serialize(expectedError, RunWorker.SerializerOptions);
1408
+ Assert.Equal(expectedErrorJson, actualErrorJson);
1409
+ }
1410
+ }
1411
+
1412
+ public static IEnumerable<object?[]> GenerateErrorFromToolOutputTestData()
1413
+ {
1414
+ yield return
1415
+ [
1416
+ // output
1417
+ "Everything was good.",
1418
+ // expectedError
1419
+ null,
1420
+ ];
1421
+
1422
+ yield return
1423
+ [
1424
+ // output
1425
+ "Response status code does not indicate success: 403",
1426
+ // expectedError
1427
+ new PrivateSourceAuthenticationFailure(["http://localhost/test-feed"]),
1428
+ ];
1429
+
1430
+ yield return
1431
+ [
1432
+ // output
1433
+ "The imported file \"some.file\" does not exist",
1434
+ // expectedError
1435
+ new DependencyFileNotFound("some.file", "test message"),
1436
+ ];
1437
+
1438
+ yield return
1439
+ [
1440
+ // output
1441
+ "Package 'Some.Package' is not found on source",
1442
+ // expectedError
1443
+ new UpdateNotPossible(["Some.Package"]),
1444
+ ];
1445
+
1446
+ yield return
1447
+ [
1448
+ // output
1449
+ "Unable to resolve dependencies. 'Some.Package 1.2.3' is not compatible with",
1450
+ // expectedError
1451
+ new UpdateNotPossible(["Some.Package.1.2.3"]),
1452
+ ];
1453
+ }
1454
+
1369
1455
  public static IEnumerable<object[]> GetTopLevelPackageDependencyInfosTestData()
1370
1456
  {
1371
1457
  // simple case
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-nuget
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.293.0
4
+ version: 0.295.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-16 00:00:00.000000000 Z
11
+ date: 2025-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.293.0
19
+ version: 0.295.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.293.0
26
+ version: 0.295.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubyzip
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -351,6 +351,7 @@ files:
351
351
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs
352
352
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs
353
353
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/TestApiHandler.cs
354
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateAllowedTests.cs
354
355
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs
355
356
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs
356
357
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryEnvironment.cs
@@ -528,7 +529,7 @@ licenses:
528
529
  - MIT
529
530
  metadata:
530
531
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
531
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.293.0
532
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.295.0
532
533
  post_install_message:
533
534
  rdoc_options: []
534
535
  require_paths: