diff --git a/src/Cli/dotnet/Commands/CliCommandStrings.resx b/src/Cli/dotnet/Commands/CliCommandStrings.resx index 4086103e08f5..300daaa0169d 100644 --- a/src/Cli/dotnet/Commands/CliCommandStrings.resx +++ b/src/Cli/dotnet/Commands/CliCommandStrings.resx @@ -1962,6 +1962,10 @@ Your project targets multiple frameworks. Specify which framework to run using ' Standard output + + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + Status diff --git a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs index 15cc7ac3c3d6..d0a3cc319e64 100644 --- a/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs +++ b/src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Diagnostics; using System.Globalization; +using System.Text; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; using Microsoft.DotNet.Cli.Commands.Test.IPC.Models; @@ -866,7 +867,7 @@ private static void AppendExecutableSummary(ITerminal terminal, int? exitCode, s terminal.Append(CliCommandStrings.ExitCode); terminal.Append(": "); terminal.AppendLine(exitCode?.ToString(CultureInfo.CurrentCulture) ?? ""); - AppendOutputWhenPresent(CliCommandStrings.StandardOutput, outputData); + AppendOutputWhenPresent(CliCommandStrings.StandardOutput, TruncateOutputForSummary(outputData)); AppendOutputWhenPresent(CliCommandStrings.StandardError, errorData); void AppendOutputWhenPresent(string description, string? output) @@ -878,6 +879,48 @@ void AppendOutputWhenPresent(string description, string? output) } } + // A test host that exits with a failure often prints its entire command-line help — hundreds of + // lines — to standard output. The classic case is an invalid argument (e.g. an unexpected value + // for a known option): the platform reports the error on the first few lines and then dumps the + // full usage, which buries the actual error in noise. Keep the beginning (where the real error + // is) and the end (where trailing diagnostics tend to be) and collapse the middle so the error + // stays easy to find. See https://github.com/dotnet/sdk/issues/52297. + private const int StandardOutputSummaryHeadLines = 30; + private const int StandardOutputSummaryTailLines = 10; + private const int StandardOutputSummaryMaxLines = StandardOutputSummaryHeadLines + StandardOutputSummaryTailLines; + + internal static string? TruncateOutputForSummary(string? output) + { + if (string.IsNullOrWhiteSpace(output)) + { + return output; + } + + string[] lines = output.Split(NewLineStrings, StringSplitOptions.None); + if (lines.Length <= StandardOutputSummaryMaxLines) + { + return output; + } + + int omitted = lines.Length - StandardOutputSummaryMaxLines; + var builder = new StringBuilder(); + for (int i = 0; i < StandardOutputSummaryHeadLines; i++) + { + builder.AppendLine(lines[i]); + } + + builder.AppendLine(string.Format(CultureInfo.CurrentCulture, CliCommandStrings.TestApplicationOutputTruncated, omitted)); + + for (int i = lines.Length - StandardOutputSummaryTailLines; i < lines.Length; i++) + { + builder.AppendLine(lines[i]); + } + + // Drop the trailing newline so the value flows through AppendIndentedLine the same way an + // untruncated payload would. + return builder.ToString().TrimEnd('\r', '\n'); + } + private static string? NormalizeSpecialCharacters(string? text) => text?.Replace('\0', '\x2400') // escape char diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf index 52cf349d9359..b1e58cab23ce 100644 --- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf +++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf @@ -3157,6 +3157,11 @@ Cílem projektu je více architektur. Pomocí parametru {0} určete, která arch Zadejte dočasný adresář pro tento příkaz, který se má stáhnout a extrahujte balíčky NuGet (musí být zabezpečené). + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. + + + ... output truncated, {0} lines omitted ... + ... output truncated, {0} lines omitted ... + {0} is the number of output lines that were omitted from the summary. +