process/src/Process/Buffered/BufferedCommandExtensions.cs
Louis Seubert 4aa6c48530
Some checks failed
default / default (8.0) (push) Failing after 21s
feat: initial project commit
2024-04-27 20:16:39 +02:00

95 lines
No EOL
2.9 KiB
C#

using System.Text;
namespace Geekeey.Extensions.Process.Buffered;
/// <summary>
/// Buffered execution model.
/// </summary>
public static class BufferedCommandExtensions
{
/// <summary>
/// Executes the command asynchronously with buffering.
/// Data written to the standard output and standard error streams is decoded as text
/// and returned as part of the result object.
/// </summary>
/// <remarks>
/// This method can be awaited.
/// </remarks>
public static CommandTask<BufferedCommandResult> ExecuteBufferedAsync(this Command command,
Encoding standardOutputEncoding, Encoding standardErrorEncoding, CancellationToken cancellationToken = default)
{
var stdOutBuffer = new StringBuilder();
var stdErrBuffer = new StringBuilder();
var stdOutPipe = PipeTarget.Merge(
command.StandardOutputPipe,
PipeTarget.ToStringBuilder(stdOutBuffer, standardOutputEncoding)
);
var stdErrPipe = PipeTarget.Merge(
command.StandardErrorPipe,
PipeTarget.ToStringBuilder(stdErrBuffer, standardErrorEncoding)
);
var commandWithPipes = command
.WithStandardOutputPipe(stdOutPipe)
.WithStandardErrorPipe(stdErrPipe);
return commandWithPipes
.ExecuteAsync(cancellationToken)
.Bind(async task =>
{
try
{
var result = await task;
return new BufferedCommandResult(
result.ExitCode,
result.StartTime,
result.ExitTime,
stdOutBuffer.ToString(),
stdErrBuffer.ToString()
);
}
catch (CommandExecutionException exception)
{
var message = $"""
Command execution failed, see the inner exception for details.
Standard error:
{stdErrBuffer.ToString().Trim()}
""";
throw new CommandExecutionException(exception.Command, exception.ExitCode, message, exception);
}
});
}
/// <summary>
/// Executes the command asynchronously with buffering.
/// Data written to the standard output and standard error streams is decoded as text
/// and returned as part of the result object.
/// </summary>
/// <remarks>
/// This method can be awaited.
/// </remarks>
public static CommandTask<BufferedCommandResult> ExecuteBufferedAsync(this Command command,
Encoding encoding, CancellationToken cancellationToken = default)
{
return command.ExecuteBufferedAsync(encoding, encoding, cancellationToken);
}
/// <summary>
/// Executes the command asynchronously with buffering.
/// Data written to the standard output and standard error streams is decoded as text
/// and returned as part of the result object.
/// Uses <see cref="Console.OutputEncoding" /> for decoding.
/// </summary>
/// <remarks>
/// This method can be awaited.
/// </remarks>
public static CommandTask<BufferedCommandResult> ExecuteBufferedAsync(this Command command,
CancellationToken cancellationToken = default)
{
return command.ExecuteBufferedAsync(Console.OutputEncoding, cancellationToken);
}
}