Skip to content
Closed
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
111 changes: 78 additions & 33 deletions cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,20 @@ FUnit Test Runner
else
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
LogFailed($"> [!CAUTION]");

if (failedTestCaseCount > 0)
{
string guidance = options.ShowStackTrace
? string.Empty
: $" Rerun with '{SR.Flag_StackTrace}' option for more detailed log."
;
ConsoleLogger.LogFailed($"> {SR.MarkdownFailed} Total {failedTestCaseCount} test cases were failed.{guidance}");
LogFailed($"> {SR.MarkdownFailed} Total {failedTestCaseCount} test cases were failed.{guidance}");
}

if (failedTestFiles.Count > 0)
{
ConsoleLogger.LogFailed($"> {SR.MarkdownFailed} {failedTestFiles.Count} of {validFUnitFiles.Count} test files were failed to build: {string.Join(", ", failedTestFiles.Select(Path.GetFileName))}");
LogFailed($"> {SR.MarkdownFailed} {failedTestFiles.Count} of {validFUnitFiles.Count} test files were failed to build: {string.Join(", ", failedTestFiles.Select(Path.GetFileName))}");
}

Environment.Exit(1);
Expand All @@ -192,9 +192,9 @@ FUnit Test Runner
else
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
LogFailed($"> [!CAUTION]");
var patterns = fileGlobs.Length > 0 ? string.Join(", ", fileGlobs) : "**/*test*.cs";
ConsoleLogger.LogFailed($"> No valid {FUnit} test files found matching the criteria: `{patterns}`");
LogFailed($"> No valid {FUnit} test files found matching the criteria: `{patterns}`");

Environment.Exit(1);
}
Expand Down Expand Up @@ -229,8 +229,8 @@ int EnsureEnvironment()
if (process == null)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed("> [!CAUTION]");
ConsoleLogger.LogFailed("> Error: 'dotnet' command could not be started. Please ensure .NET SDK is installed and 'dotnet' command is accessible in your system's PATH.");
LogFailed("> [!CAUTION]");
LogFailed("> Error: 'dotnet' command could not be started. Please ensure .NET SDK is installed and 'dotnet' command is accessible in your system's PATH.");
return 1;
}

Expand All @@ -241,17 +241,17 @@ int EnsureEnvironment()
if (string.IsNullOrEmpty(output))
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed("> [!CAUTION]");
ConsoleLogger.LogFailed("> Error: 'dotnet --version' returned empty output.");
LogFailed("> [!CAUTION]");
LogFailed("> Error: 'dotnet --version' returned empty output.");
return 1;
}

string[] versionParts = output.Split('.');
if (versionParts.Length == 0)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: Could not parse .NET SDK version from output: '{output}' (no dot found).");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: Could not parse .NET SDK version from output: '{output}' (no dot found).");
return 1;
}

Expand All @@ -261,9 +261,9 @@ int EnsureEnvironment()
if (majorVersion < MinimumRequiredDotnetVersion)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: .NET SDK major version {output} is less than the required {MinimumRequiredDotnetVersion}.");
ConsoleLogger.LogFailed($"> Please update your .NET SDK to version {MinimumRequiredDotnetVersion} or higher.");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: .NET SDK major version {output} is less than the required {MinimumRequiredDotnetVersion}.");
LogFailed($"> Please update your .NET SDK to version {MinimumRequiredDotnetVersion} or higher.");
return 1;
}

Expand All @@ -275,8 +275,8 @@ int EnsureEnvironment()
else
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: Could not parse .NET SDK major version from output: '{output}'");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: Could not parse .NET SDK major version from output: '{output}'");

return 1;
}
Expand Down Expand Up @@ -329,8 +329,8 @@ static string BuildEscapedArguments(string[] args)
if (exitCode != 0)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: 'dotnet restore' command failed with exit code {exitCode}.");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: 'dotnet restore' command failed with exit code {exitCode}.");

return (exitCode, false);
}
Expand All @@ -349,8 +349,8 @@ static string BuildEscapedArguments(string[] args)
if (exitCode != 0)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: 'dotnet clean' command failed with exit code {exitCode}.");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: 'dotnet clean' command failed with exit code {exitCode}.");

return (exitCode, false);
}
Expand Down Expand Up @@ -378,8 +378,8 @@ static string BuildEscapedArguments(string[] args)
if (exitCode != 0)
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed($"> [!CAUTION]");
ConsoleLogger.LogFailed($"> Error: 'dotnet build' command failed with exit code {exitCode}.");
LogFailed($"> [!CAUTION]");
LogFailed($"> Error: 'dotnet build' command failed with exit code {exitCode}.");

return (exitCode, false);
}
Expand Down Expand Up @@ -455,6 +455,7 @@ async ValueTask<int> RunDotnetAsync(
};

var callCounts = new ProcessCallbackCallCounts();
var capturedStdout = new List<string>();

proc.ErrorDataReceived += (sender, args) =>
{
Expand All @@ -465,23 +466,33 @@ async ValueTask<int> RunDotnetAsync(
}
};

if (requireStdOutLogging)
proc.OutputDataReceived += (sender, args) =>
{
proc.OutputDataReceived += (sender, args) =>
if (args.Data != null)
{
if (args.Data != null)
Interlocked.Increment(ref callCounts.Stdout);
capturedStdout.Add(args.Data);

var colorized = Colorize(args.Data, force: true);
bool hasErrorOrWarning = !string.Equals(args.Data, colorized, StringComparison.Ordinal);

if (hasErrorOrWarning && (Console.IsOutputRedirected || !requireStdOutLogging))
{
Interlocked.Increment(ref callCounts.Stdout);
Console.WriteLine(Colorize(args.Data)); // DO NOT use ConsoleLogger here!
Console.Error.WriteLine(colorized);
}
};
}

if (requireStdOutLogging)
{
Console.WriteLine(ConsoleLogger.EnableMarkdownOutput ? args.Data : colorized); // DO NOT use ConsoleLogger here!
}
}
};

if (!proc.Start())
{
ConsoleLogger.LogInfo();
ConsoleLogger.LogFailed("> [!CAUTION]");
ConsoleLogger.LogFailed("> Error: 'dotnet' command could not be started. Please ensure .NET SDK is installed and 'dotnet' command is accessible in your system's PATH.");
LogFailed("> [!CAUTION]");
LogFailed("> Error: 'dotnet' command could not be started. Please ensure .NET SDK is installed and 'dotnet' command is accessible in your system's PATH.");

return -1;
}
Expand All @@ -491,6 +502,22 @@ async ValueTask<int> RunDotnetAsync(

await proc.WaitForExitAsync();

if (proc.ExitCode != 0 && !requireStdOutLogging)
{
foreach (var line in capturedStdout)
{
Console.Error.WriteLine(Colorize(line, force: true));
}

if (ConsoleLogger.EnableMarkdownOutput)
{
foreach (var line in capturedStdout)
{
Console.WriteLine(line);
}
}
}

if (ConsoleLogger.EnableMarkdownOutput)
{
if (requireDetailsTag)
Expand All @@ -517,6 +544,24 @@ async ValueTask<int> RunDotnetAsync(
}


static void LogFailed(object message)
{
ConsoleLogger.LogFailed(message);
if (Console.IsOutputRedirected)
{
var msg = message?.ToString();
if (msg == null) return;

// FUnit always!!
msg = msg.Replace("\n", $"\n{new string(' ', SR.IndentationAdjustment)}", StringComparison.Ordinal);

Console.Error.Write(SR.AnsiColorFailed);
Console.Error.Write(msg);
Console.Error.WriteLine(SR.AnsiColorReset);
}
}


#if DEBUG
static void RunAllTests()
{
Expand Down Expand Up @@ -569,9 +614,9 @@ static string ColorizeInternal(string text)
}


static string Colorize(string message)
static string Colorize(string message, bool force = false)
{
if (ConsoleLogger.EnableMarkdownOutput || // TODO: use <Span> tag instead of ANSI escape
if ((!force && ConsoleLogger.EnableMarkdownOutput) || // TODO: use <Span> tag instead of ANSI escape
string.IsNullOrWhiteSpace(message))
{
return message;
Expand Down
Loading