dependabot-nuget 0.310.0 → 0.312.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.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
- data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/DotNetPackageCorrelation.Test.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/NuGetUpdater.Cli.Test.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +7 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/BadResponseException.cs +12 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +121 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ClosePullRequest.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CreatePullRequest.cs +20 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +26 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MessageBase.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UnknownError.cs +12 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatePullRequest.cs +16 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs +19 -50
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs +33 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +49 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +41 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +13 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +6 -25
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +13 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +74 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +3 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +3 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +58 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +37 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +116 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +231 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +32 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +714 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +44 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/TestApiHandler.cs +2 -39
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +9 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +99 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateOperationBaseTests.cs +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +1 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LoggerTests.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +66 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/global.json +1 -1
- metadata +30 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acb9d775c29330f4cae905aa23b7ad9c36f0ed161d8cc1c2fbfc7391fb52646b
|
4
|
+
data.tar.gz: 97b60783a35914969fe10efc5235a91d29a470faf40e4520cf331bf6bafe21f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1d117e611b42497834c3276f08e35e3a70a3b2d0f960ac3d666dde3c12eb32697f911e0af3409e76500977f4c1db835c4979a85879e86bbd00e0ec0df4cc34c
|
7
|
+
data.tar.gz: b3f8f76bc8be51fc23493c1660cb41e5f6b9c10721941bd98c72c49652c807bb320def722cdc3c08d822f2cd2ed0dbe993b75cd6d43d0f1593de6890a753af32
|
@@ -38,7 +38,7 @@
|
|
38
38
|
<PackageVersion Include="System.Text.Json" Version="9.0.3" />
|
39
39
|
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
40
40
|
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.3" />
|
41
|
-
<PackageVersion Include="xunit" Version="2.
|
41
|
+
<PackageVersion Include="xunit.v3" Version="2.0.1" />
|
42
42
|
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
|
43
43
|
</ItemGroup>
|
44
44
|
</Project>
|
@@ -58,7 +58,7 @@ public partial class EntryPointTests
|
|
58
58
|
);
|
59
59
|
}
|
60
60
|
|
61
|
-
private static async Task RunAsync(TestFile[] files, Job job, string[] expectedUrls, MockNuGetPackage[]? packages = null)
|
61
|
+
private static async Task RunAsync(TestFile[] files, Job job, string[] expectedUrls, MockNuGetPackage[]? packages = null, string? repoContentsPath = null)
|
62
62
|
{
|
63
63
|
using var tempDirectory = new TemporaryDirectory();
|
64
64
|
|
@@ -90,7 +90,7 @@ public partial class EntryPointTests
|
|
90
90
|
"--job-path",
|
91
91
|
jobPath,
|
92
92
|
"--repo-contents-path",
|
93
|
-
tempDirectory.DirectoryPath,
|
93
|
+
repoContentsPath ?? tempDirectory.DirectoryPath,
|
94
94
|
"--api-url",
|
95
95
|
http.BaseUrl,
|
96
96
|
"--job-id",
|
@@ -1,5 +1,7 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
2
|
|
3
|
+
using Newtonsoft.Json;
|
4
|
+
|
3
5
|
using NuGet.Common;
|
4
6
|
using NuGet.Configuration;
|
5
7
|
using NuGet.Frameworks;
|
@@ -98,6 +100,11 @@ internal static class VersionFinder
|
|
98
100
|
// if anything goes wrong here, the package source obviously doesn't contain the requested package
|
99
101
|
continue;
|
100
102
|
}
|
103
|
+
catch (JsonReaderException ex)
|
104
|
+
{
|
105
|
+
// unable to parse server response
|
106
|
+
throw new BadResponseException(ex.Message, source.Source);
|
107
|
+
}
|
101
108
|
|
102
109
|
var feedVersions = (await feed.GetVersions(
|
103
110
|
packageId,
|
@@ -1,9 +1,11 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
|
+
using System.Text.Json;
|
2
3
|
using System.Xml.Linq;
|
3
4
|
using System.Xml.XPath;
|
4
5
|
|
5
6
|
using Microsoft.Build.Logging.StructuredLogger;
|
6
7
|
|
8
|
+
using NuGet.Frameworks;
|
7
9
|
using NuGet.Versioning;
|
8
10
|
|
9
11
|
using NuGetUpdater.Core.Utilities;
|
@@ -39,6 +41,8 @@ internal static class SdkProjectDiscovery
|
|
39
41
|
// these packages are resolved during restore, but aren't really updatable and shouldn't be reported as dependencies
|
40
42
|
private static readonly HashSet<string> NonReportedPackgeNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
41
43
|
{
|
44
|
+
"Microsoft.NETCore.Platforms",
|
45
|
+
"Microsoft.NETCore.Targets",
|
42
46
|
"NETStandard.Library"
|
43
47
|
};
|
44
48
|
|
@@ -84,6 +88,9 @@ internal static class SdkProjectDiscovery
|
|
84
88
|
Dictionary<string, Dictionary<string, Dictionary<string, string>>> packagesReplacedBySdkPerProject = new(PathComparer.Instance);
|
85
89
|
// projectPath tfm packageName packageVersion
|
86
90
|
|
91
|
+
Dictionary<string, Dictionary<string, HashSet<string>>> packageDependencies = new(PathComparer.Instance);
|
92
|
+
// projectPath tfm packageNames
|
93
|
+
|
87
94
|
Dictionary<string, Dictionary<string, string>> resolvedProperties = new(PathComparer.Instance);
|
88
95
|
// projectPath propertyName propertyValue
|
89
96
|
|
@@ -228,6 +235,28 @@ internal static class SdkProjectDiscovery
|
|
228
235
|
}
|
229
236
|
}
|
230
237
|
}
|
238
|
+
|
239
|
+
// track all referenced projects in case they have no assemblies and can't be otherwise reported
|
240
|
+
if (addItem.Name.Equals("PackageDependencies", StringComparison.OrdinalIgnoreCase))
|
241
|
+
{
|
242
|
+
var projectEvaluation = GetNearestProjectEvaluation(node);
|
243
|
+
if (projectEvaluation is not null)
|
244
|
+
{
|
245
|
+
var specificPackageDeps = packageDependencies.GetOrAdd(projectEvaluation.ProjectFile, () => new(StringComparer.OrdinalIgnoreCase));
|
246
|
+
var tfm = GetPropertyValueFromProjectEvaluation(projectEvaluation, "TargetFramework");
|
247
|
+
if (tfm is not null)
|
248
|
+
{
|
249
|
+
var packagesByTfm = specificPackageDeps.GetOrAdd(tfm, () => new(StringComparer.OrdinalIgnoreCase));
|
250
|
+
foreach (var package in addItem.Children.OfType<Item>())
|
251
|
+
{
|
252
|
+
if (!NonReportedPackgeNames.Contains(package.Name))
|
253
|
+
{
|
254
|
+
packagesByTfm.Add(package.Name);
|
255
|
+
}
|
256
|
+
}
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
231
260
|
}
|
232
261
|
break;
|
233
262
|
case Target target when target.Name == "_HandlePackageFileConflicts":
|
@@ -330,7 +359,7 @@ internal static class SdkProjectDiscovery
|
|
330
359
|
}
|
331
360
|
|
332
361
|
// and done
|
333
|
-
var projectDiscoveryResults = BuildResults(
|
362
|
+
var projectDiscoveryResults = await BuildResults(
|
334
363
|
repoRootPath,
|
335
364
|
workspacePath,
|
336
365
|
packagesPerProject,
|
@@ -338,6 +367,7 @@ internal static class SdkProjectDiscovery
|
|
338
367
|
packagesReplacedBySdkPerProject,
|
339
368
|
topLevelPackagesPerProject,
|
340
369
|
resolvedProperties,
|
370
|
+
packageDependencies,
|
341
371
|
referencedProjects,
|
342
372
|
importedFiles,
|
343
373
|
additionalFiles
|
@@ -345,7 +375,7 @@ internal static class SdkProjectDiscovery
|
|
345
375
|
return projectDiscoveryResults;
|
346
376
|
}
|
347
377
|
|
348
|
-
private static ImmutableArray<ProjectDiscoveryResult
|
378
|
+
private static async Task<ImmutableArray<ProjectDiscoveryResult>> BuildResults(
|
349
379
|
string repoRootPath,
|
350
380
|
string workspacePath,
|
351
381
|
Dictionary<string, Dictionary<string, Dictionary<string, string>>> packagesPerProject,
|
@@ -353,13 +383,14 @@ internal static class SdkProjectDiscovery
|
|
353
383
|
Dictionary<string, Dictionary<string, Dictionary<string, string>>> packagesReplacedBySdkPerProject,
|
354
384
|
Dictionary<string, Dictionary<string, HashSet<string>>> topLevelPackagesPerProject,
|
355
385
|
Dictionary<string, Dictionary<string, string>> resolvedProperties,
|
386
|
+
Dictionary<string, Dictionary<string, HashSet<string>>> packageDependencies,
|
356
387
|
Dictionary<string, HashSet<string>> referencedProjects,
|
357
388
|
Dictionary<string, HashSet<string>> importedFiles,
|
358
389
|
Dictionary<string, HashSet<string>> additionalFiles
|
359
390
|
)
|
360
391
|
{
|
361
392
|
var projectDiscoveryResults = new List<ProjectDiscoveryResult>();
|
362
|
-
foreach (var projectPath in packagesPerProject.Keys.OrderBy(p => p))
|
393
|
+
foreach (var projectPath in packagesPerProject.Keys.OrderBy(p => p))
|
363
394
|
{
|
364
395
|
// gather some project-level information
|
365
396
|
var packagesByTfm = packagesPerProject[projectPath];
|
@@ -400,18 +431,99 @@ internal static class SdkProjectDiscovery
|
|
400
431
|
.SelectMany(kvp => kvp.Value)
|
401
432
|
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
402
433
|
|
434
|
+
var propertiesForProject = resolvedProperties.GetOrAdd(projectPath, () => new(StringComparer.OrdinalIgnoreCase));
|
435
|
+
var assetsJson = new Lazy<JsonElement?>(() =>
|
436
|
+
{
|
437
|
+
if (propertiesForProject.TryGetValue("ProjectAssetsFile", out var assetsFilePath))
|
438
|
+
{
|
439
|
+
var assetsContent = File.ReadAllText(assetsFilePath);
|
440
|
+
var assets = JsonDocument.Parse(assetsContent).RootElement;
|
441
|
+
return assets;
|
442
|
+
}
|
443
|
+
|
444
|
+
return null;
|
445
|
+
});
|
446
|
+
|
403
447
|
// create dependencies
|
404
448
|
var tfms = packagesByTfm.Keys.OrderBy(tfm => tfm).ToImmutableArray();
|
405
|
-
var
|
449
|
+
var groupedDependencies = new Dictionary<string, Dependency>(StringComparer.OrdinalIgnoreCase);
|
450
|
+
foreach (var tfm in tfms)
|
406
451
|
{
|
407
|
-
|
452
|
+
var parsedTfm = NuGetFramework.Parse(tfm);
|
453
|
+
var packages = packagesByTfm[tfm];
|
454
|
+
|
455
|
+
// augment with any packages that might not have reported assemblies
|
456
|
+
var assetsPackageVersions = new Lazy<Dictionary<string, string>>(() =>
|
457
|
+
{
|
458
|
+
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
459
|
+
if (assetsJson.Value is { } assets &&
|
460
|
+
assets.TryGetProperty("targets", out var tfmObjects))
|
461
|
+
{
|
462
|
+
foreach (var tfmObject in tfmObjects.EnumerateObject())
|
463
|
+
{
|
464
|
+
// TFM might have a RID suffix after a slash that we can't parse
|
465
|
+
var tfmParts = tfmObject.Name.Split('/');
|
466
|
+
var reportedTargetFramework = NuGetFramework.Parse(tfmParts[0]);
|
467
|
+
if (reportedTargetFramework == parsedTfm)
|
468
|
+
{
|
469
|
+
foreach (var packageObject in tfmObject.Value.EnumerateObject())
|
470
|
+
{
|
471
|
+
var parts = packageObject.Name.Split('/');
|
472
|
+
if (parts.Length == 2)
|
473
|
+
{
|
474
|
+
var packageName = parts[0];
|
475
|
+
var packageVersion = parts[1];
|
476
|
+
result[packageName] = packageVersion;
|
477
|
+
}
|
478
|
+
}
|
479
|
+
}
|
480
|
+
}
|
481
|
+
}
|
482
|
+
|
483
|
+
return result;
|
484
|
+
});
|
485
|
+
var packageDepsForProject = packageDependencies.GetOrAdd(projectPath, () => new(StringComparer.OrdinalIgnoreCase));
|
486
|
+
var packageDepsForTfm = packageDepsForProject.GetOrAdd(tfm, () => new(StringComparer.OrdinalIgnoreCase));
|
487
|
+
foreach (var packageDepName in packageDepsForTfm)
|
488
|
+
{
|
489
|
+
if (packages.ContainsKey(packageDepName))
|
490
|
+
{
|
491
|
+
// we already know about this
|
492
|
+
continue;
|
493
|
+
}
|
494
|
+
|
495
|
+
// otherwise find the corresponding version through project.assets.json
|
496
|
+
if (assetsPackageVersions.Value.TryGetValue(packageDepName, out var packageDepVersion))
|
497
|
+
{
|
498
|
+
packages[packageDepName] = packageDepVersion;
|
499
|
+
}
|
500
|
+
}
|
501
|
+
|
502
|
+
foreach (var package in packages)
|
408
503
|
{
|
409
|
-
var
|
504
|
+
var packageName = package.Key;
|
505
|
+
var packageVersion = package.Value;
|
410
506
|
var isTopLevel = topLevelPackageNames.Contains(packageName);
|
411
507
|
var dependencyType = isTopLevel ? DependencyType.PackageReference : DependencyType.Unknown;
|
412
|
-
|
413
|
-
|
414
|
-
|
508
|
+
var combinedTfms = new HashSet<string>([tfm], StringComparer.OrdinalIgnoreCase);
|
509
|
+
if (groupedDependencies.TryGetValue(packageName, out var existingDependency) &&
|
510
|
+
existingDependency.Version == packageVersion &&
|
511
|
+
existingDependency.Type == dependencyType &&
|
512
|
+
existingDependency.TargetFrameworks is not null)
|
513
|
+
{
|
514
|
+
// same dependency, combine tfms
|
515
|
+
combinedTfms.AddRange(existingDependency.TargetFrameworks);
|
516
|
+
}
|
517
|
+
|
518
|
+
var normalizedTfms = combinedTfms.OrderBy(t => t).ToImmutableArray();
|
519
|
+
groupedDependencies[package.Key] = new Dependency(packageName, packageVersion, dependencyType, TargetFrameworks: normalizedTfms, IsDirect: isTopLevel, IsTransitive: !isTopLevel);
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
523
|
+
var dependencies = groupedDependencies.Values
|
524
|
+
.OrderBy(d => d.Name)
|
525
|
+
.ThenBy(d => d.Version)
|
526
|
+
.ToImmutableArray();
|
415
527
|
|
416
528
|
// others
|
417
529
|
var properties = resolvedProperties[projectPath]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
|
+
using System.Text;
|
2
3
|
using System.Text.Json.Serialization;
|
3
4
|
|
4
5
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
@@ -9,4 +10,16 @@ public sealed record ClosePullRequest : MessageBase
|
|
9
10
|
public required ImmutableArray<string> DependencyNames { get; init; }
|
10
11
|
|
11
12
|
public string Reason { get; init; } = "up_to_date";
|
13
|
+
|
14
|
+
public override string GetReport()
|
15
|
+
{
|
16
|
+
var report = new StringBuilder();
|
17
|
+
report.AppendLine($"{nameof(ClosePullRequest)}: {Reason}");
|
18
|
+
foreach (var dependencyName in DependencyNames)
|
19
|
+
{
|
20
|
+
report.AppendLine($"- {dependencyName}");
|
21
|
+
}
|
22
|
+
|
23
|
+
return report.ToString().Trim();
|
24
|
+
}
|
12
25
|
}
|
@@ -1,5 +1,8 @@
|
|
1
|
+
using System.Text;
|
1
2
|
using System.Text.Json.Serialization;
|
2
3
|
|
4
|
+
using NuGet.Versioning;
|
5
|
+
|
3
6
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
4
7
|
|
5
8
|
public sealed record CreatePullRequest : MessageBase
|
@@ -15,4 +18,21 @@ public sealed record CreatePullRequest : MessageBase
|
|
15
18
|
public required string PrTitle { get; init; }
|
16
19
|
[JsonPropertyName("pr-body")]
|
17
20
|
public required string PrBody { get; init; }
|
21
|
+
|
22
|
+
public override string GetReport()
|
23
|
+
{
|
24
|
+
var dependencyNames = Dependencies
|
25
|
+
.OrderBy(d => d.Name, StringComparer.OrdinalIgnoreCase)
|
26
|
+
.ThenBy(d => NuGetVersion.Parse(d.Version!))
|
27
|
+
.Select(d => $"{d.Name}/{d.Version}")
|
28
|
+
.ToArray();
|
29
|
+
var report = new StringBuilder();
|
30
|
+
report.AppendLine(nameof(CreatePullRequest));
|
31
|
+
foreach (var d in dependencyNames)
|
32
|
+
{
|
33
|
+
report.AppendLine($"- {d}");
|
34
|
+
}
|
35
|
+
|
36
|
+
return report.ToString().Trim();
|
37
|
+
}
|
18
38
|
}
|
@@ -2,7 +2,6 @@ using System.Collections.Immutable;
|
|
2
2
|
using System.Text.Json;
|
3
3
|
using System.Text.Json.Serialization;
|
4
4
|
|
5
|
-
using NuGet.Credentials;
|
6
5
|
using NuGet.Versioning;
|
7
6
|
|
8
7
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
@@ -32,7 +31,7 @@ public sealed record Job
|
|
32
31
|
public bool RejectExternalCode { get; init; } = false;
|
33
32
|
public bool RepoPrivate { get; init; } = false;
|
34
33
|
public CommitOptions? CommitMessageOptions { get; init; } = null;
|
35
|
-
public ImmutableArray<Dictionary<string,
|
34
|
+
public ImmutableArray<Dictionary<string, object>>? CredentialsMetadata { get; init; } = null;
|
36
35
|
public int MaxUpdaterRunTime { get; init; } = 0;
|
37
36
|
|
38
37
|
public IEnumerable<string> GetAllDirectories()
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using System.Net;
|
2
|
+
using System.Text;
|
2
3
|
using System.Text.Json.Serialization;
|
3
4
|
|
4
5
|
using Microsoft.Build.Exceptions;
|
@@ -20,11 +21,36 @@ public abstract record JobErrorBase : MessageBase
|
|
20
21
|
[JsonPropertyName("error-details")]
|
21
22
|
public Dictionary<string, object> Details { get; init; } = new();
|
22
23
|
|
24
|
+
public override string GetReport()
|
25
|
+
{
|
26
|
+
var report = new StringBuilder();
|
27
|
+
report.AppendLine($"Error type: {Type}");
|
28
|
+
foreach (var (key, value) in Details)
|
29
|
+
{
|
30
|
+
if (this is UnknownError && key == "error-backtrace")
|
31
|
+
{
|
32
|
+
// there's nothing meaningful in this field
|
33
|
+
continue;
|
34
|
+
}
|
35
|
+
|
36
|
+
var valueString = value.ToString();
|
37
|
+
if (value is IEnumerable<string> strings)
|
38
|
+
{
|
39
|
+
valueString = string.Join(", ", strings);
|
40
|
+
}
|
41
|
+
|
42
|
+
report.AppendLine($"- {key}: {valueString}");
|
43
|
+
}
|
44
|
+
|
45
|
+
return report.ToString().Trim();
|
46
|
+
}
|
47
|
+
|
23
48
|
public static JobErrorBase ErrorFromException(Exception ex, string jobId, string currentDirectory)
|
24
49
|
{
|
25
50
|
return ex switch
|
26
51
|
{
|
27
52
|
BadRequirementException badRequirement => new BadRequirement(badRequirement.Message),
|
53
|
+
BadResponseException badResponse => new PrivateSourceBadResponse([badResponse.Uri]),
|
28
54
|
DependencyNotFoundException dependencyNotFound => new DependencyNotFound(string.Join(", ", dependencyNotFound.Dependencies)),
|
29
55
|
HttpRequestException httpRequest => httpRequest.StatusCode switch
|
30
56
|
{
|
@@ -1,13 +1,23 @@
|
|
1
|
+
using System.Text.Json.Serialization;
|
2
|
+
|
1
3
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
4
|
|
3
5
|
public record UnknownError : JobErrorBase
|
4
6
|
{
|
7
|
+
[JsonIgnore]
|
8
|
+
public Exception Exception { get; init; }
|
9
|
+
|
5
10
|
public UnknownError(Exception ex, string jobId)
|
6
11
|
: base("unknown_error")
|
7
12
|
{
|
13
|
+
Exception = ex;
|
14
|
+
|
15
|
+
// The following object is parsed by the server and the `error-backtrace` property is expected to be a Ruby
|
16
|
+
// stacktrace. Since we're not in Ruby we can set an empty string there and append the .NET stacktrace to
|
17
|
+
// the message.
|
8
18
|
Details["error-class"] = ex.GetType().Name;
|
9
|
-
Details["error-message"] = ex.
|
10
|
-
Details["error-backtrace"] =
|
19
|
+
Details["error-message"] = ex.ToString();
|
20
|
+
Details["error-backtrace"] = "";
|
11
21
|
Details["package-manager"] = "nuget";
|
12
22
|
Details["job-id"] = jobId;
|
13
23
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
|
+
using System.Text;
|
2
3
|
using System.Text.Json.Serialization;
|
3
4
|
|
4
5
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
@@ -25,4 +26,19 @@ public sealed record UpdatePullRequest : MessageBase
|
|
25
26
|
|
26
27
|
[JsonPropertyName("dependency-group")]
|
27
28
|
public required string? DependencyGroup { get; init; }
|
29
|
+
|
30
|
+
public override string GetReport()
|
31
|
+
{
|
32
|
+
var dependencyNames = DependencyNames
|
33
|
+
.Order(StringComparer.OrdinalIgnoreCase)
|
34
|
+
.ToArray();
|
35
|
+
var report = new StringBuilder();
|
36
|
+
report.AppendLine(nameof(UpdatePullRequest));
|
37
|
+
foreach (var d in dependencyNames)
|
38
|
+
{
|
39
|
+
report.AppendLine($"- {d}");
|
40
|
+
}
|
41
|
+
|
42
|
+
return report.ToString().Trim();
|
43
|
+
}
|
28
44
|
}
|
@@ -2,8 +2,6 @@ using System.Text;
|
|
2
2
|
using System.Text.Json;
|
3
3
|
using System.Text.Json.Serialization;
|
4
4
|
|
5
|
-
using NuGetUpdater.Core.Run.ApiModel;
|
6
|
-
|
7
5
|
namespace NuGetUpdater.Core.Run;
|
8
6
|
|
9
7
|
public class HttpApiHandler : IApiHandler
|
@@ -25,39 +23,27 @@ public class HttpApiHandler : IApiHandler
|
|
25
23
|
_jobId = jobId;
|
26
24
|
}
|
27
25
|
|
28
|
-
public async Task
|
29
|
-
{
|
30
|
-
await PostAsJson("record_update_job_error", error);
|
31
|
-
}
|
32
|
-
|
33
|
-
public async Task UpdateDependencyList(UpdatedDependencyList updatedDependencyList)
|
26
|
+
public async Task SendAsync(string endpoint, object body, string method)
|
34
27
|
{
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
}
|
52
|
-
|
53
|
-
public async Task UpdatePullRequest(UpdatePullRequest updatePullRequest)
|
54
|
-
{
|
55
|
-
await PostAsJson("update_pull_request", updatePullRequest);
|
56
|
-
}
|
28
|
+
var uri = $"{_apiUrl}/update_jobs/{_jobId}/{endpoint}";
|
29
|
+
var payload = Serialize(body);
|
30
|
+
var content = new StringContent(payload, Encoding.UTF8, "application/json");
|
31
|
+
var httpMethod = new HttpMethod(method);
|
32
|
+
var message = new HttpRequestMessage(httpMethod, uri)
|
33
|
+
{
|
34
|
+
Content = content
|
35
|
+
};
|
36
|
+
var response = await HttpClient.SendAsync(message);
|
37
|
+
if (!response.IsSuccessStatusCode)
|
38
|
+
{
|
39
|
+
var responseContent = await response.Content.ReadAsStringAsync();
|
40
|
+
if (!string.IsNullOrEmpty(responseContent))
|
41
|
+
{
|
42
|
+
responseContent = string.Concat(": ", responseContent);
|
43
|
+
}
|
57
44
|
|
58
|
-
|
59
|
-
|
60
|
-
await PatchAsJson("mark_as_processed", markAsProcessed);
|
45
|
+
throw new HttpRequestException(message: $"{(int)response.StatusCode} ({response.StatusCode}){responseContent}", inner: null, statusCode: response.StatusCode);
|
46
|
+
}
|
61
47
|
}
|
62
48
|
|
63
49
|
internal static string Serialize(object body)
|
@@ -69,21 +55,4 @@ public class HttpApiHandler : IApiHandler
|
|
69
55
|
var payload = JsonSerializer.Serialize(wrappedBody, SerializerOptions);
|
70
56
|
return payload;
|
71
57
|
}
|
72
|
-
|
73
|
-
private Task PostAsJson(string endpoint, object body) => SendAsJson(endpoint, body, "POST");
|
74
|
-
private Task PatchAsJson(string endpoint, object body) => SendAsJson(endpoint, body, "PATCH");
|
75
|
-
|
76
|
-
private async Task SendAsJson(string endpoint, object body, string method)
|
77
|
-
{
|
78
|
-
var uri = $"{_apiUrl}/update_jobs/{_jobId}/{endpoint}";
|
79
|
-
var payload = Serialize(body);
|
80
|
-
var content = new StringContent(payload, Encoding.UTF8, "application/json");
|
81
|
-
var httpMethod = new HttpMethod(method);
|
82
|
-
var message = new HttpRequestMessage(httpMethod, uri)
|
83
|
-
{
|
84
|
-
Content = content
|
85
|
-
};
|
86
|
-
var response = await HttpClient.SendAsync(message);
|
87
|
-
var _ = response.EnsureSuccessStatusCode();
|
88
|
-
}
|
89
58
|
}
|
@@ -4,11 +4,37 @@ namespace NuGetUpdater.Core.Run;
|
|
4
4
|
|
5
5
|
public interface IApiHandler
|
6
6
|
{
|
7
|
-
Task
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Task
|
13
|
-
|
7
|
+
Task SendAsync(string endpoint, object body, string method);
|
8
|
+
}
|
9
|
+
|
10
|
+
public static class IApiHandlerExtensions
|
11
|
+
{
|
12
|
+
public static async Task RecordUpdateJobError(this IApiHandler handler, JobErrorBase error)
|
13
|
+
{
|
14
|
+
await handler.PostAsJson("record_update_job_error", error);
|
15
|
+
if (error is UnknownError unknown)
|
16
|
+
{
|
17
|
+
await handler.PostAsJson("record_update_job_unknown_error", error);
|
18
|
+
var increment = new IncrementMetric()
|
19
|
+
{
|
20
|
+
Metric = "updater.update_job_unknown_error",
|
21
|
+
Tags =
|
22
|
+
{
|
23
|
+
["package_manager"] = "nuget",
|
24
|
+
["class_name"] = unknown.Exception.GetType().Name
|
25
|
+
},
|
26
|
+
};
|
27
|
+
await handler.IncrementMetric(increment);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
public static Task UpdateDependencyList(this IApiHandler handler, UpdatedDependencyList updatedDependencyList) => handler.PostAsJson("update_dependency_list", updatedDependencyList);
|
32
|
+
public static Task IncrementMetric(this IApiHandler handler, IncrementMetric incrementMetric) => handler.PostAsJson("increment_metric", incrementMetric);
|
33
|
+
public static Task CreatePullRequest(this IApiHandler handler, CreatePullRequest createPullRequest) => handler.PostAsJson("create_pull_request", createPullRequest);
|
34
|
+
public static Task ClosePullRequest(this IApiHandler handler, ClosePullRequest closePullRequest) => handler.PostAsJson("close_pull_request", closePullRequest);
|
35
|
+
public static Task UpdatePullRequest(this IApiHandler handler, UpdatePullRequest updatePullRequest) => handler.PostAsJson("update_pull_request", updatePullRequest);
|
36
|
+
public static Task MarkAsProcessed(this IApiHandler handler, MarkAsProcessed markAsProcessed) => handler.PatchAsJson("mark_as_processed", markAsProcessed);
|
37
|
+
|
38
|
+
private static Task PostAsJson(this IApiHandler handler, string endpoint, object body) => handler.SendAsync(endpoint, body, "POST");
|
39
|
+
private static Task PatchAsJson(this IApiHandler handler, string endpoint, object body) => handler.SendAsync(endpoint, body, "PATCH");
|
14
40
|
}
|