diff --git a/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Linux.verified.txt b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Linux.verified.txt
new file mode 100644
index 00000000000..7e88eaa0b95
--- /dev/null
+++ b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Linux.verified.txt
@@ -0,0 +1,12 @@
+]9;4;3;\ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+[?25l[1F
+[?25h
+Build summary:
+ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+
+Build [31;1mfailed with 1 error(s) and 1 warning(s)[m in 5.0s
+]9;4;0;\
\ No newline at end of file
diff --git a/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.OSX.verified.txt b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.OSX.verified.txt
new file mode 100644
index 00000000000..42a61e2fbbb
--- /dev/null
+++ b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.OSX.verified.txt
@@ -0,0 +1,12 @@
+ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+[?25l[1F
+[?25h
+Build summary:
+ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+
+Build [31;1mfailed with 1 error(s) and 1 warning(s)[m in 5.0s
+
diff --git a/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Windows.verified.txt b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Windows.verified.txt
new file mode 100644
index 00000000000..7e88eaa0b95
--- /dev/null
+++ b/src/MSBuild.UnitTests/Snapshots/TerminalLogger_Tests.PrintDetailedBuildSummary_FailedWithErrorAndWarning.Windows.verified.txt
@@ -0,0 +1,12 @@
+]9;4;3;\ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+[?25l[1F
+[?25h
+Build summary:
+ project [31;1mfailed with 1 error(s) and 1 warning(s)[m (0.2s)
+ directory/[1mfile[m(1,2,3,4): [33;1mwarning[m [33;1mAA0000[m: Warning!
+ directory/[1mfile[m(1,2,3,4): [31;1merror[m [31;1mAA0000[m: Error!
+
+Build [31;1mfailed with 1 error(s) and 1 warning(s)[m in 5.0s
+]9;4;0;\
\ No newline at end of file
diff --git a/src/MSBuild.UnitTests/TerminalLogger_Tests.cs b/src/MSBuild.UnitTests/TerminalLogger_Tests.cs
index bfcf0ddf585..a97f2c683cc 100644
--- a/src/MSBuild.UnitTests/TerminalLogger_Tests.cs
+++ b/src/MSBuild.UnitTests/TerminalLogger_Tests.cs
@@ -414,6 +414,26 @@ public Task PrintBuildSummary_FailedWithErrors()
return Verify(_outputWriter.ToString(), _settings).UniqueForOSPlatform();
}
+ [Fact]
+ public Task PrintDetailedBuildSummary_FailedWithErrorAndWarning()
+ {
+ string? originalParameters = _terminallogger.Parameters;
+ _terminallogger.Parameters = "SUMMARY";
+ _terminallogger.ParseParameters();
+
+ InvokeLoggerCallbacksForSimpleProject(succeeded: false, () =>
+ {
+ WarningRaised?.Invoke(_eventSender, MakeWarningEventArgs("Warning!"));
+ ErrorRaised?.Invoke(_eventSender, MakeErrorEventArgs("Error!"));
+ });
+
+ // Restore original parameters
+ _terminallogger.Parameters = originalParameters;
+ _terminallogger.ParseParameters();
+
+ return Verify(_outputWriter.ToString(), _settings).UniqueForOSPlatform();
+ }
+
[Fact]
public Task PrintBuildSummary_FailedWithErrorsAndWarnings()
{
diff --git a/src/MSBuild/Resources/Strings.resx b/src/MSBuild/Resources/Strings.resx
index 0a0ac48dc13..ece0160d846 100644
--- a/src/MSBuild/Resources/Strings.resx
+++ b/src/MSBuild/Resources/Strings.resx
@@ -1661,6 +1661,12 @@
's' should reflect the localized abbreviation for seconds
+
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
+
+
failed with {0} error(s)
diff --git a/src/MSBuild/Resources/xlf/Strings.cs.xlf b/src/MSBuild/Resources/xlf/Strings.cs.xlf
index f3239abb2cb..ae1cc82bcde 100644
--- a/src/MSBuild/Resources/xlf/Strings.cs.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.cs.xlf
@@ -65,6 +65,13 @@
akce proběhla úspěšně s {0} upozorněním(i).
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.de.xlf b/src/MSBuild/Resources/xlf/Strings.de.xlf
index d7fb58897c7..9a6f40c211a 100644
--- a/src/MSBuild/Resources/xlf/Strings.de.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.de.xlf
@@ -65,6 +65,13 @@
erfolgreich mit {0} Warnung(en)
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.es.xlf b/src/MSBuild/Resources/xlf/Strings.es.xlf
index fc01707fc5d..a4efc5fbe67 100644
--- a/src/MSBuild/Resources/xlf/Strings.es.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.es.xlf
@@ -65,6 +65,13 @@
correcto con {0} advertencias
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.fr.xlf b/src/MSBuild/Resources/xlf/Strings.fr.xlf
index 83094e546db..25303575605 100644
--- a/src/MSBuild/Resources/xlf/Strings.fr.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.fr.xlf
@@ -65,6 +65,13 @@
a réussi avec {0} avertissement(s)
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.it.xlf b/src/MSBuild/Resources/xlf/Strings.it.xlf
index 6c513308d99..1d6ba50eb0d 100644
--- a/src/MSBuild/Resources/xlf/Strings.it.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.it.xlf
@@ -65,6 +65,13 @@
completato con {0} avvisi
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.ja.xlf b/src/MSBuild/Resources/xlf/Strings.ja.xlf
index 6755b1fc171..d0ddddead98 100644
--- a/src/MSBuild/Resources/xlf/Strings.ja.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.ja.xlf
@@ -65,6 +65,13 @@
{0} 件の警告付きで成功しました
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.ko.xlf b/src/MSBuild/Resources/xlf/Strings.ko.xlf
index 9e8b9de1dfa..8e6560daf49 100644
--- a/src/MSBuild/Resources/xlf/Strings.ko.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.ko.xlf
@@ -65,6 +65,13 @@
{0} 경고와 함께 성공
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.pl.xlf b/src/MSBuild/Resources/xlf/Strings.pl.xlf
index 815886c7de9..a42e0e4f5e5 100644
--- a/src/MSBuild/Resources/xlf/Strings.pl.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.pl.xlf
@@ -65,6 +65,13 @@
zakończono powodzeniem, z ostrzeżeniami w liczbie: {0}
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf b/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf
index d5738d0f8e9..be0a3cfcdf5 100644
--- a/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.pt-BR.xlf
@@ -65,6 +65,13 @@
êxito(s) com {0} aviso(s)
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.ru.xlf b/src/MSBuild/Resources/xlf/Strings.ru.xlf
index eabd3b267b5..a6abaa1f4a0 100644
--- a/src/MSBuild/Resources/xlf/Strings.ru.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.ru.xlf
@@ -65,6 +65,13 @@
успешно выполнено с предупреждениями ({0})
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.tr.xlf b/src/MSBuild/Resources/xlf/Strings.tr.xlf
index eb4eb23bfba..5ba264c7cc6 100644
--- a/src/MSBuild/Resources/xlf/Strings.tr.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.tr.xlf
@@ -65,6 +65,13 @@
{0} uyarıyla başarılı oldu
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf b/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf
index 3f343348633..921a7a50e3f 100644
--- a/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.zh-Hans.xlf
@@ -65,6 +65,13 @@
成功,出现 {0} 警告
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf b/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf
index f14b8436e8b..e83d5bbd6d7 100644
--- a/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf
+++ b/src/MSBuild/Resources/xlf/Strings.zh-Hant.xlf
@@ -65,6 +65,13 @@
成功但有 {0} 個警告
Part of Terminal Logger summary message: "Build {BuildResult_X} in {duration}s"
+
+
+
+ Build summary:
+ Build summary:
+
+ A header used by Terminal Logger to introduce the build summary.
diff --git a/src/MSBuild/TerminalLogger/Project.cs b/src/MSBuild/TerminalLogger/Project.cs
index eabfd989c3e..e32d3686dc7 100644
--- a/src/MSBuild/TerminalLogger/Project.cs
+++ b/src/MSBuild/TerminalLogger/Project.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
namespace Microsoft.Build.Logging.TerminalLogger;
@@ -12,12 +13,15 @@ namespace Microsoft.Build.Logging.TerminalLogger;
///
internal sealed class Project
{
+ private List? _buildMessages;
+
///
/// Initialized a new with the given .
///
/// The target framework of the project or null if not multi-targeting.
- public Project(string? targetFramework, StopwatchAbstraction? stopwatch)
+ public Project(string projectFile, string? targetFramework, StopwatchAbstraction? stopwatch)
{
+ File = projectFile;
TargetFramework = targetFramework;
if (stopwatch is not null)
@@ -31,6 +35,8 @@ public Project(string? targetFramework, StopwatchAbstraction? stopwatch)
}
}
+ public string File { get; }
+
///
/// A stopwatch to time the build of the project.
///
@@ -56,17 +62,59 @@ public Project(string? targetFramework, StopwatchAbstraction? stopwatch)
///
public bool IsCachePluginProject { get; set; }
+ ///
+ /// True if project built successfully; otherwise false.
+ ///
+ public bool Succeeded { get; set; }
+
+ ///
+ /// The number of errors raised during the build of the project.
+ ///
+ public int ErrorCount { get; private set; }
+
+ ///
+ /// The number of warnings raised during the build of the project.
+ ///
+ public int WarningCount { get; private set; }
+
+ ///
+ /// True when the project has error or warning build messages; otherwise false.
+ ///
+ public bool HasErrorsOrWarnings => ErrorCount > 0 || WarningCount > 0;
+
///
/// A lazily initialized list of build messages/warnings/errors raised during the build.
///
- public List? BuildMessages { get; private set; }
+ public IReadOnlyList? BuildMessages => _buildMessages;
///
/// Adds a build message of the given severity to .
///
public void AddBuildMessage(MessageSeverity severity, string message)
{
- BuildMessages ??= new List();
- BuildMessages.Add(new BuildMessage(severity, message));
+ _buildMessages ??= new List();
+ _buildMessages.Add(new BuildMessage(severity, message));
+
+ if (severity == MessageSeverity.Error)
+ {
+ ErrorCount++;
+ }
+ else if (severity == MessageSeverity.Warning)
+ {
+ WarningCount++;
+ }
+ }
+
+ ///
+ /// Filters the build messages to only include errors and warnings.
+ ///
+ /// A sequence of error and warning build messages.
+ public IEnumerable GetBuildErrorAndWarningMessages()
+ {
+ return BuildMessages is null ?
+ Enumerable.Empty() :
+ BuildMessages.Where(message =>
+ message.Severity == MessageSeverity.Error ||
+ message.Severity == MessageSeverity.Warning);
}
}
diff --git a/src/MSBuild/TerminalLogger/TerminalLogger.cs b/src/MSBuild/TerminalLogger/TerminalLogger.cs
index 85a4baf1e08..d4dc4346cf9 100644
--- a/src/MSBuild/TerminalLogger/TerminalLogger.cs
+++ b/src/MSBuild/TerminalLogger/TerminalLogger.cs
@@ -221,6 +221,11 @@ public ProjectContext(BuildEventContext context)
///
private bool _showCommandLine = false;
+ ///
+ /// Indicates whether to show the build summary.
+ ///
+ private bool? _showSummary;
+
private uint? _originalConsoleMode;
///
@@ -320,6 +325,12 @@ private void ApplyParameter(string parameterName, string? parameterValue)
case "SHOWCOMMANDLINE":
TryApplyShowCommandLineParameter(parameterValue);
break;
+ case "SUMMARY":
+ _showSummary = true;
+ break;
+ case "NOSUMMARY":
+ _showSummary = false;
+ break;
}
}
@@ -334,9 +345,7 @@ private void ApplyVerbosityParameter(string? parameterValue)
}
else
{
- string errorCode;
- string helpKeyword;
- string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(out errorCode, out helpKeyword, "InvalidVerbosity", parameterValue);
+ string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(out string errorCode, out string helpKeyword, "InvalidVerbosity", parameterValue);
throw new LoggerException(message, null, errorCode, helpKeyword);
}
}
@@ -401,15 +410,13 @@ private void BuildFinished(object sender, BuildFinishedEventArgs e)
_cts.Cancel();
_refresher?.Join();
- _projects.Clear();
-
Terminal.BeginUpdate();
try
{
if (Verbosity > LoggerVerbosity.Quiet)
{
string duration = (e.Timestamp - _buildStartTime).TotalSeconds.ToString("F1");
- string buildResult = RenderBuildResult(e.Succeeded, _buildErrorsCount, _buildWarningsCount);
+ string buildResult = GetBuildResultString(e.Succeeded, _buildErrorsCount, _buildWarningsCount);
Terminal.WriteLine("");
if (_testRunSummaries.Any())
@@ -437,6 +444,11 @@ private void BuildFinished(object sender, BuildFinishedEventArgs e)
Terminal.WriteLine(string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", summaryAndTotalText, failedText, passedText, skippedText, durationText));
}
+ if (_showSummary == true)
+ {
+ RenderBuildSummary();
+ }
+
if (_restoreFailed)
{
Terminal.WriteLine(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("RestoreCompleteWithMessage",
@@ -461,6 +473,7 @@ private void BuildFinished(object sender, BuildFinishedEventArgs e)
Terminal.EndUpdate();
}
+ _projects.Clear();
_testRunSummaries.Clear();
_buildErrorsCount = 0;
_buildWarningsCount = 0;
@@ -469,6 +482,33 @@ private void BuildFinished(object sender, BuildFinishedEventArgs e)
_testEndTime = null;
}
+ private void RenderBuildSummary()
+ {
+ if (_buildErrorsCount == 0 && _buildWarningsCount == 0)
+ {
+ // No errors/warnings to display.
+ return;
+ }
+
+ Terminal.WriteLine(ResourceUtilities.GetResourceString("BuildSummary"));
+
+ foreach (Project project in _projects.Values.Where(p => p.HasErrorsOrWarnings))
+ {
+ string duration = project.Stopwatch.ElapsedSeconds.ToString("F1");
+ string buildResult = GetBuildResultString(project.Succeeded, project.ErrorCount, project.WarningCount);
+ string projectHeader = GetProjectFinishedHeader(project, buildResult, duration);
+
+ Terminal.WriteLine(projectHeader);
+
+ foreach (BuildMessage buildMessage in project.GetBuildErrorAndWarningMessages())
+ {
+ Terminal.WriteLine($"{DoubleIndentation}{buildMessage.Message}");
+ }
+ }
+
+ Terminal.WriteLine(string.Empty);
+ }
+
private void StatusEventRaised(object sender, BuildStatusEventArgs e)
{
if (e is BuildCanceledEventArgs buildCanceledEventArgs)
@@ -496,7 +536,7 @@ private void ProjectStarted(object sender, ProjectStartedEventArgs e)
{
targetFramework = null;
}
- _projects[c] = new(targetFramework, CreateStopwatch?.Invoke());
+ _projects[c] = new(e.ProjectFile!, targetFramework, CreateStopwatch?.Invoke());
// First ever restore in the build is starting.
if (e.TargetNames == "Restore" && !_restoreFinished)
@@ -535,6 +575,8 @@ private void ProjectFinished(object sender, ProjectFinishedEventArgs e)
if (_projects.TryGetValue(c, out Project? project))
{
+ project.Succeeded = e.Succeeded;
+ project.Stopwatch.Stop();
lock (_lock)
{
Terminal.BeginUpdate();
@@ -545,26 +587,16 @@ private void ProjectFinished(object sender, ProjectFinishedEventArgs e)
string duration = project.Stopwatch.ElapsedSeconds.ToString("F1");
ReadOnlyMemory? outputPath = project.OutputPath;
- string projectFile = e.ProjectFile is not null ?
- Path.GetFileNameWithoutExtension(e.ProjectFile) :
- string.Empty;
-
// Build result. One of 'failed', 'succeeded with warnings', or 'succeeded' depending on the build result and diagnostic messages
// reported during build.
- int countErrors = project.BuildMessages?.Count(m => m.Severity == MessageSeverity.Error) ?? 0;
- int countWarnings = project.BuildMessages?.Count(m => m.Severity == MessageSeverity.Warning) ?? 0;
-
- string buildResult = RenderBuildResult(e.Succeeded, countErrors, countWarnings);
-
- bool haveErrors = countErrors > 0;
- bool haveWarnings = countWarnings > 0;
+ string buildResult = GetBuildResultString(project.Succeeded, project.ErrorCount, project.WarningCount);
// Check if we're done restoring.
if (c == _restoreContext)
{
if (e.Succeeded)
{
- if (haveErrors || haveWarnings)
+ if (project.HasErrorsOrWarnings)
{
Terminal.WriteLine(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("RestoreCompleteWithMessage",
buildResult,
@@ -591,46 +623,8 @@ private void ProjectFinished(object sender, ProjectFinishedEventArgs e)
else if (project.OutputPath is not null || project.BuildMessages is not null || project.IsTestProject)
{
// Show project build complete and its output
- if (project.IsTestProject)
- {
- if (string.IsNullOrEmpty(project.TargetFramework))
- {
- Terminal.Write(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TestProjectFinished_NoTF",
- Indentation,
- projectFile,
- buildResult,
- duration));
- }
- else
- {
- Terminal.Write(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TestProjectFinished_WithTF",
- Indentation,
- projectFile,
- AnsiCodes.Colorize(project.TargetFramework, TargetFrameworkColor),
- buildResult,
- duration));
- }
- }
- else
- {
- if (string.IsNullOrEmpty(project.TargetFramework))
- {
- Terminal.Write(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ProjectFinished_NoTF",
- Indentation,
- projectFile,
- buildResult,
- duration));
- }
- else
- {
- Terminal.Write(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ProjectFinished_WithTF",
- Indentation,
- projectFile,
- AnsiCodes.Colorize(project.TargetFramework, TargetFrameworkColor),
- buildResult,
- duration));
- }
- }
+ string projectFinishedHeader = GetProjectFinishedHeader(project, buildResult, duration);
+ Terminal.Write(projectFinishedHeader);
// Print the output path as a link if we have it.
if (outputPath is not null)
@@ -685,8 +679,8 @@ private void ProjectFinished(object sender, ProjectFinishedEventArgs e)
}
}
- _buildErrorsCount += countErrors;
- _buildWarningsCount += countWarnings;
+ _buildErrorsCount += project.ErrorCount;
+ _buildWarningsCount += project.WarningCount;
DisplayNodes();
}
@@ -698,6 +692,35 @@ private void ProjectFinished(object sender, ProjectFinishedEventArgs e)
}
}
+ private static string GetProjectFinishedHeader(Project project, string buildResult, string duration)
+ {
+ string projectFile = project.File is not null ?
+ Path.GetFileNameWithoutExtension(project.File) :
+ string.Empty;
+
+ if (string.IsNullOrEmpty(project.TargetFramework))
+ {
+ string resourceName = project.IsTestProject ? "TestProjectFinished_NoTF" : "ProjectFinished_NoTF";
+
+ return ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(resourceName,
+ Indentation,
+ projectFile,
+ buildResult,
+ duration);
+ }
+ else
+ {
+ string resourceName = project.IsTestProject ? "TestProjectFinished_WithTF" : "ProjectFinished_WithTF";
+
+ return ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(resourceName,
+ Indentation,
+ projectFile,
+ AnsiCodes.Colorize(project.TargetFramework, TargetFrameworkColor),
+ buildResult,
+ duration);
+ }
+ }
+
///
/// The callback.
///
@@ -1051,12 +1074,12 @@ private void EraseNodes()
#region Helpers
///
- /// Print a build result summary to the output.
+ /// Construct a build result summary string.
///
/// True if the build completed with success.
/// True if the build has logged at least one error.
/// True if the build has logged at least one warning.
- private string RenderBuildResult(bool succeeded, int countErrors, int countWarnings)
+ private static string GetBuildResultString(bool succeeded, int countErrors, int countWarnings)
{
if (!succeeded)
{