mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d9c7e942c | ||
|
|
0f3abb9db4 | ||
|
|
896482821c | ||
|
|
aa3094ee54 | ||
|
|
712580e3d7 | ||
|
|
c08102f85f |
@@ -1,3 +1,12 @@
|
|||||||
|
### v2.2.2 (30-Jan-2022)
|
||||||
|
|
||||||
|
- Fixed an issue where `ConsoleWriter` and `ConsoleReader` were not properly thread-safe.
|
||||||
|
- Fixed an issue where the analyzer failed to load under certain circumstances when running inside Visual Studio.
|
||||||
|
|
||||||
|
### v2.2.1 (16-Jan-2022)
|
||||||
|
|
||||||
|
- Fixed an issue which caused help text to not show default values for optional parameters. (Thanks [@AliReZa Sabouri](https://github.com/alirezanet))
|
||||||
|
|
||||||
### v2.2 (11-Jan-2022)
|
### v2.2 (11-Jan-2022)
|
||||||
|
|
||||||
- Added support for optional parameters. A parameter can be marked as optional by setting `IsRequired = false` on the attribute. Only one parameter is allowed to be optional and such parameter must be the last in order. (Thanks [@AliReZa Sabouri](https://github.com/alirezanet))
|
- Added support for optional parameters. A parameter can be marked as optional by setting `IsRequired = false` on the attribute. Only one parameter is allowed to be optional and such parameter must be the last in order. (Thanks [@AliReZa Sabouri](https://github.com/alirezanet))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
<Nullable>annotations</Nullable>
|
<Nullable>annotations</Nullable>
|
||||||
<NoWarn>$(NoWarn);RS1025;RS1026</NoWarn>
|
<NoWarn>$(NoWarn);RS1025;RS1026</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -35,6 +35,16 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../CliFx.Analyzers/CliFx.Analyzers.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
|
<ProjectReference Include="../CliFx.Analyzers/CliFx.Analyzers.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
|
||||||
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/CliFx.Analyzers.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/CliFx.Analyzers.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/Microsoft.CodeAnalysis.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/Microsoft.CodeAnalysis.CSharp.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Buffers.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Collections.Immutable.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Memory.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Numerics.Vectors.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Reflection.Metadata.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Text.Encoding.CodePages.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="../CliFx.Analyzers/bin/$(Configuration)/netstandard2.0/System.Threading.Tasks.Extensions.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -206,6 +206,12 @@ internal class HelpConsoleFormatter : ConsoleFormatter
|
|||||||
Write('.');
|
Write('.');
|
||||||
Write(' ');
|
Write(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default value
|
||||||
|
if (!parameterSchema.IsRequired)
|
||||||
|
{
|
||||||
|
WriteDefaultValue(parameterSchema);
|
||||||
|
}
|
||||||
|
|
||||||
WriteLine();
|
WriteLine();
|
||||||
}
|
}
|
||||||
@@ -298,60 +304,65 @@ internal class HelpConsoleFormatter : ConsoleFormatter
|
|||||||
// Default value
|
// Default value
|
||||||
if (!optionSchema.IsRequired)
|
if (!optionSchema.IsRequired)
|
||||||
{
|
{
|
||||||
var defaultValue = _context.CommandDefaultValues.GetValueOrDefault(optionSchema);
|
WriteDefaultValue(optionSchema);
|
||||||
if (defaultValue is not null)
|
|
||||||
{
|
|
||||||
// Non-Scalar
|
|
||||||
if (defaultValue is not string && defaultValue is IEnumerable defaultValues)
|
|
||||||
{
|
|
||||||
var elementType =
|
|
||||||
defaultValues.GetType().TryGetEnumerableUnderlyingType() ??
|
|
||||||
typeof(object);
|
|
||||||
|
|
||||||
if (elementType.IsToStringOverriden())
|
|
||||||
{
|
|
||||||
Write(ConsoleColor.White, "Default: ");
|
|
||||||
|
|
||||||
var isFirst = true;
|
|
||||||
|
|
||||||
foreach (var element in defaultValues)
|
|
||||||
{
|
|
||||||
if (isFirst)
|
|
||||||
{
|
|
||||||
isFirst = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
Write('"');
|
|
||||||
Write(element.ToString(CultureInfo.InvariantCulture));
|
|
||||||
Write('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
Write('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (defaultValue.GetType().IsToStringOverriden())
|
|
||||||
{
|
|
||||||
Write(ConsoleColor.White, "Default: ");
|
|
||||||
|
|
||||||
Write('"');
|
|
||||||
Write(defaultValue.ToString(CultureInfo.InvariantCulture));
|
|
||||||
Write('"');
|
|
||||||
Write('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteLine();
|
WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WriteDefaultValue(IMemberSchema schema)
|
||||||
|
{
|
||||||
|
var defaultValue = _context.CommandDefaultValues.GetValueOrDefault(schema);
|
||||||
|
if (defaultValue is not null)
|
||||||
|
{
|
||||||
|
// Non-Scalar
|
||||||
|
if (defaultValue is not string && defaultValue is IEnumerable defaultValues)
|
||||||
|
{
|
||||||
|
var elementType =
|
||||||
|
defaultValues.GetType().TryGetEnumerableUnderlyingType() ??
|
||||||
|
typeof(object);
|
||||||
|
|
||||||
|
if (elementType.IsToStringOverriden())
|
||||||
|
{
|
||||||
|
Write(ConsoleColor.White, "Default: ");
|
||||||
|
|
||||||
|
var isFirst = true;
|
||||||
|
|
||||||
|
foreach (var element in defaultValues)
|
||||||
|
{
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Write('"');
|
||||||
|
Write(element.ToString(CultureInfo.InvariantCulture));
|
||||||
|
Write('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
Write('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (defaultValue.GetType().IsToStringOverriden())
|
||||||
|
{
|
||||||
|
Write(ConsoleColor.White, "Default: ");
|
||||||
|
|
||||||
|
Write('"');
|
||||||
|
Write(defaultValue.ToString(CultureInfo.InvariantCulture));
|
||||||
|
Write('"');
|
||||||
|
Write('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteCommandChildren()
|
private void WriteCommandChildren()
|
||||||
{
|
{
|
||||||
var childCommandSchemas = _context
|
var childCommandSchemas = _context
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
using System.IO;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CliFx.Infrastructure;
|
namespace CliFx.Infrastructure;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a <see cref="TextReader"/> for reading characters from a console stream.
|
/// Implements a <see cref="TextReader"/> for reading characters from a console stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
// Both the underlying stream AND the stream reader must be synchronized!
|
||||||
|
// https://github.com/Tyrrrz/CliFx/issues/123
|
||||||
public partial class ConsoleReader : StreamReader
|
public partial class ConsoleReader : StreamReader
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,6 +34,77 @@ public partial class ConsoleReader : StreamReader
|
|||||||
: this(console, stream, System.Console.InputEncoding)
|
: this(console, stream, System.Console.InputEncoding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following overrides are required to establish thread-safe behavior
|
||||||
|
// in methods deriving from StreamReader.
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override int Peek() => base.Peek();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override int Read() => base.Read();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override int Read(char[] buffer, int index, int count) =>
|
||||||
|
base.Read(buffer, index, count);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override int ReadBlock(char[] buffer, int index, int count)
|
||||||
|
{
|
||||||
|
return base.ReadBlock(buffer, index, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override string? ReadLine() => base.ReadLine();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override string ReadToEnd() => base.ReadToEnd();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task<int> ReadAsync(char[] buffer, int index, int count)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
return Task.FromResult(Read(buffer, index, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
return Task.FromResult(ReadBlock(buffer, index, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task<string?> ReadLineAsync()
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
return Task.FromResult(ReadLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task<string> ReadToEndAsync()
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
return Task.FromResult(ReadToEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Close() => base.Close();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
protected override void Dispose(bool disposing) => base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class ConsoleReader
|
public partial class ConsoleReader
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using System.IO;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using CliFx.Utils;
|
using CliFx.Utils;
|
||||||
|
|
||||||
namespace CliFx.Infrastructure;
|
namespace CliFx.Infrastructure;
|
||||||
@@ -7,6 +10,8 @@ namespace CliFx.Infrastructure;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a <see cref="TextWriter"/> for writing characters to a console stream.
|
/// Implements a <see cref="TextWriter"/> for writing characters to a console stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
// Both the underlying stream AND the stream writer must be synchronized!
|
||||||
|
// https://github.com/Tyrrrz/CliFx/issues/123
|
||||||
public partial class ConsoleWriter : StreamWriter
|
public partial class ConsoleWriter : StreamWriter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -30,6 +35,239 @@ public partial class ConsoleWriter : StreamWriter
|
|||||||
: this(console, stream, System.Console.OutputEncoding)
|
: this(console, stream, System.Console.OutputEncoding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following overrides are required to establish thread-safe behavior
|
||||||
|
// in methods deriving from StreamWriter.
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(char[] buffer, int index, int count) => base.Write(buffer, index, count);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(char[] buffer) => base.Write(buffer);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(char value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(string? value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(string format, object? arg0) => base.Write(format, arg0);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(string format, object? arg0, object? arg1) =>
|
||||||
|
base.Write(format, arg0, arg1);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(string format, object? arg0, object? arg1, object? arg2) =>
|
||||||
|
base.Write(format, arg0, arg1, arg2);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(string format, params object?[] arg) => base.Write(format, arg);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(bool value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(int value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(long value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(uint value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(ulong value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(float value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(double value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(decimal value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Write(object? value) => base.Write(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteAsync(char[] buffer, int index, int count)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
Write(buffer, index, count);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteAsync(char value)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
Write(value);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteAsync(string? value)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
Write(value);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine() => base.WriteLine();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(char[] buffer, int index, int count) =>
|
||||||
|
base.WriteLine(buffer, index, count);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(char[] buffer) => base.WriteLine(buffer);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(char value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(string? value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(string format, object? arg0) => base.WriteLine(format, arg0);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(string format, object? arg0, object? arg1) =>
|
||||||
|
base.WriteLine(format, arg0, arg1);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(string format, object? arg0, object? arg1, object? arg2) =>
|
||||||
|
base.WriteLine(format, arg0, arg1, arg2);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(string format, params object?[] arg) =>
|
||||||
|
base.WriteLine(format, arg);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(bool value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(int value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(long value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(uint value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(ulong value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(float value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(double value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(decimal value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void WriteLine(object? value) => base.WriteLine(value);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteLineAsync()
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
WriteLine();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteLineAsync(char value)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
WriteLine(value);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteLineAsync(char[] buffer, int index, int count)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
WriteLine(buffer, index, count);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task WriteLineAsync(string? value)
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
WriteLine(value);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Flush() => base.Flush();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override Task FlushAsync()
|
||||||
|
{
|
||||||
|
// Must be non-async to work with locks
|
||||||
|
Flush();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
public override void Close() => base.Close();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[ExcludeFromCodeCoverage, MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
protected override void Dispose(bool disposing) => base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class ConsoleWriter
|
public partial class ConsoleWriter
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ namespace CliFx.Utils;
|
|||||||
// https://github.com/dotnet/runtime/blob/01b7e73cd378145264a7cb7a09365b41ed42b240/src/libraries/Common/src/System/Text/ConsoleEncoding.cs
|
// https://github.com/dotnet/runtime/blob/01b7e73cd378145264a7cb7a09365b41ed42b240/src/libraries/Common/src/System/Text/ConsoleEncoding.cs
|
||||||
// Also see:
|
// Also see:
|
||||||
// https://source.dot.net/#System.Console/ConsoleEncoding.cs,5eedd083a4a4f4a2
|
// https://source.dot.net/#System.Console/ConsoleEncoding.cs,5eedd083a4a4f4a2
|
||||||
|
// Majority of overrides are just proxy calls to avoid potentially more expensive base behavior.
|
||||||
|
// The important part is the GetPreamble() method that has been overriden to return an empty array.
|
||||||
internal class NoPreambleEncoding : Encoding
|
internal class NoPreambleEncoding : Encoding
|
||||||
{
|
{
|
||||||
private readonly Encoding _underlyingEncoding;
|
private readonly Encoding _underlyingEncoding;
|
||||||
@@ -72,20 +74,20 @@ internal class NoPreambleEncoding : Encoding
|
|||||||
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) =>
|
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) =>
|
||||||
_underlyingEncoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
|
_underlyingEncoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
|
||||||
public override byte[] GetBytes(char[] chars) => _underlyingEncoding.GetBytes(chars);
|
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public override byte[] GetBytes(char[] chars, int index, int count) =>
|
public override byte[] GetBytes(char[] chars, int index, int count) =>
|
||||||
_underlyingEncoding.GetBytes(chars, index, count);
|
_underlyingEncoding.GetBytes(chars, index, count);
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public override byte[] GetBytes(string s) => _underlyingEncoding.GetBytes(s);
|
public override byte[] GetBytes(char[] chars) => _underlyingEncoding.GetBytes(chars);
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) =>
|
public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) =>
|
||||||
_underlyingEncoding.GetBytes(s, charIndex, charCount, bytes, byteIndex);
|
_underlyingEncoding.GetBytes(s, charIndex, charCount, bytes, byteIndex);
|
||||||
|
|
||||||
|
[ExcludeFromCodeCoverage]
|
||||||
|
public override byte[] GetBytes(string s) => _underlyingEncoding.GetBytes(s);
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public override int GetCharCount(byte[] bytes, int index, int count) =>
|
public override int GetCharCount(byte[] bytes, int index, int count) =>
|
||||||
_underlyingEncoding.GetCharCount(bytes, index, count);
|
_underlyingEncoding.GetCharCount(bytes, index, count);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>2.2</Version>
|
<Version>2.2.2</Version>
|
||||||
<Company>Tyrrrz</Company>
|
<Company>Tyrrrz</Company>
|
||||||
<Copyright>Copyright (C) Alexey Golub</Copyright>
|
<Copyright>Copyright (C) Oleksii Holub</Copyright>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2022 Alexey Golub
|
Copyright (c) 2019-2022 Oleksii Holub
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
Reference in New Issue
Block a user