Skip to content
Merged
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
40 changes: 40 additions & 0 deletions src/MSBuild.UnitTests/LiveLogger_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,45 @@ public Task PrintBuildSummary_FailedWithErrors()
}

#endregion

[Fact]
public void DisplayNodesShowsCurrent()
{
InvokeLoggerCallbacksForSimpleProject(succeeded: false, async () =>
{
_liveLogger.DisplayNodes();

await Verify(_outputWriter.ToString(), _settings);
});
}

[Fact]
public async Task DisplayNodesOverwritesWithNewTargetFramework()
{
BuildStarted?.Invoke(_eventSender, MakeBuildStartedEventArgs());

ProjectStartedEventArgs pse = MakeProjectStartedEventArgs(_projectFile, "Build");
pse.GlobalProperties = new Dictionary<string, string>() { ["TargetFramework"] = "tfName" };

ProjectStarted?.Invoke(_eventSender, pse);

TargetStarted?.Invoke(_eventSender, MakeTargetStartedEventArgs(_projectFile, "Build"));
TaskStarted?.Invoke(_eventSender, MakeTaskStartedEventArgs(_projectFile, "Task"));

_liveLogger.DisplayNodes();

// This is a bit fast and loose with the events that would be fired
// in a real "stop building that TF for the project and start building
// a new TF of the same project" situation, but it's enough now.
ProjectStartedEventArgs pse2 = MakeProjectStartedEventArgs(_projectFile, "Build");
pse2.GlobalProperties = new Dictionary<string, string>() { ["TargetFramework"] = "tf2" };

ProjectStarted?.Invoke(_eventSender, pse2);
TargetStarted?.Invoke(_eventSender, MakeTargetStartedEventArgs(_projectFile, "Build"));

_liveLogger.DisplayNodes();

await Verify(_outputWriter.ToString(), _settings);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[?25l
project tfName Build (0.0s)
[?25h[?25l
project tf2 Build (0.0s)
[?25h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[?25l
project Build (0.0s)
[?25h
25 changes: 13 additions & 12 deletions src/MSBuild/LiveLogger/LiveLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ private void ThreadProc()
/// Render Nodes section.
/// It shows what all build nodes do.
/// </summary>
private void DisplayNodes()
internal void DisplayNodes()
{
NodesFrame newFrame = new NodesFrame(_nodes, width: Terminal.Width, height: Terminal.Height);

Expand Down Expand Up @@ -740,21 +740,22 @@ public string Render(NodesFrame previousFrame)
if (!previous.SequenceEqual(needed))
{
int commonPrefixLen = previous.CommonPrefixLength(needed);
if (commonPrefixLen == 0)

if (commonPrefixLen != 0 && needed.Slice(0, commonPrefixLen).IndexOf('\x1b') == -1)
{
// whole string
sb.Append(needed);
// no escape codes, so can trivially skip substrings
sb.Append($"{AnsiCodes.CSI}{commonPrefixLen}{AnsiCodes.MoveForward}");
sb.Append(needed.Slice(commonPrefixLen));
}
else
{
// set cursor to different char
sb.Append($"{AnsiCodes.CSI}{commonPrefixLen}{AnsiCodes.MoveForward}");
sb.Append(needed.Slice(commonPrefixLen));
// Shall we clear rest of line
if (needed.Length < previous.Length)
{
sb.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}");
}
sb.Append(needed);
}

// Shall we clear rest of line
if (needed.Length < previous.Length)
{
sb.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/MSBuild/LiveLogger/Terminal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void Write(string text)
}
else
{
Console.Write(text);
Output.Write(text);
}
}

Expand Down