Argument Fowarding Tests should account for newline added by StreamFowarder. Add an entry to developer guide so command developers will use Console.WriteLine. PR feedback and slight refactoring.
This commit is contained in:
parent
ccaaebf6e5
commit
b8e95a9568
3 changed files with 39 additions and 21 deletions
|
@ -65,3 +65,6 @@ Each command's project root should contain a manpage-style Readme.md that descri
|
|||
#### Add command to packages
|
||||
- Update the `symlinks` property of `packaging/debian/debian_config.json` to include the new command
|
||||
- Update the `$Projects` property in `packaging/osx/scripts/postinstall`
|
||||
|
||||
#### Things to Know
|
||||
- Any added commands are usually invoked through `dotnet {command}`. As a result of this, stdout and stderr are redirected through the driver (`dotnet`) and buffered by line. As a result of this, child commands should use Console.WriteLine in any cases where they expect output to be written immediately. Any uses of Console.Write should be followed by Console.WriteLine to ensure the output is written.
|
|
@ -2,11 +2,15 @@ using System;
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils
|
||||
{
|
||||
public sealed class StreamForwarder
|
||||
{
|
||||
private static readonly char[] s_ignoreCharacters = new char[] { '\r' };
|
||||
private static readonly char s_flushBuilderCharacter = '\n';
|
||||
|
||||
private StringBuilder _builder;
|
||||
private StringWriter _capture;
|
||||
private Action<string> _write;
|
||||
|
@ -22,10 +26,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
|
||||
public StreamForwarder Capture()
|
||||
{
|
||||
if (_capture != null)
|
||||
{
|
||||
throw new InvalidOperationException("Already capturing stream!");
|
||||
}
|
||||
ThrowIfCaptureSet();
|
||||
|
||||
_capture = new StringWriter();
|
||||
|
||||
return this;
|
||||
|
@ -33,15 +35,9 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
|
||||
public StreamForwarder ForwardTo(Action<string> writeLine)
|
||||
{
|
||||
if (writeLine == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(writeLine));
|
||||
}
|
||||
ThrowIfNull(writeLine);
|
||||
|
||||
if (_writeLine != null)
|
||||
{
|
||||
throw new InvalidOperationException("WriteLine forwarder set previously");
|
||||
}
|
||||
ThrowIfForwarderSet();
|
||||
|
||||
_writeLine = writeLine;
|
||||
|
||||
|
@ -71,18 +67,13 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
{
|
||||
currentCharacter = buffer[0];
|
||||
|
||||
// Flush per line
|
||||
if (currentCharacter == '\n')
|
||||
if (currentCharacter == s_flushBuilderCharacter)
|
||||
{
|
||||
WriteBuilder();
|
||||
}
|
||||
else
|
||||
else if (! s_ignoreCharacters.Contains(currentCharacter))
|
||||
{
|
||||
// Ignore \r
|
||||
if (currentCharacter != '\r')
|
||||
{
|
||||
_builder.Append(currentCharacter);
|
||||
}
|
||||
_builder.Append(currentCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,5 +105,29 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
_writeLine(str);
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowIfNull(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowIfForwarderSet()
|
||||
{
|
||||
if (_writeLine != null)
|
||||
{
|
||||
throw new InvalidOperationException("WriteLine forwarder set previously");
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowIfCaptureSet()
|
||||
{
|
||||
if (_capture != null)
|
||||
{
|
||||
throw new InvalidOperationException("Already capturing stream!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -206,7 +206,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
|
|||
/// <returns></returns>
|
||||
private string[] ParseReflectorOutput(string reflectorOutput)
|
||||
{
|
||||
return reflectorOutput.Split(',');
|
||||
return reflectorOutput.TrimEnd('\r', '\n').Split(',');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in a new issue