mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Use latest C# features
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.5" />
|
||||
<PackageReference Include="Basic.Reference.Assemblies.Net80" Version="1.4.5" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" />
|
||||
<PackageReference Include="CSharpier.MsBuild" Version="0.26.5" PrivateAssets="all" />
|
||||
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.3" PrivateAssets="all" />
|
||||
|
||||
@@ -23,7 +23,7 @@ public class OptionMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandOption("foo", Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandOption("foo", Validators = new[] { typeof(MyValidator) })]
|
||||
public string? Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
@@ -48,7 +48,7 @@ public class OptionMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandOption("foo", Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandOption("foo", Validators = new[] { typeof(MyValidator) })]
|
||||
public string? Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
@@ -73,7 +73,7 @@ public class OptionMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandOption("foo", Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandOption("foo", Validators = new[] { typeof(MyValidator) })]
|
||||
public string? Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ParameterMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandParameter(0, Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandParameter(0, Validators = new[] { typeof(MyValidator) })]
|
||||
public required string Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
@@ -48,7 +48,7 @@ public class ParameterMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandParameter(0, Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandParameter(0, Validators = new[] { typeof(MyValidator) })]
|
||||
public required string Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
@@ -73,7 +73,7 @@ public class ParameterMustHaveValidValidatorsAnalyzerSpecs
|
||||
[Command]
|
||||
public class MyCommand : ICommand
|
||||
{
|
||||
[CommandParameter(0, Validators = new[] {typeof(MyValidator)})]
|
||||
[CommandParameter(0, Validators = new[] { typeof(MyValidator) })]
|
||||
public required string Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
|
||||
@@ -47,14 +47,14 @@ internal class AnalyzerAssertions(DiagnosticAnalyzer analyzer)
|
||||
// Parse the source code
|
||||
var ast = SyntaxFactory.ParseSyntaxTree(
|
||||
SourceText.From(sourceCodeWithUsings),
|
||||
CSharpParseOptions.Default
|
||||
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)
|
||||
);
|
||||
|
||||
// Compile the code to IL
|
||||
var compilation = CSharpCompilation.Create(
|
||||
"CliFxTests_DynamicAssembly_" + Guid.NewGuid(),
|
||||
new[] { ast },
|
||||
Net70
|
||||
[ast],
|
||||
Net80
|
||||
.References
|
||||
.All
|
||||
.Append(MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location)),
|
||||
|
||||
@@ -8,9 +8,9 @@ public partial class Benchmarks
|
||||
public class CoconaCommand
|
||||
{
|
||||
public void Execute(
|
||||
[Option("str", new[] { 's' })] string? strOption,
|
||||
[Option("int", new[] { 'i' })] int intOption,
|
||||
[Option("bool", new[] { 'b' })] bool boolOption
|
||||
[Option("str", ['s'])] string? strOption,
|
||||
[Option("int", ['i'])] int intOption,
|
||||
[Option("bool", ['b'])] bool boolOption
|
||||
) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ public partial class Benchmarks
|
||||
{
|
||||
var command = new RootCommand
|
||||
{
|
||||
new Option(new[] { "--str", "-s" }) { Argument = new Argument<string?>() },
|
||||
new Option(new[] { "--int", "-i" }) { Argument = new Argument<int>() },
|
||||
new Option(new[] { "--bool", "-b" }) { Argument = new Argument<bool>() }
|
||||
new Option(["--str", "-s"]) { Argument = new Argument<string?>() },
|
||||
new Option(["--int", "-i"]) { Argument = new Argument<int>() },
|
||||
new Option(["--bool", "-b"]) { Argument = new Argument<bool>() }
|
||||
};
|
||||
|
||||
command.Handler = CommandHandler.Create(
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace CliFx.Benchmarks;
|
||||
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
|
||||
public partial class Benchmarks
|
||||
{
|
||||
private static readonly string[] Arguments = { "--str", "hello world", "-i", "13", "-b" };
|
||||
private static readonly string[] Arguments = ["--str", "hello world", "-i", "13", "-b"];
|
||||
|
||||
public static void Main() =>
|
||||
BenchmarkRunner.Run<Benchmarks>(
|
||||
|
||||
@@ -32,8 +32,8 @@ public class ApplicationSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutp
|
||||
var app = new CliApplicationBuilder()
|
||||
.AddCommand<NoOpCommand>()
|
||||
.AddCommandsFrom(typeof(NoOpCommand).Assembly)
|
||||
.AddCommands(new[] { typeof(NoOpCommand) })
|
||||
.AddCommandsFrom(new[] { typeof(NoOpCommand).Assembly })
|
||||
.AddCommands([typeof(NoOpCommand)])
|
||||
.AddCommandsFrom([typeof(NoOpCommand).Assembly])
|
||||
.AddCommandsFromThisAssembly()
|
||||
.AllowDebugMode()
|
||||
.AllowPreviewMode()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.5" />
|
||||
<PackageReference Include="Basic.Reference.Assemblies.Net80" Version="1.4.5" />
|
||||
<PackageReference Include="CliWrap" Version="3.6.4" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" />
|
||||
<PackageReference Include="CSharpier.MsBuild" Version="0.26.5" PrivateAssets="all" />
|
||||
|
||||
@@ -38,10 +38,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "xyz" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "xyz"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -78,10 +75,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "xyz" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "xyz"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -128,7 +122,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "true", "-b", "false", "-c" },
|
||||
["-f", "true", "-b", "false", "-c"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -167,10 +161,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "32" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "32"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -208,7 +199,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "32.14" },
|
||||
["-f", "32.14"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -248,7 +239,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "1995-04-28Z" },
|
||||
["-f", "1995-04-28Z"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -288,7 +279,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "12:34:56" },
|
||||
["-f", "12:34:56"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -329,10 +320,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "two" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "two"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -374,10 +362,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-b", "123" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-b", "123"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -421,10 +406,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-b", "two" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-b", "two"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -468,10 +450,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "xyz" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "xyz"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -534,7 +513,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "hello", "-b", "world" },
|
||||
["-f", "hello", "-b", "world"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -580,7 +559,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "hello world" },
|
||||
["-f", "hello world"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -622,7 +601,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "two", "three" },
|
||||
["-f", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -664,7 +643,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "two", "three" },
|
||||
["-f", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -706,7 +685,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "two", "three" },
|
||||
["-f", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -748,7 +727,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "1", "13", "27" },
|
||||
["-f", "1", "13", "27"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -787,10 +766,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "xyz" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "xyz"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -831,7 +807,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "two" },
|
||||
["-f", "one", "two"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -867,7 +843,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "12.34" },
|
||||
["-f", "12.34"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -898,7 +874,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
[Command]
|
||||
public class Command : ICommand
|
||||
{
|
||||
[CommandOption('f', Validators = new[] {typeof(ValidatorA), typeof(ValidatorB)})]
|
||||
[CommandOption('f', Validators = [typeof(ValidatorA), typeof(ValidatorB)])]
|
||||
public int Foo { get; init; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
@@ -912,10 +888,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "12" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "12"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -957,10 +930,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "bar" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["-f", "bar"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class DirectivesSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "[preview]", "cmd", "param", "-abc", "--option", "foo" },
|
||||
["[preview]", "cmd", "param", "-abc", "--option", "foo"],
|
||||
new Dictionary<string, string> { ["ENV_QOP"] = "hello", ["ENV_KIL"] = "world" }
|
||||
);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class EnvironmentSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutp
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "42" },
|
||||
["--foo", "42"],
|
||||
new Dictionary<string, string> { ["ENV_FOO"] = "100", ["ENV_BAR"] = "200" }
|
||||
);
|
||||
|
||||
|
||||
@@ -55,10 +55,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -95,10 +92,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -141,7 +135,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "cmd", "--help" },
|
||||
["cmd", "--help"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -186,7 +180,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "cmd", "sub", "--help" },
|
||||
["cmd", "sub", "--help"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -209,7 +203,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "invalid-command", "--invalid-option" },
|
||||
["invalid-command", "--invalid-option"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -235,10 +229,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -268,10 +259,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -307,10 +295,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -349,10 +334,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -398,10 +380,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -440,10 +419,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -481,10 +457,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -523,10 +496,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -566,7 +536,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "cmd", "--help" },
|
||||
["cmd", "--help"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -609,10 +579,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -665,10 +632,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -721,10 +685,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -777,10 +738,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -846,10 +804,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -927,10 +882,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -1001,10 +953,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--help"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -1035,10 +984,7 @@ public class HelpTextSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--version" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--version"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
|
||||
@@ -39,10 +39,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--foo"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -79,7 +76,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(new[] { "-f" }, new Dictionary<string, string>());
|
||||
var exitCode = await application.RunAsync(["-f"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -122,7 +119,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "--bar", "two" },
|
||||
["--foo", "one", "--bar", "two"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -167,7 +164,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "-b", "two" },
|
||||
["-f", "one", "-b", "two"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -212,7 +209,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-fb", "value" },
|
||||
["-fb", "value"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -254,7 +251,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "two", "three" },
|
||||
["--foo", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -296,7 +293,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "two", "three" },
|
||||
["-f", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -338,7 +335,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "--foo", "two", "--foo", "three" },
|
||||
["--foo", "one", "--foo", "two", "--foo", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -380,7 +377,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "-f", "one", "-f", "two", "-f", "three" },
|
||||
["-f", "one", "-f", "two", "-f", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -422,7 +419,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "-f", "two", "--foo", "three" },
|
||||
["--foo", "one", "-f", "two", "--foo", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -467,7 +464,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one" },
|
||||
["--foo", "one"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -541,7 +538,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(new[] { "--foo", "42", "--bar", "--baz", "xyz" });
|
||||
var exitCode = await application.RunAsync(["--foo", "42", "--bar", "--baz", "xyz"]);
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -579,7 +576,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "-13" },
|
||||
["--foo", "-13"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -650,10 +647,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--foo"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -686,10 +680,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["--foo"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -723,7 +714,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "--bar", "two" },
|
||||
["--foo", "one", "--bar", "two"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -759,7 +750,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--foo", "one", "two", "three" },
|
||||
["--foo", "one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
|
||||
@@ -43,10 +43,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "one", "two" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["one", "two"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -98,7 +95,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "one", "two", "three", "four", "five", "--boo", "xxx" },
|
||||
["one", "two", "three", "four", "five", "--boo", "xxx"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
@@ -138,10 +135,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "one" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["one"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -177,10 +171,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "one" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["one"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().NotBe(0);
|
||||
@@ -222,10 +213,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "abc" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["abc"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -262,7 +250,7 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "one", "two", "three" },
|
||||
["one", "two", "three"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
|
||||
@@ -112,10 +112,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "cmd" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
var exitCode = await application.RunAsync(["cmd"], new Dictionary<string, string>());
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
@@ -170,7 +167,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "cmd", "child" },
|
||||
["cmd", "child"],
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
|
||||
@@ -49,14 +49,14 @@ internal static class DynamicCommandBuilder
|
||||
// Parse the source code
|
||||
var ast = SyntaxFactory.ParseSyntaxTree(
|
||||
SourceText.From(sourceCodeWithUsings),
|
||||
CSharpParseOptions.Default
|
||||
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)
|
||||
);
|
||||
|
||||
// Compile the code to IL
|
||||
var compilation = CSharpCompilation.Create(
|
||||
"CliFxTests_DynamicAssembly_" + Guid.NewGuid(),
|
||||
new[] { ast },
|
||||
Net70
|
||||
[ast],
|
||||
Net80
|
||||
.References
|
||||
.All
|
||||
.Append(MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location))
|
||||
|
||||
@@ -6,34 +6,24 @@ namespace CliFx;
|
||||
/// <summary>
|
||||
/// Configuration of an application.
|
||||
/// </summary>
|
||||
public class ApplicationConfiguration
|
||||
public class ApplicationConfiguration(
|
||||
IReadOnlyList<Type> commandTypes,
|
||||
bool isDebugModeAllowed,
|
||||
bool isPreviewModeAllowed
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Command types defined in the application.
|
||||
/// </summary>
|
||||
public IReadOnlyList<Type> CommandTypes { get; }
|
||||
public IReadOnlyList<Type> CommandTypes { get; } = commandTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Whether debug mode is allowed in the application.
|
||||
/// </summary>
|
||||
public bool IsDebugModeAllowed { get; }
|
||||
public bool IsDebugModeAllowed { get; } = isDebugModeAllowed;
|
||||
|
||||
/// <summary>
|
||||
/// Whether preview mode is allowed in the application.
|
||||
/// </summary>
|
||||
public bool IsPreviewModeAllowed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ApplicationConfiguration" />.
|
||||
/// </summary>
|
||||
public ApplicationConfiguration(
|
||||
IReadOnlyList<Type> commandTypes,
|
||||
bool isDebugModeAllowed,
|
||||
bool isPreviewModeAllowed
|
||||
)
|
||||
{
|
||||
CommandTypes = commandTypes;
|
||||
IsDebugModeAllowed = isDebugModeAllowed;
|
||||
IsPreviewModeAllowed = isPreviewModeAllowed;
|
||||
}
|
||||
public bool IsPreviewModeAllowed { get; } = isPreviewModeAllowed;
|
||||
}
|
||||
|
||||
@@ -3,41 +3,30 @@
|
||||
/// <summary>
|
||||
/// Metadata associated with an application.
|
||||
/// </summary>
|
||||
public class ApplicationMetadata
|
||||
public class ApplicationMetadata(
|
||||
string title,
|
||||
string executableName,
|
||||
string version,
|
||||
string? description
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Application title.
|
||||
/// </summary>
|
||||
public string Title { get; }
|
||||
public string Title { get; } = title;
|
||||
|
||||
/// <summary>
|
||||
/// Application executable name.
|
||||
/// </summary>
|
||||
public string ExecutableName { get; }
|
||||
public string ExecutableName { get; } = executableName;
|
||||
|
||||
/// <summary>
|
||||
/// Application version.
|
||||
/// </summary>
|
||||
public string Version { get; }
|
||||
public string Version { get; } = version;
|
||||
|
||||
/// <summary>
|
||||
/// Application description.
|
||||
/// </summary>
|
||||
public string? Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ApplicationMetadata" />.
|
||||
/// </summary>
|
||||
public ApplicationMetadata(
|
||||
string title,
|
||||
string executableName,
|
||||
string version,
|
||||
string? description
|
||||
)
|
||||
{
|
||||
Title = title;
|
||||
ExecutableName = executableName;
|
||||
Version = version;
|
||||
Description = description;
|
||||
}
|
||||
public string? Description { get; } = description;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace CliFx.Attributes;
|
||||
/// Annotates a property that defines a command parameter.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class CommandParameterAttribute : Attribute
|
||||
public sealed class CommandParameterAttribute(int order) : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameter order.
|
||||
@@ -18,7 +18,7 @@ public sealed class CommandParameterAttribute : Attribute
|
||||
/// Parameter whose type is a non-scalar (e.g. array), must always be the last in order.
|
||||
/// Only one non-scalar parameter is allowed in a command.
|
||||
/// </remarks>
|
||||
public int Order { get; }
|
||||
public int Order { get; } = order;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this parameter is required (default: <c>true</c>).
|
||||
@@ -62,12 +62,4 @@ public sealed class CommandParameterAttribute : Attribute
|
||||
/// Validators must derive from <see cref="BindingValidator{T}" />.
|
||||
/// </remarks>
|
||||
public Type[] Validators { get; set; } = Array.Empty<Type>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="CommandParameterAttribute" />.
|
||||
/// </summary>
|
||||
public CommandParameterAttribute(int order)
|
||||
{
|
||||
Order = order;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,40 +17,24 @@ namespace CliFx;
|
||||
/// <summary>
|
||||
/// Command-line application facade.
|
||||
/// </summary>
|
||||
public class CliApplication
|
||||
public class CliApplication(
|
||||
ApplicationMetadata metadata,
|
||||
ApplicationConfiguration configuration,
|
||||
IConsole console,
|
||||
ITypeActivator typeActivator
|
||||
)
|
||||
{
|
||||
private readonly CommandBinder _commandBinder = new(typeActivator);
|
||||
|
||||
/// <summary>
|
||||
/// Application metadata.
|
||||
/// </summary>
|
||||
public ApplicationMetadata Metadata { get; }
|
||||
public ApplicationMetadata Metadata { get; } = metadata;
|
||||
|
||||
/// <summary>
|
||||
/// Application configuration.
|
||||
/// </summary>
|
||||
public ApplicationConfiguration Configuration { get; }
|
||||
|
||||
private readonly IConsole _console;
|
||||
private readonly ITypeActivator _typeActivator;
|
||||
|
||||
private readonly CommandBinder _commandBinder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="CliApplication" />.
|
||||
/// </summary>
|
||||
public CliApplication(
|
||||
ApplicationMetadata metadata,
|
||||
ApplicationConfiguration configuration,
|
||||
IConsole console,
|
||||
ITypeActivator typeActivator
|
||||
)
|
||||
{
|
||||
Metadata = metadata;
|
||||
Configuration = configuration;
|
||||
_console = console;
|
||||
_typeActivator = typeActivator;
|
||||
|
||||
_commandBinder = new CommandBinder(typeActivator);
|
||||
}
|
||||
public ApplicationConfiguration Configuration { get; } = configuration;
|
||||
|
||||
private bool IsDebugModeEnabled(CommandInput commandInput) =>
|
||||
Configuration.IsDebugModeAllowed && commandInput.IsDebugDirectiveSpecified;
|
||||
@@ -70,9 +54,9 @@ public class CliApplication
|
||||
|
||||
private async ValueTask PromptDebuggerAsync()
|
||||
{
|
||||
using (_console.WithForegroundColor(ConsoleColor.Green))
|
||||
using (console.WithForegroundColor(ConsoleColor.Green))
|
||||
{
|
||||
_console
|
||||
console
|
||||
.Output
|
||||
.WriteLine(
|
||||
$"Attach the debugger to process with ID {ProcessEx.GetCurrentProcessId()} to continue."
|
||||
@@ -93,7 +77,7 @@ public class CliApplication
|
||||
{
|
||||
// Console colors may have already been overridden by the parent process,
|
||||
// so we need to reset it to make sure that everything we write looks properly.
|
||||
_console.ResetColor();
|
||||
console.ResetColor();
|
||||
|
||||
// Handle the debug directive
|
||||
if (IsDebugModeEnabled(commandInput))
|
||||
@@ -104,7 +88,7 @@ public class CliApplication
|
||||
// Handle the preview directive
|
||||
if (IsPreviewModeEnabled(commandInput))
|
||||
{
|
||||
_console.Output.WriteCommandInput(commandInput);
|
||||
console.Output.WriteCommandInput(commandInput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,7 +112,7 @@ public class CliApplication
|
||||
var commandInstance =
|
||||
commandSchema == FallbackDefaultCommand.Schema
|
||||
? new FallbackDefaultCommand() // bypass the activator
|
||||
: _typeActivator.CreateInstance<ICommand>(commandSchema.Type);
|
||||
: typeActivator.CreateInstance<ICommand>(commandSchema.Type);
|
||||
|
||||
// Assemble the help context
|
||||
var helpContext = new HelpContext(
|
||||
@@ -141,14 +125,14 @@ public class CliApplication
|
||||
// Handle the help option
|
||||
if (ShouldShowHelpText(commandSchema, commandInput))
|
||||
{
|
||||
_console.Output.WriteHelpText(helpContext);
|
||||
console.Output.WriteHelpText(helpContext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle the version option
|
||||
if (ShouldShowVersionText(commandSchema, commandInput))
|
||||
{
|
||||
_console.Output.WriteLine(Metadata.Version);
|
||||
console.Output.WriteLine(Metadata.Version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,18 +144,18 @@ public class CliApplication
|
||||
{
|
||||
// Bind and execute the command
|
||||
_commandBinder.Bind(commandInput, commandSchema, commandInstance);
|
||||
await commandInstance.ExecuteAsync(_console);
|
||||
await commandInstance.ExecuteAsync(console);
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (CliFxException ex)
|
||||
{
|
||||
_console.Error.WriteException(ex);
|
||||
console.Error.WriteException(ex);
|
||||
|
||||
if (ex.ShowHelp)
|
||||
{
|
||||
_console.Output.WriteLine();
|
||||
_console.Output.WriteHelpText(helpContext);
|
||||
console.Output.WriteLine();
|
||||
console.Output.WriteHelpText(helpContext);
|
||||
}
|
||||
|
||||
return ex.ExitCode;
|
||||
@@ -211,7 +195,7 @@ public class CliApplication
|
||||
// developer, so we don't swallow them in that case.
|
||||
catch (Exception ex) when (!Debugger.IsAttached)
|
||||
{
|
||||
_console.Error.WriteException(ex);
|
||||
console.Error.WriteException(ex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace CliFx;
|
||||
/// </summary>
|
||||
public partial class CliApplicationBuilder
|
||||
{
|
||||
private readonly HashSet<Type> _commandTypes = new();
|
||||
private readonly HashSet<Type> _commandTypes = [];
|
||||
|
||||
private bool _isDebugModeAllowed = true;
|
||||
private bool _isPreviewModeAllowed = true;
|
||||
|
||||
@@ -74,27 +74,24 @@ internal class CommandBinder(ITypeActivator typeActivator)
|
||||
}
|
||||
|
||||
// String-constructable (FileInfo, etc)
|
||||
var stringConstructor = targetType.GetConstructor(new[] { typeof(string) });
|
||||
var stringConstructor = targetType.GetConstructor([typeof(string)]);
|
||||
if (stringConstructor is not null)
|
||||
{
|
||||
return stringConstructor.Invoke(new object?[] { rawValue });
|
||||
return stringConstructor.Invoke([rawValue]);
|
||||
}
|
||||
|
||||
// String-parseable (with IFormatProvider)
|
||||
var parseMethodWithFormatProvider = targetType.TryGetStaticParseMethod(true);
|
||||
if (parseMethodWithFormatProvider is not null)
|
||||
{
|
||||
return parseMethodWithFormatProvider.Invoke(
|
||||
null,
|
||||
new object?[] { rawValue, _formatProvider }
|
||||
);
|
||||
return parseMethodWithFormatProvider.Invoke(null, [rawValue, _formatProvider]);
|
||||
}
|
||||
|
||||
// String-parseable (without IFormatProvider)
|
||||
var parseMethod = targetType.TryGetStaticParseMethod();
|
||||
if (parseMethod is not null)
|
||||
{
|
||||
return parseMethod.Invoke(null, new object?[] { rawValue });
|
||||
return parseMethod.Invoke(null, [rawValue]);
|
||||
}
|
||||
|
||||
throw CliFxException.InternalError(
|
||||
@@ -126,10 +123,10 @@ internal class CommandBinder(ITypeActivator typeActivator)
|
||||
}
|
||||
|
||||
// Array-constructable (List<T>, HashSet<T>, etc)
|
||||
var arrayConstructor = targetEnumerableType.GetConstructor(new[] { arrayType });
|
||||
var arrayConstructor = targetEnumerableType.GetConstructor([arrayType]);
|
||||
if (arrayConstructor is not null)
|
||||
{
|
||||
return arrayConstructor.Invoke(new object?[] { array });
|
||||
return arrayConstructor.Invoke([array]);
|
||||
}
|
||||
|
||||
throw CliFxException.InternalError(
|
||||
@@ -263,12 +260,9 @@ internal class CommandBinder(ITypeActivator typeActivator)
|
||||
if (parameterSchema.Property.IsScalar())
|
||||
{
|
||||
var parameterInput = commandInput.Parameters[position];
|
||||
|
||||
var rawValues = new[] { parameterInput.Value };
|
||||
BindMember(parameterSchema, commandInstance, rawValues);
|
||||
BindMember(parameterSchema, commandInstance, [parameterInput.Value]);
|
||||
|
||||
position++;
|
||||
|
||||
remainingParameterInputs.Remove(parameterInput);
|
||||
}
|
||||
// Non-scalar: take all remaining inputs starting from the current position
|
||||
@@ -276,11 +270,13 @@ internal class CommandBinder(ITypeActivator typeActivator)
|
||||
{
|
||||
var parameterInputs = commandInput.Parameters.Skip(position).ToArray();
|
||||
|
||||
var rawValues = parameterInputs.Select(p => p.Value).ToArray();
|
||||
BindMember(parameterSchema, commandInstance, rawValues);
|
||||
BindMember(
|
||||
parameterSchema,
|
||||
commandInstance,
|
||||
parameterInputs.Select(p => p.Value).ToArray()
|
||||
);
|
||||
|
||||
position += parameterInputs.Length;
|
||||
|
||||
remainingParameterInputs.RemoveRange(parameterInputs);
|
||||
}
|
||||
|
||||
@@ -347,7 +343,7 @@ internal class CommandBinder(ITypeActivator typeActivator)
|
||||
else if (environmentVariableInput is not null)
|
||||
{
|
||||
var rawValues = optionSchema.Property.IsScalar()
|
||||
? new[] { environmentVariableInput.Value }
|
||||
? [environmentVariableInput.Value]
|
||||
: environmentVariableInput.SplitValues();
|
||||
|
||||
BindMember(optionSchema, commandInstance, rawValues);
|
||||
|
||||
@@ -5,7 +5,12 @@ namespace CliFx.Exceptions;
|
||||
/// <summary>
|
||||
/// Exception thrown when there is an error during application execution.
|
||||
/// </summary>
|
||||
public partial class CliFxException : Exception
|
||||
public partial class CliFxException(
|
||||
string message,
|
||||
int exitCode = CliFxException.DefaultExitCode,
|
||||
bool showHelp = false,
|
||||
Exception? innerException = null
|
||||
) : Exception(message, innerException)
|
||||
{
|
||||
internal const int DefaultExitCode = 1;
|
||||
|
||||
@@ -13,33 +18,17 @@ public partial class CliFxException : Exception
|
||||
// provides a default message that is not very useful.
|
||||
// This property is used to identify whether this instance was created with
|
||||
// a custom message, so that we can avoid printing the default message.
|
||||
internal bool HasCustomMessage { get; }
|
||||
internal bool HasCustomMessage { get; } = !string.IsNullOrWhiteSpace(message);
|
||||
|
||||
/// <summary>
|
||||
/// Returned exit code.
|
||||
/// </summary>
|
||||
public int ExitCode { get; }
|
||||
public int ExitCode { get; } = exitCode;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show the help text before exiting.
|
||||
/// </summary>
|
||||
public bool ShowHelp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="CliFxException" />.
|
||||
/// </summary>
|
||||
public CliFxException(
|
||||
string message,
|
||||
int exitCode = DefaultExitCode,
|
||||
bool showHelp = false,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base(message, innerException)
|
||||
{
|
||||
HasCustomMessage = !string.IsNullOrWhiteSpace(message);
|
||||
ExitCode = exitCode;
|
||||
ShowHelp = showHelp;
|
||||
}
|
||||
public bool ShowHelp { get; } = showHelp;
|
||||
}
|
||||
|
||||
public partial class CliFxException
|
||||
|
||||
@@ -6,16 +6,9 @@ namespace CliFx.Exceptions;
|
||||
/// Exception thrown when a command cannot proceed with its normal execution due to an error.
|
||||
/// Use this exception to report an error to the console and return a specific exit code.
|
||||
/// </summary>
|
||||
public class CommandException : CliFxException
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="CommandException" />.
|
||||
/// </summary>
|
||||
public CommandException(
|
||||
string message,
|
||||
int exitCode = DefaultExitCode,
|
||||
bool showHelp = false,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base(message, exitCode, showHelp, innerException) { }
|
||||
}
|
||||
public class CommandException(
|
||||
string message,
|
||||
int exitCode = CliFxException.DefaultExitCode,
|
||||
bool showHelp = false,
|
||||
Exception? innerException = null
|
||||
) : CliFxException(message, exitCode, showHelp, innerException);
|
||||
|
||||
@@ -3,15 +3,10 @@
|
||||
/// <summary>
|
||||
/// Represents a validation error.
|
||||
/// </summary>
|
||||
public class BindingValidationError
|
||||
public class BindingValidationError(string message)
|
||||
{
|
||||
/// <summary>
|
||||
/// Error message shown to the user.
|
||||
/// </summary>
|
||||
public string Message { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="BindingValidationError" />.
|
||||
/// </summary>
|
||||
public BindingValidationError(string message) => Message = message;
|
||||
public string Message { get; } = message;
|
||||
}
|
||||
|
||||
@@ -11,28 +11,20 @@ namespace CliFx.Infrastructure;
|
||||
/// </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(IConsole console, Stream stream, Encoding encoding)
|
||||
: StreamReader(stream, encoding, false, 4096)
|
||||
{
|
||||
/// <summary>
|
||||
/// Console that owns this stream.
|
||||
/// </summary>
|
||||
public IConsole Console { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ConsoleReader" />.
|
||||
/// </summary>
|
||||
public ConsoleReader(IConsole console, Stream stream, Encoding encoding)
|
||||
: base(stream, encoding, false, 4096)
|
||||
{
|
||||
Console = console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ConsoleReader" />.
|
||||
/// </summary>
|
||||
public ConsoleReader(IConsole console, Stream stream)
|
||||
: this(console, stream, System.Console.InputEncoding) { }
|
||||
|
||||
/// <summary>
|
||||
/// Console that owns this stream.
|
||||
/// </summary>
|
||||
public IConsole Console { get; } = console;
|
||||
|
||||
// The following overrides are required to establish thread-safe behavior
|
||||
// in methods deriving from StreamReader.
|
||||
|
||||
|
||||
@@ -12,28 +12,20 @@ namespace CliFx.Infrastructure;
|
||||
/// </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(IConsole console, Stream stream, Encoding encoding)
|
||||
: StreamWriter(stream, encoding.WithoutPreamble(), 256)
|
||||
{
|
||||
/// <summary>
|
||||
/// Console that owns this stream.
|
||||
/// </summary>
|
||||
public IConsole Console { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ConsoleWriter" />.
|
||||
/// </summary>
|
||||
public ConsoleWriter(IConsole console, Stream stream, Encoding encoding)
|
||||
: base(stream, encoding.WithoutPreamble(), 256)
|
||||
{
|
||||
Console = console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="ConsoleWriter" />.
|
||||
/// </summary>
|
||||
public ConsoleWriter(IConsole console, Stream stream)
|
||||
: this(console, stream, System.Console.OutputEncoding) { }
|
||||
|
||||
/// <summary>
|
||||
/// Console that owns this stream.
|
||||
/// </summary>
|
||||
public IConsole Console { get; } = console;
|
||||
|
||||
// The following overrides are required to establish thread-safe behavior
|
||||
// in methods deriving from StreamWriter.
|
||||
|
||||
|
||||
@@ -6,20 +6,12 @@ namespace CliFx.Infrastructure;
|
||||
/// <summary>
|
||||
/// Implementation of <see cref="ITypeActivator" /> that instantiates an object by using a predefined delegate.
|
||||
/// </summary>
|
||||
public class DelegateTypeActivator : ITypeActivator
|
||||
public class DelegateTypeActivator(Func<Type, object> createInstance) : ITypeActivator
|
||||
{
|
||||
private readonly Func<Type, object> _createInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of <see cref="DelegateTypeActivator" />.
|
||||
/// </summary>
|
||||
public DelegateTypeActivator(Func<Type, object> createInstance) =>
|
||||
_createInstance = createInstance;
|
||||
|
||||
/// <inheritdoc />
|
||||
public object CreateInstance(Type type)
|
||||
{
|
||||
var instance = _createInstance(type);
|
||||
var instance = createInstance(type);
|
||||
|
||||
if (instance is null)
|
||||
{
|
||||
|
||||
@@ -160,7 +160,7 @@ internal partial class CommandInput
|
||||
result.Add(new OptionInput(lastOptionIdentifier, lastOptionValues));
|
||||
|
||||
lastOptionIdentifier = argument[2..];
|
||||
lastOptionValues = new List<string>();
|
||||
lastOptionValues = [];
|
||||
}
|
||||
// Short name
|
||||
else if (argument.StartsWith('-') && argument.Length > 1 && char.IsLetter(argument[1]))
|
||||
@@ -172,7 +172,7 @@ internal partial class CommandInput
|
||||
result.Add(new OptionInput(lastOptionIdentifier, lastOptionValues));
|
||||
|
||||
lastOptionIdentifier = identifier.AsString();
|
||||
lastOptionValues = new List<string>();
|
||||
lastOptionValues = [];
|
||||
}
|
||||
}
|
||||
// Value
|
||||
|
||||
Reference in New Issue
Block a user