process/src/process/Buffered/BufferedCommandExtensions.cs
Louis Seubert 48c483c568
All checks were successful
release / dotnet-release-workflow (push) Successful in 1m23s
build: initial project release
2026-05-10 10:49:39 +02:00

91 lines
No EOL
3 KiB
C#

// Copyright (c) The Geekeey Authors
// SPDX-License-Identifier: EUPL-1.2
using System.Text;
namespace Geekeey.Process.Buffered;
/// <summary>
/// Buffered execution model.
/// </summary>
public static class BufferedCommandExtensions
{
/// <inheritdoc cref="BufferedCommandExtensions"/>
extension(Command command)
{
/// <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 CommandTask<BufferedCommandResult> ExecuteBufferedAsync(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 CommandTask<BufferedCommandResult> ExecuteBufferedAsync(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 CommandTask<BufferedCommandResult> ExecuteBufferedAsync(CancellationToken cancellationToken = default)
{
return command.ExecuteBufferedAsync(Console.OutputEncoding, cancellationToken);
}
}
}