Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/Build.UnitTests/TerminalLogger_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.Build.BackEnd.Logging;
using Microsoft.Build.CommandLine.UnitTests;
using Microsoft.Build.Framework;
using Microsoft.Build.Framework.Logging;
using Microsoft.Build.Logging;
using Microsoft.Build.UnitTests.Shared;
using Shouldly;
Expand Down Expand Up @@ -134,6 +135,25 @@ void IBuildEventSink.ShutDown()
[UseInvariantCulture]
public class TerminalLogger_Tests
{
private sealed class ResizableTerminal(TextWriter output, int width, int height) : ITerminal
{
private readonly Terminal _terminal = new(output);

public int Width { get; set; } = width;
public int Height { get; } = height;
public bool SupportsProgressReporting => false;

public void BeginUpdate() => _terminal.BeginUpdate();
public void EndUpdate() => _terminal.EndUpdate();
public void Write(string text) => _terminal.Write(text);
public void Write(ReadOnlySpan<char> text) => _terminal.Write(text);
public void WriteLine(string text) => _terminal.WriteLine(text);
public void WriteLineFitToWidth(ReadOnlySpan<char> text) => _terminal.WriteLineFitToWidth(text);
public void WriteColor(TerminalColor color, string text) => _terminal.WriteColor(color, text);
public void WriteColorLine(TerminalColor color, string text) => _terminal.WriteColorLine(color, text);
public void Dispose() => _terminal.Dispose();
}

private const int _nodeCount = 8;

private const string _immediateMessageString =
Expand Down Expand Up @@ -895,6 +915,29 @@ public void DisplayNodesOverwritesTime()
}
}

[Fact]
public void RefreshChecksForTerminalResizeEveryFrame()
{
using StringWriter output = new();
using ResizableTerminal terminal = new(output, width: 120, height: 40);

MockBuildEventSink eventSource = new(0);
TerminalLogger terminalLogger = new(terminal);
terminalLogger.Initialize(eventSource, _nodeCount);
eventSource.InvokeBuildStarted(MakeBuildStartedEventArgs());
eventSource.InvokeStatusEventRaised(MakeProjectEvalFinishedArgs(_projectFile));
eventSource.InvokeProjectStarted(MakeProjectStartedEventArgs(_projectFile));
eventSource.InvokeTargetStarted(MakeTargetStartedEventArgs(_projectFile, "Build"));
eventSource.InvokeTaskStarted(MakeTaskStartedEventArgs(_projectFile, "Task"));

terminalLogger.Refresh();
output.GetStringBuilder().Clear();
terminal.Width = 40;
terminalLogger.Refresh();

output.ToString().ShouldContain($"{AnsiCodes.CSI}{AnsiCodes.EraseInDisplay}");
}
Comment on lines +924 to +939


[Fact]
public async Task DisplayNodesOverwritesWithNewTargetFramework()
Expand Down
27 changes: 12 additions & 15 deletions src/Build/Logging/TerminalLogger/TerminalLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1472,28 +1472,25 @@ private void ErrorRaised(object sender, BuildErrorEventArgs e)
private void ThreadProc()
{
// 1_000 / 30 is a poor approx of 30Hz
int count = 0;
while (!_cts.Token.WaitHandle.WaitOne(1_000 / 30))
{
count++;
lock (_lock)
{
// Querying the terminal for it's dimensions is expensive, so we only do it every 30 frames e.g. once a second.
if (count >= 30)
{
count = 0;
DisplayNodes();
}
else
{
DisplayNodes(false);
}
}
Refresh();
}

EraseNodes();
}

/// <summary>
/// Refreshes the node display using the current terminal dimensions.
/// </summary>
internal void Refresh()
{
lock (_lock)
{
DisplayNodes();
}
}
Comment on lines +1483 to +1492

/// <summary>
/// Render Nodes section.
/// It shows what all build nodes do.
Expand Down
Loading