From 6b8abf88e2abb8aaa6f42cc33e631d8327d852ba Mon Sep 17 00:00:00 2001
From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com>
Date: Fri, 25 Oct 2024 03:57:40 +0300
Subject: [PATCH] Use `Encoding.Default` instead of `Console.OutputEncoding` as
 the default encoding (#262)

---
 CliWrap.Tests/CancellationSpecs.cs            | 12 ++++++------
 CliWrap/Buffered/BufferedCommandExtensions.cs |  4 ++--
 CliWrap/Command.PipeOperators.cs              | 16 ++++++++--------
 .../PullEventStreamCommandExtensions.cs       |  7 +++++--
 .../PushEventStreamCommandExtensions.cs       |  4 ++--
 CliWrap/PipeTarget.cs                         | 19 +++++++++++--------
 Readme.md                                     |  2 +-
 7 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/CliWrap.Tests/CancellationSpecs.cs b/CliWrap.Tests/CancellationSpecs.cs
index 6f4ed0c0..d8e0c530 100644
--- a/CliWrap.Tests/CancellationSpecs.cs
+++ b/CliWrap.Tests/CancellationSpecs.cs
@@ -141,8 +141,8 @@ public async Task I_can_execute_a_command_with_buffering_and_cancel_it_gracefull
         var ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(
             async () =>
                 await cmd.ExecuteBufferedAsync(
-                    Console.OutputEncoding,
-                    Console.OutputEncoding,
+                    Encoding.Default,
+                    Encoding.Default,
                     CancellationToken.None,
                     cts.Token
                 )
@@ -209,8 +209,8 @@ public async Task I_can_execute_a_command_as_a_pull_based_event_stream_and_cance
         {
             await foreach (
                 var cmdEvent in cmd.ListenAsync(
-                    Console.OutputEncoding,
-                    Console.OutputEncoding,
+                    Encoding.Default,
+                    Encoding.Default,
                     CancellationToken.None,
                     cts.Token
                 )
@@ -289,8 +289,8 @@ public async Task I_can_execute_a_command_as_a_push_based_event_stream_and_cance
         var ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(
             async () =>
                 await cmd.Observe(
-                        Console.OutputEncoding,
-                        Console.OutputEncoding,
+                        Encoding.Default,
+                        Encoding.Default,
                         CancellationToken.None,
                         cts.Token
                     )
diff --git a/CliWrap/Buffered/BufferedCommandExtensions.cs b/CliWrap/Buffered/BufferedCommandExtensions.cs
index 4cf9ff8c..290bd0ed 100644
--- a/CliWrap/Buffered/BufferedCommandExtensions.cs
+++ b/CliWrap/Buffered/BufferedCommandExtensions.cs
@@ -121,7 +121,7 @@ public static CommandTask<BufferedCommandResult> ExecuteBufferedAsync(
     /// 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.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     /// <remarks>
     /// This method can be awaited.
@@ -131,6 +131,6 @@ public static CommandTask<BufferedCommandResult> ExecuteBufferedAsync(
         CancellationToken cancellationToken = default
     )
     {
-        return command.ExecuteBufferedAsync(Console.OutputEncoding, cancellationToken);
+        return command.ExecuteBufferedAsync(Encoding.Default, cancellationToken);
     }
 }
diff --git a/CliWrap/Command.PipeOperators.cs b/CliWrap/Command.PipeOperators.cs
index 54fa75e0..91f6d35c 100644
--- a/CliWrap/Command.PipeOperators.cs
+++ b/CliWrap/Command.PipeOperators.cs
@@ -25,7 +25,7 @@ public partial class Command
 
     /// <summary>
     /// Creates a new command that pipes its standard output to the specified string builder.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(Command source, StringBuilder target) =>
@@ -34,7 +34,7 @@ public partial class Command
     /// <summary>
     /// Creates a new command that pipes its standard output line-by-line to the specified
     /// asynchronous delegate.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(
@@ -45,7 +45,7 @@ Func<string, CancellationToken, Task> target
     /// <summary>
     /// Creates a new command that pipes its standard output line-by-line to the specified
     /// asynchronous delegate.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(Command source, Func<string, Task> target) =>
@@ -54,7 +54,7 @@ Func<string, CancellationToken, Task> target
     /// <summary>
     /// Creates a new command that pipes its standard output line-by-line to the specified
     /// synchronous delegate.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(Command source, Action<string> target) =>
@@ -81,7 +81,7 @@ Func<string, CancellationToken, Task> target
     /// <summary>
     /// Creates a new command that pipes its standard output and standard error to the
     /// specified string builders.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(
@@ -94,7 +94,7 @@ Func<string, CancellationToken, Task> target
     /// <summary>
     /// Creates a new command that pipes its standard output and standard error line-by-line
     /// to the specified asynchronous delegates.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(
@@ -108,7 +108,7 @@ Func<string, CancellationToken, Task> stdErr
     /// <summary>
     /// Creates a new command that pipes its standard output and standard error line-by-line
     /// to the specified asynchronous delegates.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(
@@ -119,7 +119,7 @@ Func<string, CancellationToken, Task> stdErr
     /// <summary>
     /// Creates a new command that pipes its standard output and standard error line-by-line
     /// to the specified synchronous delegates.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     [Pure]
     public static Command operator |(
diff --git a/CliWrap/EventStream/PullEventStreamCommandExtensions.cs b/CliWrap/EventStream/PullEventStreamCommandExtensions.cs
index 6d4fd15f..b6a01269 100644
--- a/CliWrap/EventStream/PullEventStreamCommandExtensions.cs
+++ b/CliWrap/EventStream/PullEventStreamCommandExtensions.cs
@@ -67,6 +67,7 @@ await channel
             forcefulCancellationToken,
             gracefulCancellationToken
         );
+
         yield return new StartedCommandEvent(commandTask.ProcessId);
 
         // Close the channel once the command completes, so that ReceiveAsync() can finish
@@ -83,7 +84,9 @@ await channel
         await foreach (
             var cmdEvent in channel.ReceiveAsync(forcefulCancellationToken).ConfigureAwait(false)
         )
+        {
             yield return cmdEvent;
+        }
 
         var exitCode = await commandTask.Select(r => r.ExitCode).ConfigureAwait(false);
         yield return new ExitedCommandEvent(exitCode);
@@ -127,7 +130,7 @@ public static IAsyncEnumerable<CommandEvent> ListenAsync(
 
     /// <summary>
     /// Executes the command as a pull-based event stream.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     /// <remarks>
     /// Use pattern matching to handle specific instances of <see cref="CommandEvent" />.
@@ -137,6 +140,6 @@ public static IAsyncEnumerable<CommandEvent> ListenAsync(
         CancellationToken cancellationToken = default
     )
     {
-        return command.ListenAsync(Console.OutputEncoding, cancellationToken);
+        return command.ListenAsync(Encoding.Default, cancellationToken);
     }
 }
diff --git a/CliWrap/EventStream/PushEventStreamCommandExtensions.cs b/CliWrap/EventStream/PushEventStreamCommandExtensions.cs
index 1f95f126..d398726b 100644
--- a/CliWrap/EventStream/PushEventStreamCommandExtensions.cs
+++ b/CliWrap/EventStream/PushEventStreamCommandExtensions.cs
@@ -122,7 +122,7 @@ public static IObservable<CommandEvent> Observe(
 
     /// <summary>
     /// Executes the command as a push-based event stream.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     /// <remarks>
     /// Use pattern matching to handle specific instances of <see cref="CommandEvent" />.
@@ -132,6 +132,6 @@ public static IObservable<CommandEvent> Observe(
         CancellationToken cancellationToken = default
     )
     {
-        return command.Observe(Console.OutputEncoding, cancellationToken);
+        return command.Observe(Encoding.Default, cancellationToken);
     }
 }
diff --git a/CliWrap/PipeTarget.cs b/CliWrap/PipeTarget.cs
index 4ed7946b..1034421d 100644
--- a/CliWrap/PipeTarget.cs
+++ b/CliWrap/PipeTarget.cs
@@ -217,10 +217,10 @@ public static PipeTarget ToStringBuilder(StringBuilder stringBuilder, Encoding e
 
     /// <summary>
     /// Creates a pipe target that writes to the specified string builder.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     public static PipeTarget ToStringBuilder(StringBuilder stringBuilder) =>
-        ToStringBuilder(stringBuilder, Console.OutputEncoding);
+        ToStringBuilder(stringBuilder, Encoding.Default);
 
     /// <summary>
     /// Creates a pipe target that invokes the specified asynchronous delegate on every line written to the stream.
@@ -239,19 +239,22 @@ Encoding encoding
                     BufferSizes.StreamReader,
                     true
                 );
+
                 await foreach (
                     var line in reader.ReadAllLinesAsync(cancellationToken).ConfigureAwait(false)
                 )
+                {
                     await handleLineAsync(line, cancellationToken).ConfigureAwait(false);
+                }
             }
         );
 
     /// <summary>
     /// Creates a pipe target that invokes the specified asynchronous delegate on every line written to the stream.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     public static PipeTarget ToDelegate(Func<string, CancellationToken, Task> handleLineAsync) =>
-        ToDelegate(handleLineAsync, Console.OutputEncoding);
+        ToDelegate(handleLineAsync, Encoding.Default);
 
     /// <summary>
     /// Creates a pipe target that invokes the specified asynchronous delegate on every line written to the stream.
@@ -261,10 +264,10 @@ public static PipeTarget ToDelegate(Func<string, Task> handleLineAsync, Encoding
 
     /// <summary>
     /// Creates a pipe target that invokes the specified asynchronous delegate on every line written to the stream.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     public static PipeTarget ToDelegate(Func<string, Task> handleLineAsync) =>
-        ToDelegate(handleLineAsync, Console.OutputEncoding);
+        ToDelegate(handleLineAsync, Encoding.Default);
 
     /// <summary>
     /// Creates a pipe target that invokes the specified synchronous delegate on every line written to the stream.
@@ -281,10 +284,10 @@ public static PipeTarget ToDelegate(Action<string> handleLine, Encoding encoding
 
     /// <summary>
     /// Creates a pipe target that invokes the specified synchronous delegate on every line written to the stream.
-    /// Uses <see cref="Console.OutputEncoding" /> for decoding.
+    /// Uses <see cref="Encoding.Default" /> for decoding.
     /// </summary>
     public static PipeTarget ToDelegate(Action<string> handleLine) =>
-        ToDelegate(handleLine, Console.OutputEncoding);
+        ToDelegate(handleLine, Encoding.Default);
 
     /// <summary>
     /// Creates a pipe target that replicates data over multiple inner targets.
diff --git a/Readme.md b/Readme.md
index b2765eee..aa581d4a 100644
--- a/Readme.md
+++ b/Readme.md
@@ -531,7 +531,7 @@ var stdOut = result.StandardOutput;
 var stdErr = result.StandardError;
 ```
 
-By default, `ExecuteBufferedAsync()` assumes that the underlying process uses the default encoding (`Console.OutputEncoding`) for writing text to the console.
+By default, `ExecuteBufferedAsync()` assumes that the underlying process uses the default encoding (`Encoding.Default`) for writing text to the console.
 To override this, specify the encoding explicitly by using one of the available overloads:
 
 ```csharp