dependabot-nuget 0.304.0 → 0.305.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 +5 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +3 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +4 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +13 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +52 -21
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +13 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +33 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/OpenTelemetryLogger.cs +54 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +77 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +45 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +63 -44
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +56 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatePermittedAndMessageTests.cs +90 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +60 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LoggerTests.cs +61 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +44 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 137dd6d83f2c7ddfa976b7c2f4998569608d53591fcb78c71493a2a2f6ba38ba
|
4
|
+
data.tar.gz: 95c0a8c95e46fd79bbea338e110c675ee9e56983b587cea9392aa2161d939efa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c1f3bc6e859ebadea39a5f5c142270458abd1b6778f872dc3026bec5489652bd652356ee37c8f8b5f5f57397e00c81914281f2d3380584afea88e8080eab0a2
|
7
|
+
data.tar.gz: 2b23f7200bf17572009da8f6eed84bbac0fd6e8a0d9c52eb781e6a32fa0933598adb25732d8488cef709eed07a10b88d2146618f8444350e35d0798e8c74030b
|
@@ -1,13 +1,10 @@
|
|
1
1
|
<Project>
|
2
|
-
|
3
2
|
<PropertyGroup>
|
4
3
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
5
4
|
</PropertyGroup>
|
6
|
-
|
7
5
|
<PropertyGroup>
|
8
6
|
<MSBuildPackageVersion>17.12.6</MSBuildPackageVersion>
|
9
7
|
</PropertyGroup>
|
10
|
-
|
11
8
|
<ItemGroup>
|
12
9
|
<PackageVersion Include="DiffPlex" Version="1.7.2" />
|
13
10
|
<PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.93" />
|
@@ -20,12 +17,16 @@
|
|
20
17
|
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
|
21
18
|
<PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="9.0.0" />
|
22
19
|
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="9.0.3" />
|
20
|
+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.3" />
|
23
21
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
24
22
|
<PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.12.2149" />
|
25
23
|
<PackageVersion Include="Microsoft.Web.Xdt" Version="3.1.0" />
|
26
24
|
<PackageVersion Include="MSBuild.StructuredLogger" Version="2.2.386" />
|
27
25
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
28
26
|
<PackageVersion Include="NuGet.Core" Version="2.14.0" Aliases="CoreV2" />
|
27
|
+
<PackageVersion Include="OpenTelemetry" Version="1.11.2" />
|
28
|
+
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.11.2" />
|
29
|
+
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.2" />
|
29
30
|
<PackageVersion Include="Semver" Version="3.0.0" />
|
30
31
|
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
31
32
|
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.3" />
|
@@ -39,5 +40,4 @@
|
|
39
40
|
<PackageVersion Include="xunit" Version="2.9.3" />
|
40
41
|
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
|
41
42
|
</ItemGroup>
|
42
|
-
|
43
|
-
</Project>
|
43
|
+
</Project>
|
@@ -30,7 +30,7 @@ internal static class AnalyzeCommand
|
|
30
30
|
|
31
31
|
command.SetHandler(async (jobId, jobPath, repoRoot, discoveryPath, dependencyPath, analysisDirectory) =>
|
32
32
|
{
|
33
|
-
var logger = new
|
33
|
+
var logger = new OpenTelemetryLogger();
|
34
34
|
var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
|
35
35
|
var worker = new AnalyzeWorker(jobId, experimentsManager, logger);
|
36
36
|
await worker.RunAsync(repoRoot.FullName, discoveryPath.FullName, dependencyPath.FullName, analysisDirectory.FullName);
|
@@ -28,7 +28,7 @@ internal static class CloneCommand
|
|
28
28
|
command.SetHandler(async (jobPath, repoContentsPath, apiUrl, jobId) =>
|
29
29
|
{
|
30
30
|
var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
|
31
|
-
var logger = new
|
31
|
+
var logger = new OpenTelemetryLogger();
|
32
32
|
var gitCommandHandler = new ShellGitCommandHandler(logger);
|
33
33
|
var worker = new CloneWorker(jobId, apiHandler, gitCommandHandler);
|
34
34
|
var exitCode = await worker.RunAsync(jobPath, repoContentsPath);
|
@@ -28,7 +28,8 @@ internal static class DiscoverCommand
|
|
28
28
|
|
29
29
|
command.SetHandler(async (jobId, jobPath, repoRoot, workspace, outputPath) =>
|
30
30
|
{
|
31
|
-
|
31
|
+
var logger = new OpenTelemetryLogger();
|
32
|
+
MSBuildHelper.RegisterMSBuild(repoRoot.FullName, repoRoot.FullName, logger);
|
32
33
|
var (experimentsManager, error) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
|
33
34
|
if (error is not null)
|
34
35
|
{
|
@@ -43,7 +44,6 @@ internal static class DiscoverCommand
|
|
43
44
|
return;
|
44
45
|
}
|
45
46
|
|
46
|
-
var logger = new ConsoleLogger();
|
47
47
|
var worker = new DiscoveryWorker(jobId, experimentsManager, logger);
|
48
48
|
await worker.RunAsync(repoRoot.FullName, workspace, outputPath.FullName);
|
49
49
|
}, JobIdOption, JobPathOption, RepoRootOption, WorkspaceOption, OutputOption);
|
@@ -34,7 +34,7 @@ internal static class RunCommand
|
|
34
34
|
{
|
35
35
|
var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
|
36
36
|
var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
|
37
|
-
var logger = new
|
37
|
+
var logger = new OpenTelemetryLogger();
|
38
38
|
var discoverWorker = new DiscoveryWorker(jobId, experimentsManager, logger);
|
39
39
|
var analyzeWorker = new AnalyzeWorker(jobId, experimentsManager, logger);
|
40
40
|
var updateWorker = new UpdaterWorker(jobId, experimentsManager, logger);
|
@@ -46,7 +46,7 @@ internal static class UpdateCommand
|
|
46
46
|
var resultOutputPath = context.ParseResult.GetValueForOption(ResultOutputPathOption);
|
47
47
|
|
48
48
|
var (experimentsManager, _error) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
|
49
|
-
var logger = new
|
49
|
+
var logger = new OpenTelemetryLogger();
|
50
50
|
var worker = new UpdaterWorker(jobId, experimentsManager, logger);
|
51
51
|
await worker.RunAsync(repoRoot.FullName, solutionOrProjectFile.FullName, dependencyName, previousVersion, newVersion, isTransitive, resultOutputPath);
|
52
52
|
setExitCode(0);
|
@@ -67,7 +67,7 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
67
67
|
|
68
68
|
public async Task<AnalysisResult> RunAsync(string repoRoot, WorkspaceDiscoveryResult discovery, DependencyInfo dependencyInfo)
|
69
69
|
{
|
70
|
-
MSBuildHelper.RegisterMSBuild(repoRoot, repoRoot);
|
70
|
+
MSBuildHelper.RegisterMSBuild(repoRoot, repoRoot, _logger);
|
71
71
|
|
72
72
|
var startingDirectory = PathHelper.JoinPath(repoRoot, discovery.Path);
|
73
73
|
|
@@ -65,7 +65,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
65
65
|
|
66
66
|
public async Task<WorkspaceDiscoveryResult> RunAsync(string repoRootPath, string workspacePath)
|
67
67
|
{
|
68
|
-
MSBuildHelper.RegisterMSBuild(repoRootPath, workspacePath);
|
68
|
+
MSBuildHelper.RegisterMSBuild(repoRootPath, workspacePath, _logger);
|
69
69
|
|
70
70
|
// the `workspacePath` variable is relative to a repository root, so a rooted path actually isn't rooted; the
|
71
71
|
// easy way to deal with this is to just trim the leading "/" if it exists
|
@@ -8,13 +8,15 @@ internal sealed class ProjectBuildFile : XmlBuildFile
|
|
8
8
|
=> Parse(basePath, path, File.ReadAllText(path));
|
9
9
|
|
10
10
|
public static ProjectBuildFile Parse(string basePath, string path, string xml)
|
11
|
-
=> new(basePath, path,
|
11
|
+
=> new(basePath, path, Parse(xml));
|
12
12
|
|
13
13
|
public ProjectBuildFile(string basePath, string path, XmlDocumentSyntax contents)
|
14
14
|
: base(basePath, path, contents)
|
15
15
|
{
|
16
16
|
}
|
17
17
|
|
18
|
+
public static XmlDocumentSyntax Parse(string contents) => Parser.ParseText(contents);
|
19
|
+
|
18
20
|
public IXmlElementSyntax ProjectNode => Contents.RootSyntax;
|
19
21
|
|
20
22
|
public IEnumerable<IXmlElementSyntax> SdkNodes => ProjectNode
|
@@ -23,8 +23,12 @@
|
|
23
23
|
<PackageReference Include="GuiLabs.Language.Xml" />
|
24
24
|
<PackageReference Include="DiffPlex" />
|
25
25
|
<PackageReference Include="Microsoft.Build.Locator" />
|
26
|
+
<PackageReference Include="Microsoft.Extensions.Logging" />
|
26
27
|
<PackageReference Include="MSBuild.StructuredLogger" />
|
27
28
|
<PackageReference Include="NuGet.Core" Aliases="CoreV2" />
|
29
|
+
<PackageReference Include="OpenTelemetry" />
|
30
|
+
<PackageReference Include="OpenTelemetry.Exporter.Console" />
|
31
|
+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
|
28
32
|
</ItemGroup>
|
29
33
|
|
30
34
|
<ItemGroup>
|
@@ -31,6 +31,7 @@ public abstract record JobErrorBase : MessageBase
|
|
31
31
|
HttpStatusCode.Unauthorized or
|
32
32
|
HttpStatusCode.Forbidden => new PrivateSourceAuthenticationFailure(NuGetContext.GetPackageSourceUrls(currentDirectory)),
|
33
33
|
HttpStatusCode.TooManyRequests => new PrivateSourceBadResponse(NuGetContext.GetPackageSourceUrls(currentDirectory)),
|
34
|
+
HttpStatusCode.ServiceUnavailable => new PrivateSourceBadResponse(NuGetContext.GetPackageSourceUrls(currentDirectory)),
|
34
35
|
_ => new UnknownError(ex, jobId),
|
35
36
|
},
|
36
37
|
InvalidProjectFileException invalidProjectFile => new DependencyFileNotParseable(invalidProjectFile.ProjectFile),
|
@@ -1,44 +1,45 @@
|
|
1
|
-
using
|
1
|
+
using System.Collections.Immutable;
|
2
2
|
|
3
3
|
using NuGetUpdater.Core.Run.ApiModel;
|
4
|
+
using NuGetUpdater.Core.Updater;
|
4
5
|
|
5
6
|
namespace NuGetUpdater.Core.Run;
|
6
7
|
|
7
8
|
public class PullRequestTextGenerator
|
8
9
|
{
|
9
|
-
public static string GetPullRequestTitle(Job job,
|
10
|
+
public static string GetPullRequestTitle(Job job, ImmutableArray<UpdateOperationBase> updateOperationsPerformed, string? dependencyGroupName)
|
10
11
|
{
|
11
12
|
// simple version looks like
|
12
13
|
// Update Some.Package to 1.2.3
|
13
14
|
// if multiple packages are updated to multiple versions, result looks like:
|
14
15
|
// Update Package.A to 1.0.0, 2.0.0; Package.B to 3.0.0, 4.0.0
|
15
|
-
var dependencySets =
|
16
|
-
.GroupBy(d => d.
|
16
|
+
var dependencySets = updateOperationsPerformed
|
17
|
+
.GroupBy(d => d.DependencyName, StringComparer.OrdinalIgnoreCase)
|
17
18
|
.OrderBy(g => g.Key, StringComparer.OrdinalIgnoreCase)
|
18
19
|
.Select(g => new
|
19
20
|
{
|
20
21
|
Name = g.Key,
|
21
22
|
Versions = g
|
22
|
-
.
|
23
|
-
.
|
24
|
-
.OrderBy(d => NuGetVersion.Parse(d))
|
23
|
+
.Select(d => d.NewVersion)
|
24
|
+
.OrderBy(v => v)
|
25
25
|
.ToArray()
|
26
26
|
})
|
27
27
|
.ToArray();
|
28
28
|
var updatedPartTitles = dependencySets
|
29
|
-
.Select(d => $"{d.Name} to {string.Join(", ", d.Versions)}")
|
29
|
+
.Select(d => $"{d.Name} to {string.Join(", ", d.Versions.Select(v => v.ToString()))}")
|
30
30
|
.ToArray();
|
31
31
|
var title = $"{job.CommitMessageOptions?.Prefix}Update {string.Join("; ", updatedPartTitles)}";
|
32
32
|
return title;
|
33
33
|
}
|
34
34
|
|
35
|
-
public static string GetPullRequestCommitMessage(Job job,
|
35
|
+
public static string GetPullRequestCommitMessage(Job job, ImmutableArray<UpdateOperationBase> updateOperationsPerformed, string? dependencyGroupName)
|
36
36
|
{
|
37
|
-
return GetPullRequestTitle(job,
|
37
|
+
return GetPullRequestTitle(job, updateOperationsPerformed, dependencyGroupName);
|
38
38
|
}
|
39
39
|
|
40
|
-
public static string GetPullRequestBody(Job job,
|
40
|
+
public static string GetPullRequestBody(Job job, ImmutableArray<UpdateOperationBase> updateOperationsPerformed, string? dependencyGroupName)
|
41
41
|
{
|
42
|
-
|
42
|
+
var report = UpdateOperationBase.GenerateUpdateOperationReport(updateOperationsPerformed);
|
43
|
+
return report;
|
43
44
|
}
|
44
45
|
}
|
@@ -69,7 +69,7 @@ public class RunWorker
|
|
69
69
|
|
70
70
|
try
|
71
71
|
{
|
72
|
-
MSBuildHelper.RegisterMSBuild(repoContentsPath.FullName, repoContentsPath.FullName);
|
72
|
+
MSBuildHelper.RegisterMSBuild(repoContentsPath.FullName, repoContentsPath.FullName, _logger);
|
73
73
|
|
74
74
|
var experimentsManager = ExperimentsManager.GetExperimentsManager(job.Experiments);
|
75
75
|
var allDependencyFiles = new Dictionary<string, DependencyFile>();
|
@@ -291,7 +291,12 @@ public class RunWorker
|
|
291
291
|
.Select(kvp => kvp.Value)
|
292
292
|
.ToArray();
|
293
293
|
|
294
|
-
var
|
294
|
+
var normalizedUpdateOperationsPerformed = UpdateOperationBase.NormalizeUpdateOperationCollection(repoContentsPath.FullName, updateOperationsPerformed);
|
295
|
+
var report = UpdateOperationBase.GenerateUpdateOperationReport(normalizedUpdateOperationsPerformed);
|
296
|
+
_logger.Info(report);
|
297
|
+
|
298
|
+
var sortedUpdatedDependencies = actualUpdatedDependencies.OrderBy(d => d.Name, StringComparer.OrdinalIgnoreCase).ToArray();
|
299
|
+
var resultMessage = GetPullRequestApiMessage(job, updatedDependencyFileList, sortedUpdatedDependencies, normalizedUpdateOperationsPerformed, baseCommitSha);
|
295
300
|
switch (resultMessage)
|
296
301
|
{
|
297
302
|
case ClosePullRequest close:
|
@@ -321,10 +326,6 @@ public class RunWorker
|
|
321
326
|
await SendApiMessage(new SecurityUpdateNotNeeded(depName));
|
322
327
|
}
|
323
328
|
|
324
|
-
var normalizedUpdateOperationsPerformed = UpdateOperationBase.NormalizeUpdateOperationCollection(repoContentsPath.FullName, updateOperationsPerformed);
|
325
|
-
var report = UpdateOperationBase.GenerateUpdateOperationReport(normalizedUpdateOperationsPerformed);
|
326
|
-
_logger.Info(report);
|
327
|
-
|
328
329
|
var result = new RunResult()
|
329
330
|
{
|
330
331
|
Base64DependencyFiles = originalDependencyFileContents.OrderBy(kvp => kvp.Key).Select(kvp =>
|
@@ -365,10 +366,16 @@ public class RunWorker
|
|
365
366
|
}
|
366
367
|
}
|
367
368
|
|
368
|
-
internal static MessageBase? GetPullRequestApiMessage(
|
369
|
+
internal static MessageBase? GetPullRequestApiMessage(
|
370
|
+
Job job,
|
371
|
+
DependencyFile[] updatedFiles,
|
372
|
+
ReportedDependency[] updatedDependencies,
|
373
|
+
ImmutableArray<UpdateOperationBase> updateOperationsPerformed,
|
374
|
+
string baseCommitSha
|
375
|
+
)
|
369
376
|
{
|
370
|
-
|
371
|
-
var updatedDependenciesSet =
|
377
|
+
var updatedDependencyNames = updateOperationsPerformed.Select(u => u.DependencyName).OrderBy(d => d, StringComparer.OrdinalIgnoreCase).ToArray();
|
378
|
+
var updatedDependenciesSet = updatedDependencyNames.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
372
379
|
|
373
380
|
// all pull request dependencies with optional group name
|
374
381
|
var existingPullRequests = job.GetAllExistingPullRequests();
|
@@ -390,12 +397,12 @@ public class RunWorker
|
|
390
397
|
return new UpdatePullRequest()
|
391
398
|
{
|
392
399
|
DependencyGroup = existingPullRequest.Item1,
|
393
|
-
DependencyNames =
|
400
|
+
DependencyNames = [.. updatedDependencyNames],
|
394
401
|
UpdatedDependencyFiles = updatedFiles,
|
395
402
|
BaseCommitSha = baseCommitSha,
|
396
|
-
CommitMessage = PullRequestTextGenerator.GetPullRequestCommitMessage(job,
|
397
|
-
PrTitle = PullRequestTextGenerator.GetPullRequestTitle(job,
|
398
|
-
PrBody = PullRequestTextGenerator.GetPullRequestBody(job,
|
403
|
+
CommitMessage = PullRequestTextGenerator.GetPullRequestCommitMessage(job, updateOperationsPerformed, existingPullRequest.Item1),
|
404
|
+
PrTitle = PullRequestTextGenerator.GetPullRequestTitle(job, updateOperationsPerformed, existingPullRequest.Item1),
|
405
|
+
PrBody = PullRequestTextGenerator.GetPullRequestBody(job, updateOperationsPerformed, existingPullRequest.Item1),
|
399
406
|
};
|
400
407
|
}
|
401
408
|
else
|
@@ -422,16 +429,16 @@ public class RunWorker
|
|
422
429
|
}
|
423
430
|
else
|
424
431
|
{
|
425
|
-
if (
|
432
|
+
if (updatedDependencyNames.Any())
|
426
433
|
{
|
427
434
|
return new CreatePullRequest()
|
428
435
|
{
|
429
436
|
Dependencies = updatedDependencies,
|
430
437
|
UpdatedDependencyFiles = updatedFiles,
|
431
438
|
BaseCommitSha = baseCommitSha,
|
432
|
-
CommitMessage = PullRequestTextGenerator.GetPullRequestCommitMessage(job,
|
433
|
-
PrTitle = PullRequestTextGenerator.GetPullRequestTitle(job,
|
434
|
-
PrBody = PullRequestTextGenerator.GetPullRequestBody(job,
|
439
|
+
CommitMessage = PullRequestTextGenerator.GetPullRequestCommitMessage(job, updateOperationsPerformed, dependencyGroupName: null),
|
440
|
+
PrTitle = PullRequestTextGenerator.GetPullRequestTitle(job, updateOperationsPerformed, dependencyGroupName: null),
|
441
|
+
PrBody = PullRequestTextGenerator.GetPullRequestBody(job, updateOperationsPerformed, dependencyGroupName: null),
|
435
442
|
};
|
436
443
|
}
|
437
444
|
}
|
@@ -547,9 +554,33 @@ public class RunWorker
|
|
547
554
|
.ToArray();
|
548
555
|
if (existingPullRequests.Length > 0)
|
549
556
|
{
|
550
|
-
|
551
|
-
|
552
|
-
|
557
|
+
// found a matching pr...
|
558
|
+
if (job.UpdatingAPullRequest)
|
559
|
+
{
|
560
|
+
// ...and we've been asked to update it
|
561
|
+
return true;
|
562
|
+
}
|
563
|
+
else
|
564
|
+
{
|
565
|
+
// ...but no update requested => don't perform any update and report error
|
566
|
+
var existingPrVersion = existingPullRequests[0].Item2.First(d => d.DependencyName.Equals(dependency.Name, StringComparison.OrdinalIgnoreCase)).DependencyVersion;
|
567
|
+
message = new PullRequestExistsForLatestVersion(dependency.Name, existingPrVersion.ToString());
|
568
|
+
return false;
|
569
|
+
}
|
570
|
+
}
|
571
|
+
else
|
572
|
+
{
|
573
|
+
// no matching pr...
|
574
|
+
if (job.UpdatingAPullRequest)
|
575
|
+
{
|
576
|
+
// ...but we've been asked to perform an update => no update possible, nothing to report
|
577
|
+
return false;
|
578
|
+
}
|
579
|
+
else
|
580
|
+
{
|
581
|
+
// ...and no update specifically requested => create new
|
582
|
+
return true;
|
583
|
+
}
|
553
584
|
}
|
554
585
|
}
|
555
586
|
else
|
@@ -565,7 +596,7 @@ public class RunWorker
|
|
565
596
|
}
|
566
597
|
}
|
567
598
|
|
568
|
-
return
|
599
|
+
return false;
|
569
600
|
}
|
570
601
|
else
|
571
602
|
{
|
@@ -399,7 +399,7 @@ internal static class PackageReferenceUpdater
|
|
399
399
|
}
|
400
400
|
|
401
401
|
/// <returns>The updated files.</returns>
|
402
|
-
|
402
|
+
internal static async Task<IEnumerable<string>> UpdateTransitiveDependencyAsync(
|
403
403
|
string repoRootPath,
|
404
404
|
string projectPath,
|
405
405
|
string dependencyName,
|
@@ -419,6 +419,17 @@ internal static class PackageReferenceUpdater
|
|
419
419
|
else
|
420
420
|
{
|
421
421
|
updatedFiles = await AddTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, experimentsManager, logger);
|
422
|
+
|
423
|
+
// files directly modified on disk by an external tool need to be refreshed in-memory
|
424
|
+
foreach (var updatedFile in updatedFiles)
|
425
|
+
{
|
426
|
+
var matchingBuildFile = buildFiles.FirstOrDefault(bf => PathComparer.Instance.Compare(updatedFile, bf.Path) == 0);
|
427
|
+
if (matchingBuildFile is not null)
|
428
|
+
{
|
429
|
+
var updatedContents = await File.ReadAllTextAsync(updatedFile);
|
430
|
+
matchingBuildFile.Update(ProjectBuildFile.Parse(updatedContents));
|
431
|
+
}
|
432
|
+
}
|
422
433
|
}
|
423
434
|
|
424
435
|
return updatedFiles;
|
@@ -671,7 +682,7 @@ internal static class PackageReferenceUpdater
|
|
671
682
|
}
|
672
683
|
|
673
684
|
/// <returns>The updated files.</returns>
|
674
|
-
|
685
|
+
internal static (UpdateResult, IEnumerable<UpdateOperationBase>) TryUpdateDependencyVersion(
|
675
686
|
ImmutableArray<ProjectBuildFile> buildFiles,
|
676
687
|
string dependencyName,
|
677
688
|
string? previousDependencyVersion,
|
@@ -112,14 +112,14 @@ public abstract record UpdateOperationBase
|
|
112
112
|
public record DirectUpdate : UpdateOperationBase
|
113
113
|
{
|
114
114
|
public override string Type => nameof(DirectUpdate);
|
115
|
-
public override string GetReport() => $"Updated {DependencyName} to {NewVersion} in {string.Join("", UpdatedFiles)}";
|
115
|
+
public override string GetReport() => $"Updated {DependencyName} to {NewVersion} in {string.Join(", ", UpdatedFiles)}";
|
116
116
|
public sealed override string ToString() => GetString();
|
117
117
|
}
|
118
118
|
|
119
119
|
public record PinnedUpdate : UpdateOperationBase
|
120
120
|
{
|
121
121
|
public override string Type => nameof(PinnedUpdate);
|
122
|
-
public override string GetReport() => $"Pinned {DependencyName} at {NewVersion} in {string.Join("", UpdatedFiles)}";
|
122
|
+
public override string GetReport() => $"Pinned {DependencyName} at {NewVersion} in {string.Join(", ", UpdatedFiles)}";
|
123
123
|
public sealed override string ToString() => GetString();
|
124
124
|
}
|
125
125
|
|
@@ -129,7 +129,7 @@ public record ParentUpdate : UpdateOperationBase, IEquatable<UpdateOperationBase
|
|
129
129
|
public required string ParentDependencyName { get; init; }
|
130
130
|
public required NuGetVersion ParentNewVersion { get; init; }
|
131
131
|
|
132
|
-
public override string GetReport() => $"Updated {DependencyName} to {NewVersion} indirectly via {ParentDependencyName}/{ParentNewVersion} in {string.Join("", UpdatedFiles)}";
|
132
|
+
public override string GetReport() => $"Updated {DependencyName} to {NewVersion} indirectly via {ParentDependencyName}/{ParentNewVersion} in {string.Join(", ", UpdatedFiles)}";
|
133
133
|
|
134
134
|
bool IEquatable<UpdateOperationBase>.Equals(UpdateOperationBase? other)
|
135
135
|
{
|
@@ -66,7 +66,7 @@ public class UpdaterWorker : IUpdaterWorker
|
|
66
66
|
|
67
67
|
public async Task<UpdateOperationResult> RunAsync(string repoRootPath, string workspacePath, string dependencyName, string previousDependencyVersion, string newDependencyVersion, bool isTransitive)
|
68
68
|
{
|
69
|
-
MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, repoRootPath);
|
69
|
+
MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, repoRootPath, _logger);
|
70
70
|
|
71
71
|
if (!Path.IsPathRooted(workspacePath) || !File.Exists(workspacePath))
|
72
72
|
{
|
@@ -33,7 +33,7 @@ internal static partial class MSBuildHelper
|
|
33
33
|
|
34
34
|
public static string GetFileFromRuntimeDirectory(string fileName) => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, fileName);
|
35
35
|
|
36
|
-
public static void RegisterMSBuild(string currentDirectory, string rootDirectory)
|
36
|
+
public static void RegisterMSBuild(string currentDirectory, string rootDirectory, ILogger logger)
|
37
37
|
{
|
38
38
|
// Ensure MSBuild types are registered before calling a method that loads the types
|
39
39
|
if (!IsMSBuildRegistered)
|
@@ -45,7 +45,7 @@ internal static partial class MSBuildHelper
|
|
45
45
|
MSBuildPath = defaultInstance.MSBuildPath;
|
46
46
|
MSBuildLocator.RegisterInstance(defaultInstance);
|
47
47
|
return Task.FromResult(0);
|
48
|
-
}).Wait();
|
48
|
+
}, logger).Wait();
|
49
49
|
}
|
50
50
|
}
|
51
51
|
|
@@ -54,11 +54,10 @@ internal static partial class MSBuildHelper
|
|
54
54
|
string rootDirectory,
|
55
55
|
ExperimentsManager experimentsManager,
|
56
56
|
Func<Task<T>> action,
|
57
|
-
ILogger
|
57
|
+
ILogger logger,
|
58
58
|
bool retainMSBuildSdks = false
|
59
59
|
)
|
60
60
|
{
|
61
|
-
logger ??= new ConsoleLogger();
|
62
61
|
if (experimentsManager.InstallDotnetSdks)
|
63
62
|
{
|
64
63
|
logger.Info($"{nameof(ExperimentsManager.InstallDotnetSdks)} == true; retaining `global.json` contents.");
|
@@ -820,7 +819,7 @@ internal static partial class MSBuildHelper
|
|
820
819
|
experimentsManager
|
821
820
|
);
|
822
821
|
return (exitCode, stdOut, stdErr);
|
823
|
-
});
|
822
|
+
}, logger);
|
824
823
|
ThrowOnError(stdOut);
|
825
824
|
if (exitCode != 0)
|
826
825
|
{
|
@@ -969,6 +968,7 @@ internal static partial class MSBuildHelper
|
|
969
968
|
ThrowOnMissingPackages(output);
|
970
969
|
ThrowOnUpdateNotPossible(output);
|
971
970
|
ThrowOnRateLimitExceeded(output);
|
971
|
+
ThrowOnServiceUnavailable(output);
|
972
972
|
}
|
973
973
|
|
974
974
|
private static void ThrowOnUnauthenticatedFeed(string stdout)
|
@@ -999,6 +999,19 @@ internal static partial class MSBuildHelper
|
|
999
999
|
}
|
1000
1000
|
}
|
1001
1001
|
|
1002
|
+
private static void ThrowOnServiceUnavailable(string stdout)
|
1003
|
+
{
|
1004
|
+
var serviceUnavailableMessageSnippets = new string[]
|
1005
|
+
{
|
1006
|
+
"503 (Service Unavailable)",
|
1007
|
+
"Response status code does not indicate success: 503",
|
1008
|
+
};
|
1009
|
+
if (serviceUnavailableMessageSnippets.Any(stdout.Contains))
|
1010
|
+
{
|
1011
|
+
throw new HttpRequestException(message: stdout, inner: null, statusCode: System.Net.HttpStatusCode.ServiceUnavailable);
|
1012
|
+
}
|
1013
|
+
}
|
1014
|
+
|
1002
1015
|
private static void ThrowOnMissingFile(string output)
|
1003
1016
|
{
|
1004
1017
|
var missingFile = GetMissingFile(output);
|
@@ -1071,6 +1084,7 @@ internal static partial class MSBuildHelper
|
|
1071
1084
|
TryGetGlobalJsonPath(repoRootPath, projectPath, out var globalJsonPath);
|
1072
1085
|
var safeGlobalJsonName = $"{globalJsonPath}{Guid.NewGuid()}";
|
1073
1086
|
HashSet<string> targetFrameworks = new(StringComparer.OrdinalIgnoreCase);
|
1087
|
+
var repoRootDirectoryInfo = new DirectoryInfo(repoRootPath);
|
1074
1088
|
|
1075
1089
|
try
|
1076
1090
|
{
|
@@ -1099,12 +1113,23 @@ internal static partial class MSBuildHelper
|
|
1099
1113
|
// load the project even if it imports a file that doesn't exist (e.g. a file that's generated at restore
|
1100
1114
|
// or build time).
|
1101
1115
|
using var projectCollection = new ProjectCollection(); // do this in a one-off instance and don't pollute the global collection
|
1102
|
-
|
1116
|
+
var project = Project.FromFile(projectPath, new ProjectOptions
|
1103
1117
|
{
|
1104
1118
|
LoadSettings = ProjectLoadSettings.IgnoreMissingImports,
|
1105
1119
|
ProjectCollection = projectCollection,
|
1106
1120
|
});
|
1107
|
-
|
1121
|
+
var allImportedPaths = project.Imports.Select(i => i.ImportedProject.FullPath.NormalizePathToUnix()).ToArray();
|
1122
|
+
var importedPathsInRepo = allImportedPaths.Where(p => PathHelper.IsFileUnderDirectory(repoRootDirectoryInfo, new FileInfo(p))).ToArray();
|
1123
|
+
var projectDir = Path.GetDirectoryName(projectPath)!;
|
1124
|
+
var intermediateDir = new DirectoryInfo(Path.Combine(projectDir, project.GetPropertyValue("BaseIntermediateOutputPath")));
|
1125
|
+
var outputDir = new DirectoryInfo(Path.Combine(projectDir, project.GetPropertyValue("BaseOutputPath")));
|
1126
|
+
var nonTransitivePathsInRepo = importedPathsInRepo.Where(p =>
|
1127
|
+
{
|
1128
|
+
var fi = new FileInfo(p);
|
1129
|
+
return !PathHelper.IsFileUnderDirectory(intermediateDir, fi)
|
1130
|
+
&& !PathHelper.IsFileUnderDirectory(outputDir, fi);
|
1131
|
+
}).ToArray();
|
1132
|
+
buildFileList.AddRange(nonTransitivePathsInRepo.Select(p => p.NormalizePathToUnix()));
|
1108
1133
|
|
1109
1134
|
// use the MSBuild-evaluated value so we don't have to try to manually parse XML
|
1110
1135
|
IEnumerable<ProjectProperty> targetFrameworkProperties = project.Properties.Where(p => p.Name.Equals("TargetFramework", StringComparison.OrdinalIgnoreCase)).ToList();
|
@@ -1153,11 +1178,7 @@ internal static partial class MSBuildHelper
|
|
1153
1178
|
}
|
1154
1179
|
}
|
1155
1180
|
|
1156
|
-
var
|
1157
|
-
var buildFiles = buildFileList
|
1158
|
-
.Where(f => f.StartsWith(repoRootPathPrefix, StringComparison.OrdinalIgnoreCase))
|
1159
|
-
.Distinct();
|
1160
|
-
var result = buildFiles
|
1181
|
+
var result = buildFileList
|
1161
1182
|
.Where(File.Exists)
|
1162
1183
|
.Select(path => ProjectBuildFile.Open(repoRootPath, path))
|
1163
1184
|
.ToImmutableArray();
|
@@ -0,0 +1,54 @@
|
|
1
|
+
using System.Globalization;
|
2
|
+
|
3
|
+
using Microsoft.Extensions.Logging;
|
4
|
+
|
5
|
+
using OpenTelemetry;
|
6
|
+
using OpenTelemetry.Logs;
|
7
|
+
|
8
|
+
namespace NuGetUpdater.Core
|
9
|
+
{
|
10
|
+
public class OpenTelemetryLogger : ILogger, IDisposable
|
11
|
+
{
|
12
|
+
private readonly ILoggerFactory _loggerFactory;
|
13
|
+
private readonly Microsoft.Extensions.Logging.ILogger _logger;
|
14
|
+
|
15
|
+
public OpenTelemetryLogger()
|
16
|
+
{
|
17
|
+
_loggerFactory = LoggerFactory.Create(builder =>
|
18
|
+
{
|
19
|
+
builder.AddOpenTelemetry(logging =>
|
20
|
+
{
|
21
|
+
logging.AddProcessor(new SimpleLogRecordExportProcessor(new CustomConsoleExporter()));
|
22
|
+
logging.AddOtlpExporter();
|
23
|
+
});
|
24
|
+
});
|
25
|
+
|
26
|
+
_logger = _loggerFactory.CreateLogger<OpenTelemetryLogger>();
|
27
|
+
}
|
28
|
+
|
29
|
+
public void LogRaw(string message)
|
30
|
+
{
|
31
|
+
_logger.LogInformation(message);
|
32
|
+
}
|
33
|
+
|
34
|
+
public void Dispose()
|
35
|
+
{
|
36
|
+
_loggerFactory?.Dispose();
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
// We do this because the exporter that comes from AddConsoleExporter() prepends "LogRecord.Timestamp" in front of strings
|
41
|
+
internal class CustomConsoleExporter : BaseExporter<LogRecord>
|
42
|
+
{
|
43
|
+
public override ExportResult Export(in Batch<LogRecord> batch)
|
44
|
+
{
|
45
|
+
foreach (var logRecord in batch)
|
46
|
+
{
|
47
|
+
Console.WriteLine(logRecord.Body ?? string.Empty);
|
48
|
+
}
|
49
|
+
|
50
|
+
return ExportResult.Success;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
}
|