-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathNodeLoggingContext.cs
More file actions
124 lines (105 loc) · 5.67 KB
/
NodeLoggingContext.cs
File metadata and controls
124 lines (105 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;
#nullable disable
namespace Microsoft.Build.BackEnd.Logging
{
/// <summary>
/// The logging context for an entire node.
/// </summary>
internal class NodeLoggingContext : BuildLoggingContext
{
/// <summary>
/// Used to create the initial, base logging context for the node.
/// </summary>
/// <param name="loggingService">The logging service to use.</param>
/// <param name="nodeId">The </param>
/// <param name="inProcNode"><code>true</code> if this is an in-process node, otherwise <code>false</code>.</param>
internal NodeLoggingContext(ILoggingService loggingService, int nodeId, bool inProcNode)
: base(loggingService, new BuildEventContext(nodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId), inProcNode)
{
ErrorUtilities.VerifyThrow(nodeId != BuildEventContext.InvalidNodeId, "Should not ever be given an invalid NodeId");
// The in-proc node will have its BuildStarted, BuildFinished events sent by the BuildManager itself.
if (!IsInProcNode)
{
LoggingService.LogBuildStarted();
}
this.IsValid = true;
}
/// <summary>
/// Log the completion of a build
/// </summary>
/// <param name="success">Did the build succeed or not</param>
internal void LogBuildFinished(bool success)
{
ErrorUtilities.VerifyThrow(this.IsValid, "Build not started.");
// The in-proc node will have its BuildStarted, BuildFinished events sent by the BuildManager itself.
if (!IsInProcNode)
{
LoggingService.LogBuildFinished(success);
}
this.IsValid = false;
}
/// <summary>
/// Log that a project has started if it has no parent (the first project)
/// </summary>
/// <param name="requestEntry">The build request entry for this project.</param>
/// <returns>The BuildEventContext to use for this project.</returns>
internal ProjectLoggingContext LogProjectStarted(BuildRequestEntry requestEntry)
{
(ProjectStartedEventArgs arg, ProjectLoggingContext ctx) = CreateProjectLoggingContext(requestEntry);
LoggingService.LogProjectStarted(arg);
return ctx;
}
internal (ProjectStartedEventArgs, ProjectLoggingContext) CreateProjectLoggingContext(BuildRequestEntry requestEntry)
{
ErrorUtilities.VerifyThrow(this.IsValid, "Build not started.");
return ProjectLoggingContext.CreateLoggingContext(this, requestEntry);
}
/// <summary>
/// Log that a project has started if it is serviced from the cache
/// </summary>
/// <param name="request">The build request.</param>
/// <param name="configuration">The configuration used to build the request.</param>
/// <returns>The BuildEventContext to use for this project.</returns>
internal ProjectLoggingContext LogProjectStarted(BuildRequest request, BuildRequestConfiguration configuration)
{
ErrorUtilities.VerifyThrow(this.IsValid, "Build not started.");
// Use the persisted ProjectEvaluationId which remains available even when the project is cached.
int evaluationId = configuration?.ProjectEvaluationId ?? BuildEventContext.InvalidEvaluationId;
return new ProjectLoggingContext(this, request, configuration.ProjectFullPath, configuration.ToolsVersion, evaluationId);
}
/// <summary>
/// Logs the project started/finished pair for projects which are skipped entirely because all
/// of their results are available in the cache.
/// </summary>
internal void LogRequestHandledFromCache(BuildRequest request, BuildRequestConfiguration configuration, BuildResult result)
{
ProjectLoggingContext projectLoggingContext = LogProjectStarted(request, configuration);
// When pulling a request from the cache, we want to make sure we log a target skipped event for any targets which
// were used to build the request including default and initial targets.
foreach ((string name, TargetBuiltReason reason) target in configuration.GetTargetsUsedToBuildRequest(request))
{
var targetResult = result[target.name];
bool isFailure = targetResult.ResultCode == TargetResultCode.Failure;
var skippedTargetEventArgs = new TargetSkippedEventArgs(message: null)
{
BuildEventContext = projectLoggingContext.BuildEventContext,
TargetName = target.name,
BuildReason = target.reason,
SkipReason = isFailure ? TargetSkipReason.PreviouslyBuiltUnsuccessfully : TargetSkipReason.PreviouslyBuiltSuccessfully,
OriginallySucceeded = !isFailure,
OriginalBuildEventContext = (targetResult as TargetResult)?.OriginalBuildEventContext
};
projectLoggingContext.LogBuildEvent(skippedTargetEventArgs);
if (targetResult.ResultCode == TargetResultCode.Failure)
{
break;
}
}
projectLoggingContext.LogProjectFinished(result.OverallResult == BuildResultCode.Success);
}
}
}