diff --git a/CliFx.Benchmarks/CliFx.Benchmarks.csproj b/CliFx.Benchmarks/CliFx.Benchmarks.csproj
index 8b168cb..62ab854 100644
--- a/CliFx.Benchmarks/CliFx.Benchmarks.csproj
+++ b/CliFx.Benchmarks/CliFx.Benchmarks.csproj
@@ -3,6 +3,7 @@
Exe
netcoreapp3.0
+ enable
diff --git a/CliFx.Benchmarks/Commands/CliFxCommand.cs b/CliFx.Benchmarks/Commands/CliFxCommand.cs
index 3c33aff..2c6481e 100644
--- a/CliFx.Benchmarks/Commands/CliFxCommand.cs
+++ b/CliFx.Benchmarks/Commands/CliFxCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,7 +8,7 @@ namespace CliFx.Benchmarks.Commands
public class CliFxCommand : ICommand
{
[CommandOption("str", 's')]
- public string StrOption { get; set; }
+ public string? StrOption { get; set; }
[CommandOption("int", 'i')]
public int IntOption { get; set; }
diff --git a/CliFx.Benchmarks/Commands/CliprCommand.cs b/CliFx.Benchmarks/Commands/CliprCommand.cs
index 3a34d74..88c5507 100644
--- a/CliFx.Benchmarks/Commands/CliprCommand.cs
+++ b/CliFx.Benchmarks/Commands/CliprCommand.cs
@@ -5,7 +5,7 @@ namespace CliFx.Benchmarks.Commands
public class CliprCommand
{
[NamedArgument('s', "str")]
- public string StrOption { get; set; }
+ public string? StrOption { get; set; }
[NamedArgument('i', "int")]
public int IntOption { get; set; }
diff --git a/CliFx.Benchmarks/Commands/CommandLineParserCommand.cs b/CliFx.Benchmarks/Commands/CommandLineParserCommand.cs
index 8ffbc1f..9a91f12 100644
--- a/CliFx.Benchmarks/Commands/CommandLineParserCommand.cs
+++ b/CliFx.Benchmarks/Commands/CommandLineParserCommand.cs
@@ -5,7 +5,7 @@ namespace CliFx.Benchmarks.Commands
public class CommandLineParserCommand
{
[Option('s', "str")]
- public string StrOption { get; set; }
+ public string? StrOption { get; set; }
[Option('i', "int")]
public int IntOption { get; set; }
diff --git a/CliFx.Benchmarks/Commands/McMasterCommand.cs b/CliFx.Benchmarks/Commands/McMasterCommand.cs
index 57a15d7..6501290 100644
--- a/CliFx.Benchmarks/Commands/McMasterCommand.cs
+++ b/CliFx.Benchmarks/Commands/McMasterCommand.cs
@@ -5,7 +5,7 @@ namespace CliFx.Benchmarks.Commands
public class McMasterCommand
{
[Option("--str|-s")]
- public string StrOption { get; set; }
+ public string? StrOption { get; set; }
[Option("--int|-i")]
public int IntOption { get; set; }
diff --git a/CliFx.Benchmarks/Commands/PowerArgsCommand.cs b/CliFx.Benchmarks/Commands/PowerArgsCommand.cs
index 003dc2d..2c09e30 100644
--- a/CliFx.Benchmarks/Commands/PowerArgsCommand.cs
+++ b/CliFx.Benchmarks/Commands/PowerArgsCommand.cs
@@ -5,7 +5,7 @@ namespace CliFx.Benchmarks.Commands
public class PowerArgsCommand
{
[ArgShortcut("--str"), ArgShortcut("-s")]
- public string StrOption { get; set; }
+ public string? StrOption { get; set; }
[ArgShortcut("--int"), ArgShortcut("-i")]
public int IntOption { get; set; }
diff --git a/CliFx.Benchmarks/Commands/SystemCommandLineCommand.cs b/CliFx.Benchmarks/Commands/SystemCommandLineCommand.cs
index dd9de9b..9a655d0 100644
--- a/CliFx.Benchmarks/Commands/SystemCommandLineCommand.cs
+++ b/CliFx.Benchmarks/Commands/SystemCommandLineCommand.cs
@@ -14,7 +14,7 @@ namespace CliFx.Benchmarks.Commands
{
new Option(new[] {"--str", "-s"})
{
- Argument = new Argument()
+ Argument = new Argument()
},
new Option(new[] {"--int", "-i"})
{
diff --git a/CliFx.Demo/CliFx.Demo.csproj b/CliFx.Demo/CliFx.Demo.csproj
index 523cd1e..1566bf5 100644
--- a/CliFx.Demo/CliFx.Demo.csproj
+++ b/CliFx.Demo/CliFx.Demo.csproj
@@ -3,6 +3,7 @@
Exe
netcoreapp3.0
+ enable
diff --git a/CliFx.Demo/Commands/BookAddCommand.cs b/CliFx.Demo/Commands/BookAddCommand.cs
index 9bc8bcd..c94e355 100644
--- a/CliFx.Demo/Commands/BookAddCommand.cs
+++ b/CliFx.Demo/Commands/BookAddCommand.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Demo.Internal;
@@ -25,7 +24,7 @@ namespace CliFx.Demo.Commands
public DateTimeOffset Published { get; set; }
[CommandOption("isbn", 'n', Description = "Book ISBN.")]
- public Isbn Isbn { get; set; }
+ public Isbn? Isbn { get; set; }
public BookAddCommand(LibraryService libraryService)
{
diff --git a/CliFx.Demo/Commands/BookCommand.cs b/CliFx.Demo/Commands/BookCommand.cs
index 406f695..2a4fb81 100644
--- a/CliFx.Demo/Commands/BookCommand.cs
+++ b/CliFx.Demo/Commands/BookCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Demo.Internal;
using CliFx.Demo.Services;
diff --git a/CliFx.Demo/Commands/BookListCommand.cs b/CliFx.Demo/Commands/BookListCommand.cs
index 2035bfd..e6077fe 100644
--- a/CliFx.Demo/Commands/BookListCommand.cs
+++ b/CliFx.Demo/Commands/BookListCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Demo.Internal;
using CliFx.Demo.Services;
diff --git a/CliFx.Demo/Commands/BookRemoveCommand.cs b/CliFx.Demo/Commands/BookRemoveCommand.cs
index 83047f2..ce7e771 100644
--- a/CliFx.Demo/Commands/BookRemoveCommand.cs
+++ b/CliFx.Demo/Commands/BookRemoveCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Demo.Services;
using CliFx.Exceptions;
diff --git a/CliFx.Demo/Program.cs b/CliFx.Demo/Program.cs
index 6a13bdd..b699782 100644
--- a/CliFx.Demo/Program.cs
+++ b/CliFx.Demo/Program.cs
@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using CliFx.Demo.Commands;
using CliFx.Demo.Services;
using Microsoft.Extensions.DependencyInjection;
@@ -7,7 +8,7 @@ namespace CliFx.Demo
{
public static class Program
{
- public static Task Main(string[] args)
+ private static IServiceProvider ConfigureServices()
{
// We use Microsoft.Extensions.DependencyInjection for injecting dependencies in commands
var services = new ServiceCollection();
@@ -21,7 +22,12 @@ namespace CliFx.Demo
services.AddTransient();
services.AddTransient();
- var serviceProvider = services.BuildServiceProvider();
+ return services.BuildServiceProvider();
+ }
+
+ public static Task Main(string[] args)
+ {
+ var serviceProvider = ConfigureServices();
return new CliApplicationBuilder()
.AddCommandsFromThisAssembly()
diff --git a/CliFx.Tests/CliApplicationBuilderTests.cs b/CliFx.Tests/CliApplicationBuilderTests.cs
index 171875c..ffb187f 100644
--- a/CliFx.Tests/CliApplicationBuilderTests.cs
+++ b/CliFx.Tests/CliApplicationBuilderTests.cs
@@ -21,8 +21,8 @@ namespace CliFx.Tests
builder
.AddCommand(typeof(HelloWorldDefaultCommand))
.AddCommandsFrom(typeof(HelloWorldDefaultCommand).Assembly)
- .AddCommands(new[] { typeof(HelloWorldDefaultCommand) })
- .AddCommandsFrom(new[] { typeof(HelloWorldDefaultCommand).Assembly })
+ .AddCommands(new[] {typeof(HelloWorldDefaultCommand)})
+ .AddCommandsFrom(new[] {typeof(HelloWorldDefaultCommand).Assembly})
.AddCommandsFromThisAssembly()
.AllowDebugMode()
.AllowPreviewMode()
@@ -31,7 +31,7 @@ namespace CliFx.Tests
.UseVersionText("test")
.UseDescription("test")
.UseConsole(new VirtualConsole(TextWriter.Null))
- .UseCommandFactory(schema => (ICommand)Activator.CreateInstance(schema.Type))
+ .UseCommandFactory(schema => (ICommand) Activator.CreateInstance(schema.Type!)!)
.UseCommandOptionInputConverter(new CommandOptionInputConverter())
.UseEnvironmentVariablesProvider(new EnvironmentVariablesProviderStub())
.Build();
diff --git a/CliFx.Tests/CliApplicationTests.cs b/CliFx.Tests/CliApplicationTests.cs
index 9547872..6d05e48 100644
--- a/CliFx.Tests/CliApplicationTests.cs
+++ b/CliFx.Tests/CliApplicationTests.cs
@@ -19,104 +19,104 @@ namespace CliFx.Tests
private static IEnumerable GetTestCases_RunAsync()
{
yield return new TestCaseData(
- new[] { typeof(HelloWorldDefaultCommand) },
+ new[] {typeof(HelloWorldDefaultCommand)},
new string[0],
"Hello world."
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "concat", "-i", "foo", "-i", "bar", "-s", " " },
+ new[] {typeof(ConcatCommand)},
+ new[] {"concat", "-i", "foo", "-i", "bar", "-s", " "},
"foo bar"
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "concat", "-i", "one", "two", "three", "-s", ", " },
+ new[] {typeof(ConcatCommand)},
+ new[] {"concat", "-i", "one", "two", "three", "-s", ", "},
"one, two, three"
);
yield return new TestCaseData(
- new[] { typeof(DivideCommand) },
- new[] { "div", "-D", "24", "-d", "8" },
+ new[] {typeof(DivideCommand)},
+ new[] {"div", "-D", "24", "-d", "8"},
"3"
);
yield return new TestCaseData(
- new[] { typeof(HelloWorldDefaultCommand) },
- new[] { "--version" },
+ new[] {typeof(HelloWorldDefaultCommand)},
+ new[] {"--version"},
TestVersionText
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "--version" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"--version"},
TestVersionText
);
yield return new TestCaseData(
- new[] { typeof(HelloWorldDefaultCommand) },
- new[] { "-h" },
+ new[] {typeof(HelloWorldDefaultCommand)},
+ new[] {"-h"},
null
);
yield return new TestCaseData(
- new[] { typeof(HelloWorldDefaultCommand) },
- new[] { "--help" },
+ new[] {typeof(HelloWorldDefaultCommand)},
+ new[] {"--help"},
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
+ new[] {typeof(ConcatCommand)},
new string[0],
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "-h" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"-h"},
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "--help" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"--help"},
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "concat", "-h" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"concat", "-h"},
null
);
yield return new TestCaseData(
- new[] { typeof(ExceptionCommand) },
- new[] { "exc", "-h" },
+ new[] {typeof(ExceptionCommand)},
+ new[] {"exc", "-h"},
null
);
yield return new TestCaseData(
- new[] { typeof(CommandExceptionCommand) },
- new[] { "exc", "-h" },
+ new[] {typeof(CommandExceptionCommand)},
+ new[] {"exc", "-h"},
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "[preview]" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"[preview]"},
null
);
yield return new TestCaseData(
- new[] { typeof(ExceptionCommand) },
- new[] { "exc", "[preview]" },
+ new[] {typeof(ExceptionCommand)},
+ new[] {"exc", "[preview]"},
null
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "concat", "[preview]", "-o", "value" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"concat", "[preview]", "-o", "value"},
null
);
}
@@ -130,38 +130,38 @@ namespace CliFx.Tests
);
yield return new TestCaseData(
- new[] { typeof(ConcatCommand) },
- new[] { "non-existing" },
+ new[] {typeof(ConcatCommand)},
+ new[] {"non-existing"},
null, null
);
yield return new TestCaseData(
- new[] { typeof(ExceptionCommand) },
- new[] { "exc" },
+ new[] {typeof(ExceptionCommand)},
+ new[] {"exc"},
null, null
);
yield return new TestCaseData(
- new[] { typeof(CommandExceptionCommand) },
- new[] { "exc" },
+ new[] {typeof(CommandExceptionCommand)},
+ new[] {"exc"},
null, null
);
yield return new TestCaseData(
- new[] { typeof(CommandExceptionCommand) },
- new[] { "exc" },
+ new[] {typeof(CommandExceptionCommand)},
+ new[] {"exc"},
null, null
);
yield return new TestCaseData(
- new[] { typeof(CommandExceptionCommand) },
- new[] { "exc", "-m", "foo bar" },
+ new[] {typeof(CommandExceptionCommand)},
+ new[] {"exc", "-m", "foo bar"},
"foo bar", null
);
yield return new TestCaseData(
- new[] { typeof(CommandExceptionCommand) },
- new[] { "exc", "-m", "foo bar", "-c", "666" },
+ new[] {typeof(CommandExceptionCommand)},
+ new[] {"exc", "-m", "foo bar", "-c", "666"},
"foo bar", 666
);
}
@@ -169,95 +169,92 @@ namespace CliFx.Tests
[Test]
[TestCaseSource(nameof(GetTestCases_RunAsync))]
public async Task RunAsync_Test(IReadOnlyList commandTypes, IReadOnlyList commandLineArguments,
- string expectedStdOut = null)
+ string? expectedStdOut = null)
{
// Arrange
- using (var stdoutStream = new StringWriter())
- {
- var console = new VirtualConsole(stdoutStream);
- var environmentVariablesProvider = new EnvironmentVariablesProviderStub();
+ await using var stdoutStream = new StringWriter();
- var application = new CliApplicationBuilder()
- .AddCommands(commandTypes)
- .UseVersionText(TestVersionText)
- .UseConsole(console)
- .UseEnvironmentVariablesProvider(environmentVariablesProvider)
- .Build();
+ var console = new VirtualConsole(stdoutStream);
+ var environmentVariablesProvider = new EnvironmentVariablesProviderStub();
- // Act
- var exitCode = await application.RunAsync(commandLineArguments);
- var stdOut = stdoutStream.ToString().Trim();
+ var application = new CliApplicationBuilder()
+ .AddCommands(commandTypes)
+ .UseVersionText(TestVersionText)
+ .UseConsole(console)
+ .UseEnvironmentVariablesProvider(environmentVariablesProvider)
+ .Build();
- // Assert
- exitCode.Should().Be(0);
+ // Act
+ var exitCode = await application.RunAsync(commandLineArguments);
+ var stdOut = stdoutStream.ToString().Trim();
- if (expectedStdOut != null)
- stdOut.Should().Be(expectedStdOut);
- else
- stdOut.Should().NotBeNullOrWhiteSpace();
- }
+ // Assert
+ exitCode.Should().Be(0);
+
+ if (expectedStdOut != null)
+ stdOut.Should().Be(expectedStdOut);
+ else
+ stdOut.Should().NotBeNullOrWhiteSpace();
}
[Test]
[TestCaseSource(nameof(GetTestCases_RunAsync_Negative))]
public async Task RunAsync_Negative_Test(IReadOnlyList commandTypes, IReadOnlyList commandLineArguments,
- string expectedStdErr = null, int? expectedExitCode = null)
+ string? expectedStdErr = null, int? expectedExitCode = null)
{
// Arrange
- using (var stderrStream = new StringWriter())
- {
- var console = new VirtualConsole(TextWriter.Null, stderrStream);
- var environmentVariablesProvider = new EnvironmentVariablesProviderStub();
+ await using var stderrStream = new StringWriter();
- var application = new CliApplicationBuilder()
- .AddCommands(commandTypes)
- .UseVersionText(TestVersionText)
- .UseEnvironmentVariablesProvider(environmentVariablesProvider)
- .UseConsole(console)
- .Build();
+ var console = new VirtualConsole(TextWriter.Null, stderrStream);
+ var environmentVariablesProvider = new EnvironmentVariablesProviderStub();
- // Act
- var exitCode = await application.RunAsync(commandLineArguments);
- var stderr = stderrStream.ToString().Trim();
+ var application = new CliApplicationBuilder()
+ .AddCommands(commandTypes)
+ .UseVersionText(TestVersionText)
+ .UseEnvironmentVariablesProvider(environmentVariablesProvider)
+ .UseConsole(console)
+ .Build();
- // Assert
- if (expectedExitCode != null)
- exitCode.Should().Be(expectedExitCode);
- else
- exitCode.Should().NotBe(0);
+ // Act
+ var exitCode = await application.RunAsync(commandLineArguments);
+ var stderr = stderrStream.ToString().Trim();
- if (expectedStdErr != null)
- stderr.Should().Be(expectedStdErr);
- else
- stderr.Should().NotBeNullOrWhiteSpace();
- }
+ // Assert
+ if (expectedExitCode != null)
+ exitCode.Should().Be(expectedExitCode);
+ else
+ exitCode.Should().NotBe(0);
+
+ if (expectedStdErr != null)
+ stderr.Should().Be(expectedStdErr);
+ else
+ stderr.Should().NotBeNullOrWhiteSpace();
}
[Test]
public async Task RunAsync_Cancellation_Test()
{
// Arrange
- using (var stdoutStream = new StringWriter())
- using (var cancellationTokenSource = new CancellationTokenSource())
- {
- var console = new VirtualConsole(stdoutStream, cancellationTokenSource.Token);
-
- var application = new CliApplicationBuilder()
- .AddCommand(typeof(CancellableCommand))
- .UseConsole(console)
- .Build();
- var args = new[] { "cancel" };
+ using var cancellationTokenSource = new CancellationTokenSource();
+ await using var stdoutStream = new StringWriter();
- // Act
- var runTask = application.RunAsync(args);
- cancellationTokenSource.Cancel();
- var exitCode = await runTask.ConfigureAwait(false);
- var stdOut = stdoutStream.ToString().Trim();
+ var console = new VirtualConsole(stdoutStream, cancellationTokenSource.Token);
- // Assert
- exitCode.Should().Be(-2146233029);
- stdOut.Should().Be("Printed");
- }
+ var application = new CliApplicationBuilder()
+ .AddCommand(typeof(CancellableCommand))
+ .UseConsole(console)
+ .Build();
+ var args = new[] {"cancel"};
+
+ // Act
+ var runTask = application.RunAsync(args);
+ cancellationTokenSource.Cancel();
+ var exitCode = await runTask.ConfigureAwait(false);
+ var stdOut = stdoutStream.ToString().Trim();
+
+ // Assert
+ exitCode.Should().Be(-2146233029);
+ stdOut.Should().Be("Printed");
}
}
}
\ No newline at end of file
diff --git a/CliFx.Tests/CliFx.Tests.csproj b/CliFx.Tests/CliFx.Tests.csproj
index 49a04c3..e9c498c 100644
--- a/CliFx.Tests/CliFx.Tests.csproj
+++ b/CliFx.Tests/CliFx.Tests.csproj
@@ -7,6 +7,7 @@
true
opencover
bin/$(Configuration)/Coverage.xml
+ enable
diff --git a/CliFx.Tests/Services/DelegateCommandFactoryTests.cs b/CliFx.Tests/Services/DelegateCommandFactoryTests.cs
index 4f4c08b..31183c5 100644
--- a/CliFx.Tests/Services/DelegateCommandFactoryTests.cs
+++ b/CliFx.Tests/Services/DelegateCommandFactoryTests.cs
@@ -18,7 +18,7 @@ namespace CliFx.Tests.Services
private static IEnumerable GetTestCases_CreateCommand()
{
yield return new TestCaseData(
- new Func(schema => (ICommand) Activator.CreateInstance(schema.Type)),
+ new Func(schema => (ICommand) Activator.CreateInstance(schema.Type!)!),
GetCommandSchema(typeof(HelloWorldDefaultCommand))
);
}
diff --git a/CliFx.Tests/Services/HelpTextRendererTests.cs b/CliFx.Tests/Services/HelpTextRendererTests.cs
index 66f7486..ade3af9 100644
--- a/CliFx.Tests/Services/HelpTextRendererTests.cs
+++ b/CliFx.Tests/Services/HelpTextRendererTests.cs
@@ -93,17 +93,16 @@ namespace CliFx.Tests.Services
IReadOnlyList expectedSubstrings)
{
// Arrange
- using (var stdout = new StringWriter())
- {
- var console = new VirtualConsole(stdout);
- var renderer = new HelpTextRenderer();
+ using var stdout = new StringWriter();
- // Act
- renderer.RenderHelpText(console, source);
+ var console = new VirtualConsole(stdout);
+ var renderer = new HelpTextRenderer();
- // Assert
- stdout.ToString().Should().ContainAll(expectedSubstrings);
- }
+ // Act
+ renderer.RenderHelpText(console, source);
+
+ // Assert
+ stdout.ToString().Should().ContainAll(expectedSubstrings);
}
}
}
\ No newline at end of file
diff --git a/CliFx.Tests/Services/VirtualConsoleTests.cs b/CliFx.Tests/Services/VirtualConsoleTests.cs
index 8b32e9f..be01d62 100644
--- a/CliFx.Tests/Services/VirtualConsoleTests.cs
+++ b/CliFx.Tests/Services/VirtualConsoleTests.cs
@@ -14,30 +14,29 @@ namespace CliFx.Tests.Services
public void All_Smoke_Test()
{
// Arrange
- using (var stdin = new StringReader("hello world"))
- using (var stdout = new StringWriter())
- using (var stderr = new StringWriter())
- {
- var console = new VirtualConsole(stdin, stdout, stderr);
+ using var stdin = new StringReader("hello world");
+ using var stdout = new StringWriter();
+ using var stderr = new StringWriter();
- // Act
- console.ResetColor();
- console.ForegroundColor = ConsoleColor.DarkMagenta;
- console.BackgroundColor = ConsoleColor.DarkMagenta;
+ var console = new VirtualConsole(stdin, stdout, stderr);
- // Assert
- console.Input.Should().BeSameAs(stdin);
- console.Input.Should().NotBeSameAs(Console.In);
- console.IsInputRedirected.Should().BeTrue();
- console.Output.Should().BeSameAs(stdout);
- console.Output.Should().NotBeSameAs(Console.Out);
- console.IsOutputRedirected.Should().BeTrue();
- console.Error.Should().BeSameAs(stderr);
- console.Error.Should().NotBeSameAs(Console.Error);
- console.IsErrorRedirected.Should().BeTrue();
- console.ForegroundColor.Should().NotBe(Console.ForegroundColor);
- console.BackgroundColor.Should().NotBe(Console.BackgroundColor);
- }
+ // Act
+ console.ResetColor();
+ console.ForegroundColor = ConsoleColor.DarkMagenta;
+ console.BackgroundColor = ConsoleColor.DarkMagenta;
+
+ // Assert
+ console.Input.Should().BeSameAs(stdin);
+ console.Input.Should().NotBeSameAs(Console.In);
+ console.IsInputRedirected.Should().BeTrue();
+ console.Output.Should().BeSameAs(stdout);
+ console.Output.Should().NotBeSameAs(Console.Out);
+ console.IsOutputRedirected.Should().BeTrue();
+ console.Error.Should().BeSameAs(stderr);
+ console.Error.Should().NotBeSameAs(Console.Error);
+ console.IsErrorRedirected.Should().BeTrue();
+ console.ForegroundColor.Should().NotBe(Console.ForegroundColor);
+ console.BackgroundColor.Should().NotBe(Console.BackgroundColor);
}
}
}
\ No newline at end of file
diff --git a/CliFx.Tests/TestCommands/CommandExceptionCommand.cs b/CliFx.Tests/TestCommands/CommandExceptionCommand.cs
index 6e047ab..ffefaab 100644
--- a/CliFx.Tests/TestCommands/CommandExceptionCommand.cs
+++ b/CliFx.Tests/TestCommands/CommandExceptionCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Exceptions;
using CliFx.Services;
@@ -13,7 +12,7 @@ namespace CliFx.Tests.TestCommands
public int ExitCode { get; set; } = 1337;
[CommandOption("msg", 'm')]
- public string Message { get; set; }
+ public string? Message { get; set; }
public Task ExecuteAsync(IConsole console) => throw new CommandException(Message, ExitCode);
}
diff --git a/CliFx.Tests/TestCommands/ConcatCommand.cs b/CliFx.Tests/TestCommands/ConcatCommand.cs
index 48a65f9..e357230 100644
--- a/CliFx.Tests/TestCommands/ConcatCommand.cs
+++ b/CliFx.Tests/TestCommands/ConcatCommand.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Threading;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
diff --git a/CliFx.Tests/TestCommands/DivideCommand.cs b/CliFx.Tests/TestCommands/DivideCommand.cs
index d29fe24..71dad4e 100644
--- a/CliFx.Tests/TestCommands/DivideCommand.cs
+++ b/CliFx.Tests/TestCommands/DivideCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
diff --git a/CliFx.Tests/TestCommands/DuplicateOptionNamesCommand.cs b/CliFx.Tests/TestCommands/DuplicateOptionNamesCommand.cs
index 3745658..61f313c 100644
--- a/CliFx.Tests/TestCommands/DuplicateOptionNamesCommand.cs
+++ b/CliFx.Tests/TestCommands/DuplicateOptionNamesCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,10 +8,10 @@ namespace CliFx.Tests.TestCommands
public class DuplicateOptionNamesCommand : ICommand
{
[CommandOption("fruits")]
- public string Apples { get; set; }
+ public string? Apples { get; set; }
[CommandOption("fruits")]
- public string Oranges { get; set; }
+ public string? Oranges { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/DuplicateOptionShortNamesCommand.cs b/CliFx.Tests/TestCommands/DuplicateOptionShortNamesCommand.cs
index 41d2599..542d69f 100644
--- a/CliFx.Tests/TestCommands/DuplicateOptionShortNamesCommand.cs
+++ b/CliFx.Tests/TestCommands/DuplicateOptionShortNamesCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,10 +8,10 @@ namespace CliFx.Tests.TestCommands
public class DuplicateOptionShortNamesCommand : ICommand
{
[CommandOption('f')]
- public string Apples { get; set; }
+ public string? Apples { get; set; }
[CommandOption('f')]
- public string Oranges { get; set; }
+ public string? Oranges { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/EnvironmentVariableCommand.cs b/CliFx.Tests/TestCommands/EnvironmentVariableCommand.cs
index 33ab651..46eacd4 100644
--- a/CliFx.Tests/TestCommands/EnvironmentVariableCommand.cs
+++ b/CliFx.Tests/TestCommands/EnvironmentVariableCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,7 +8,7 @@ namespace CliFx.Tests.TestCommands
public class EnvironmentVariableCommand : ICommand
{
[CommandOption("opt", EnvironmentVariableName = "ENV_SINGLE_VALUE")]
- public string Option { get; set; }
+ public string? Option { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/EnvironmentVariableWithMultipleValuesCommand.cs b/CliFx.Tests/TestCommands/EnvironmentVariableWithMultipleValuesCommand.cs
index 653cc19..3eaf40d 100644
--- a/CliFx.Tests/TestCommands/EnvironmentVariableWithMultipleValuesCommand.cs
+++ b/CliFx.Tests/TestCommands/EnvironmentVariableWithMultipleValuesCommand.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Threading;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -10,7 +9,7 @@ namespace CliFx.Tests.TestCommands
public class EnvironmentVariableWithMultipleValuesCommand : ICommand
{
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
- public IEnumerable Option { get; set; }
+ public IEnumerable? Option { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/EnvironmentVariableWithoutCollectionPropertyCommand.cs b/CliFx.Tests/TestCommands/EnvironmentVariableWithoutCollectionPropertyCommand.cs
index 56f4b13..872ac91 100644
--- a/CliFx.Tests/TestCommands/EnvironmentVariableWithoutCollectionPropertyCommand.cs
+++ b/CliFx.Tests/TestCommands/EnvironmentVariableWithoutCollectionPropertyCommand.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -10,7 +8,7 @@ namespace CliFx.Tests.TestCommands
public class EnvironmentVariableWithoutCollectionPropertyCommand : ICommand
{
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
- public string Option { get; set; }
+ public string? Option { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/ExceptionCommand.cs b/CliFx.Tests/TestCommands/ExceptionCommand.cs
index 4eb0417..9c7f478 100644
--- a/CliFx.Tests/TestCommands/ExceptionCommand.cs
+++ b/CliFx.Tests/TestCommands/ExceptionCommand.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -10,7 +9,7 @@ namespace CliFx.Tests.TestCommands
public class ExceptionCommand : ICommand
{
[CommandOption("msg", 'm')]
- public string Message { get; set; }
+ public string? Message { get; set; }
public Task ExecuteAsync(IConsole console) => throw new Exception(Message);
}
diff --git a/CliFx.Tests/TestCommands/HelloWorldDefaultCommand.cs b/CliFx.Tests/TestCommands/HelloWorldDefaultCommand.cs
index b83685e..fd8eb9b 100644
--- a/CliFx.Tests/TestCommands/HelloWorldDefaultCommand.cs
+++ b/CliFx.Tests/TestCommands/HelloWorldDefaultCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
diff --git a/CliFx.Tests/TestCommands/HelpDefaultCommand.cs b/CliFx.Tests/TestCommands/HelpDefaultCommand.cs
index 54ac7fb..c130217 100644
--- a/CliFx.Tests/TestCommands/HelpDefaultCommand.cs
+++ b/CliFx.Tests/TestCommands/HelpDefaultCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,10 +8,10 @@ namespace CliFx.Tests.TestCommands
public class HelpDefaultCommand : ICommand
{
[CommandOption("option-a", 'a', Description = "OptionA description.")]
- public string OptionA { get; set; }
+ public string? OptionA { get; set; }
[CommandOption("option-b", 'b', Description = "OptionB description.")]
- public string OptionB { get; set; }
+ public string? OptionB { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/HelpNamedCommand.cs b/CliFx.Tests/TestCommands/HelpNamedCommand.cs
index 840be37..c6e3891 100644
--- a/CliFx.Tests/TestCommands/HelpNamedCommand.cs
+++ b/CliFx.Tests/TestCommands/HelpNamedCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,10 +8,10 @@ namespace CliFx.Tests.TestCommands
public class HelpNamedCommand : ICommand
{
[CommandOption("option-c", 'c', Description = "OptionC description.")]
- public string OptionC { get; set; }
+ public string? OptionC { get; set; }
[CommandOption("option-d", 'd', Description = "OptionD description.")]
- public string OptionD { get; set; }
+ public string? OptionD { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/HelpSubCommand.cs b/CliFx.Tests/TestCommands/HelpSubCommand.cs
index 602ab48..e284532 100644
--- a/CliFx.Tests/TestCommands/HelpSubCommand.cs
+++ b/CliFx.Tests/TestCommands/HelpSubCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
@@ -9,7 +8,7 @@ namespace CliFx.Tests.TestCommands
public class HelpSubCommand : ICommand
{
[CommandOption("option-e", 'e', Description = "OptionE description.")]
- public string OptionE { get; set; }
+ public string? OptionE { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
diff --git a/CliFx.Tests/TestCommands/NonAnnotatedCommand.cs b/CliFx.Tests/TestCommands/NonAnnotatedCommand.cs
index b00b7b8..6977532 100644
--- a/CliFx.Tests/TestCommands/NonAnnotatedCommand.cs
+++ b/CliFx.Tests/TestCommands/NonAnnotatedCommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
diff --git a/CliFx.Tests/Utilities/ProgressTickerTests.cs b/CliFx.Tests/Utilities/ProgressTickerTests.cs
index 74a4efb..0a3492b 100644
--- a/CliFx.Tests/Utilities/ProgressTickerTests.cs
+++ b/CliFx.Tests/Utilities/ProgressTickerTests.cs
@@ -17,41 +17,39 @@ namespace CliFx.Tests.Utilities
// Arrange
var formatProvider = CultureInfo.InvariantCulture;
- using (var stdout = new StringWriter(formatProvider))
- {
- var console = new VirtualConsole(TextReader.Null, false, stdout, false, TextWriter.Null, false);
- var ticker = console.CreateProgressTicker();
+ using var stdout = new StringWriter(formatProvider);
- var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
- var progressStringValues = progressValues.Select(p => p.ToString("P2", formatProvider)).ToArray();
+ var console = new VirtualConsole(TextReader.Null, false, stdout, false, TextWriter.Null, false);
+ var ticker = console.CreateProgressTicker();
- // Act
- foreach (var progress in progressValues)
- ticker.Report(progress);
+ var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
+ var progressStringValues = progressValues.Select(p => p.ToString("P2", formatProvider)).ToArray();
- // Assert
- stdout.ToString().Should().ContainAll(progressStringValues);
- }
+ // Act
+ foreach (var progress in progressValues)
+ ticker.Report(progress);
+
+ // Assert
+ stdout.ToString().Should().ContainAll(progressStringValues);
}
[Test]
public void Report_Redirected_Test()
{
// Arrange
- using (var stdout = new StringWriter())
- {
- var console = new VirtualConsole(stdout);
- var ticker = console.CreateProgressTicker();
+ using var stdout = new StringWriter();
- var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
+ var console = new VirtualConsole(stdout);
+ var ticker = console.CreateProgressTicker();
- // Act
- foreach (var progress in progressValues)
- ticker.Report(progress);
+ var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
- // Assert
- stdout.ToString().Should().BeEmpty();
- }
+ // Act
+ foreach (var progress in progressValues)
+ ticker.Report(progress);
+
+ // Assert
+ stdout.ToString().Should().BeEmpty();
}
}
}
\ No newline at end of file
diff --git a/CliFx/Attributes/CommandAttribute.cs b/CliFx/Attributes/CommandAttribute.cs
index 42fb155..aaa613f 100644
--- a/CliFx/Attributes/CommandAttribute.cs
+++ b/CliFx/Attributes/CommandAttribute.cs
@@ -10,27 +10,27 @@ namespace CliFx.Attributes
{
///
/// Command name.
+ /// This can be null if this is the default command.
///
- public string Name { get; }
+ public string? Name { get; }
///
/// Command description, which is used in help text.
///
- public string Description { get; set; }
+ public string? Description { get; set; }
///
/// Initializes an instance of .
///
public CommandAttribute(string name)
{
- Name = name; // can be null
+ Name = name;
}
///
/// Initializes an instance of .
///
public CommandAttribute()
- : this(null)
{
}
}
diff --git a/CliFx/Attributes/CommandOptionAttribute.cs b/CliFx/Attributes/CommandOptionAttribute.cs
index c0f34e8..a1b9ac3 100644
--- a/CliFx/Attributes/CommandOptionAttribute.cs
+++ b/CliFx/Attributes/CommandOptionAttribute.cs
@@ -10,11 +10,13 @@ namespace CliFx.Attributes
{
///
/// Option name.
+ /// Either or must be set.
///
- public string Name { get; }
+ public string? Name { get; }
///
/// Option short name.
+ /// Either or must be set.
///
public char? ShortName { get; }
@@ -26,27 +28,27 @@ namespace CliFx.Attributes
///
/// Option description, which is used in help text.
///
- public string Description { get; set; }
+ public string? Description { get; set; }
///
/// Optional environment variable name that will be used as fallback value if no option value is specified.
///
- public string EnvironmentVariableName { get; set; }
+ public string? EnvironmentVariableName { get; set; }
///
/// Initializes an instance of .
///
- public CommandOptionAttribute(string name, char? shortName)
+ private CommandOptionAttribute(string? name, char? shortName)
{
- Name = name; // can be null
- ShortName = shortName; // can be null
+ Name = name;
+ ShortName = shortName;
}
///
/// Initializes an instance of .
///
public CommandOptionAttribute(string name, char shortName)
- : this(name, (char?)shortName)
+ : this(name, (char?) shortName)
{
}
@@ -62,7 +64,7 @@ namespace CliFx.Attributes
/// Initializes an instance of .
///
public CommandOptionAttribute(char shortName)
- : this(null, shortName)
+ : this(null, (char?) shortName)
{
}
}
diff --git a/CliFx/CliApplication.cs b/CliFx/CliApplication.cs
index 91cf4b1..8b21f02 100644
--- a/CliFx/CliApplication.cs
+++ b/CliFx/CliApplication.cs
@@ -32,15 +32,15 @@ namespace CliFx
IConsole console, ICommandInputParser commandInputParser, ICommandSchemaResolver commandSchemaResolver,
ICommandFactory commandFactory, ICommandInitializer commandInitializer, IHelpTextRenderer helpTextRenderer)
{
- _metadata = metadata.GuardNotNull(nameof(metadata));
- _configuration = configuration.GuardNotNull(nameof(configuration));
+ _metadata = metadata;
+ _configuration = configuration;
- _console = console.GuardNotNull(nameof(console));
- _commandInputParser = commandInputParser.GuardNotNull(nameof(commandInputParser));
- _commandSchemaResolver = commandSchemaResolver.GuardNotNull(nameof(commandSchemaResolver));
- _commandFactory = commandFactory.GuardNotNull(nameof(commandFactory));
- _commandInitializer = commandInitializer.GuardNotNull(nameof(commandInitializer));
- _helpTextRenderer = helpTextRenderer.GuardNotNull(nameof(helpTextRenderer));
+ _console = console;
+ _commandInputParser = commandInputParser;
+ _commandSchemaResolver = commandSchemaResolver;
+ _commandFactory = commandFactory;
+ _commandInitializer = commandInitializer;
+ _helpTextRenderer = helpTextRenderer;
}
private async Task HandleDebugDirectiveAsync(CommandInput commandInput)
@@ -117,7 +117,7 @@ namespace CliFx
}
private int? HandleHelpOption(CommandInput commandInput,
- IReadOnlyList availableCommandSchemas, CommandSchema targetCommandSchema)
+ IReadOnlyList availableCommandSchemas, CommandSchema? targetCommandSchema)
{
// Help should be rendered if it was requested, or when executing a command which isn't defined
var shouldRenderHelp = commandInput.IsHelpOptionSpecified() || targetCommandSchema == null;
@@ -180,8 +180,6 @@ namespace CliFx
///
public async Task RunAsync(IReadOnlyList commandLineArguments)
{
- commandLineArguments.GuardNotNull(nameof(commandLineArguments));
-
try
{
// Parse command input from arguments
@@ -199,7 +197,7 @@ namespace CliFx
HandlePreviewDirective(commandInput) ??
HandleVersionOption(commandInput) ??
HandleHelpOption(commandInput, availableCommandSchemas, targetCommandSchema) ??
- await HandleCommandExecutionAsync(commandInput, targetCommandSchema);
+ await HandleCommandExecutionAsync(commandInput, targetCommandSchema!);
}
catch (Exception ex)
{
@@ -207,7 +205,7 @@ namespace CliFx
// Doing this also gets rid of the annoying Windows troubleshooting dialog that shows up on unhandled exceptions.
// Prefer showing message without stack trace on exceptions coming from CliFx or on CommandException
- if (!ex.Message.IsNullOrWhiteSpace() && (ex is CliFxException || ex is CommandException))
+ if (!string.IsNullOrWhiteSpace(ex.Message) && (ex is CliFxException || ex is CommandException))
{
_console.WithForegroundColor(ConsoleColor.Red, () => _console.Error.WriteLine(ex.Message));
}
diff --git a/CliFx/CliApplicationBuilder.cs b/CliFx/CliApplicationBuilder.cs
index e0be026..85bd103 100644
--- a/CliFx/CliApplicationBuilder.cs
+++ b/CliFx/CliApplicationBuilder.cs
@@ -19,20 +19,18 @@ namespace CliFx
private bool _isDebugModeAllowed = true;
private bool _isPreviewModeAllowed = true;
- private string _title;
- private string _executableName;
- private string _versionText;
- private string _description;
- private IConsole _console;
- private ICommandFactory _commandFactory;
- private ICommandOptionInputConverter _commandOptionInputConverter;
- private IEnvironmentVariablesProvider _environmentVariablesProvider;
+ private string? _title;
+ private string? _executableName;
+ private string? _versionText;
+ private string? _description;
+ private IConsole? _console;
+ private ICommandFactory? _commandFactory;
+ private ICommandOptionInputConverter? _commandOptionInputConverter;
+ private IEnvironmentVariablesProvider? _environmentVariablesProvider;
///
public ICliApplicationBuilder AddCommand(Type commandType)
{
- commandType.GuardNotNull(nameof(commandType));
-
_commandTypes.Add(commandType);
return this;
@@ -41,8 +39,6 @@ namespace CliFx
///
public ICliApplicationBuilder AddCommandsFrom(Assembly commandAssembly)
{
- commandAssembly.GuardNotNull(nameof(commandAssembly));
-
var commandTypes = commandAssembly.ExportedTypes
.Where(t => t.Implements(typeof(ICommand)))
.Where(t => t.IsDefined(typeof(CommandAttribute)))
@@ -71,56 +67,56 @@ namespace CliFx
///
public ICliApplicationBuilder UseTitle(string title)
{
- _title = title.GuardNotNull(nameof(title));
+ _title = title;
return this;
}
///
public ICliApplicationBuilder UseExecutableName(string executableName)
{
- _executableName = executableName.GuardNotNull(nameof(executableName));
+ _executableName = executableName;
return this;
}
///
public ICliApplicationBuilder UseVersionText(string versionText)
{
- _versionText = versionText.GuardNotNull(nameof(versionText));
+ _versionText = versionText;
return this;
}
///
- public ICliApplicationBuilder UseDescription(string description)
+ public ICliApplicationBuilder UseDescription(string? description)
{
- _description = description; // can be null
+ _description = description;
return this;
}
///
public ICliApplicationBuilder UseConsole(IConsole console)
{
- _console = console.GuardNotNull(nameof(console));
+ _console = console;
return this;
}
///
public ICliApplicationBuilder UseCommandFactory(ICommandFactory factory)
{
- _commandFactory = factory.GuardNotNull(nameof(factory));
+ _commandFactory = factory;
return this;
}
///
public ICliApplicationBuilder UseCommandOptionInputConverter(ICommandOptionInputConverter converter)
{
- _commandOptionInputConverter = converter.GuardNotNull(nameof(converter));
+ _commandOptionInputConverter = converter;
return this;
}
///
public ICliApplicationBuilder UseEnvironmentVariablesProvider(IEnvironmentVariablesProvider environmentVariablesProvider)
{
- _environmentVariablesProvider = environmentVariablesProvider.GuardNotNull(nameof(environmentVariablesProvider));
+ _environmentVariablesProvider = environmentVariablesProvider;
return this;
}
@@ -128,13 +124,13 @@ namespace CliFx
public ICliApplication Build()
{
// Use defaults for required parameters that were not configured
- _title = _title ?? GetDefaultTitle() ?? "App";
- _executableName = _executableName ?? GetDefaultExecutableName() ?? "app";
- _versionText = _versionText ?? GetDefaultVersionText() ?? "v1.0";
- _console = _console ?? new SystemConsole();
- _commandFactory = _commandFactory ?? new CommandFactory();
- _commandOptionInputConverter = _commandOptionInputConverter ?? new CommandOptionInputConverter();
- _environmentVariablesProvider = _environmentVariablesProvider ?? new EnvironmentVariablesProvider();
+ _title ??= GetDefaultTitle() ?? "App";
+ _executableName ??= GetDefaultExecutableName() ?? "app";
+ _versionText ??= GetDefaultVersionText() ?? "v1.0";
+ _console ??= new SystemConsole();
+ _commandFactory ??= new CommandFactory();
+ _commandOptionInputConverter ??= new CommandOptionInputConverter();
+ _environmentVariablesProvider ??= new EnvironmentVariablesProvider();
// Project parameters to expected types
var metadata = new ApplicationMetadata(_title, _executableName, _versionText, _description);
@@ -153,7 +149,7 @@ namespace CliFx
// Entry assembly is null in tests
private static Assembly EntryAssembly => LazyEntryAssembly.Value;
- private static string GetDefaultTitle() => EntryAssembly?.GetName().Name;
+ private static string GetDefaultTitle() => EntryAssembly?.GetName().Name ?? "";
private static string GetDefaultExecutableName()
{
@@ -169,6 +165,6 @@ namespace CliFx
return Path.GetFileNameWithoutExtension(entryAssemblyLocation);
}
- private static string GetDefaultVersionText() => EntryAssembly != null ? $"v{EntryAssembly.GetName().Version}" : null;
+ private static string GetDefaultVersionText() => EntryAssembly != null ? $"v{EntryAssembly.GetName().Version}" : "";
}
}
\ No newline at end of file
diff --git a/CliFx/CliFx.csproj b/CliFx/CliFx.csproj
index 8449eb4..371678e 100644
--- a/CliFx/CliFx.csproj
+++ b/CliFx/CliFx.csproj
@@ -1,7 +1,7 @@
- net45;netstandard2.0
+ net45;netstandard2.0;netstandard2.1
0.0.7
Tyrrrz
$(Company)
@@ -18,11 +18,15 @@
True
True
snupkg
+ latest
+ enable
-
+
+
+
diff --git a/CliFx/Exceptions/CliFxException.cs b/CliFx/Exceptions/CliFxException.cs
index 5bbba9b..7e04e9d 100644
--- a/CliFx/Exceptions/CliFxException.cs
+++ b/CliFx/Exceptions/CliFxException.cs
@@ -10,7 +10,7 @@ namespace CliFx.Exceptions
///
/// Initializes an instance of .
///
- public CliFxException(string message)
+ public CliFxException(string? message)
: base(message)
{
}
@@ -18,7 +18,7 @@ namespace CliFx.Exceptions
///
/// Initializes an instance of .
///
- public CliFxException(string message, Exception innerException)
+ public CliFxException(string? message, Exception? innerException)
: base(message, innerException)
{
}
diff --git a/CliFx/Exceptions/CommandException.cs b/CliFx/Exceptions/CommandException.cs
index 4b44994..af3d254 100644
--- a/CliFx/Exceptions/CommandException.cs
+++ b/CliFx/Exceptions/CommandException.cs
@@ -1,5 +1,4 @@
using System;
-using CliFx.Internal;
namespace CliFx.Exceptions
{
@@ -20,16 +19,16 @@ namespace CliFx.Exceptions
///
/// Initializes an instance of .
///
- public CommandException(string message, Exception innerException, int exitCode = DefaultExitCode)
+ public CommandException(string? message, Exception? innerException, int exitCode = DefaultExitCode)
: base(message, innerException)
{
- ExitCode = exitCode.GuardNotZero(nameof(exitCode));
+ ExitCode = exitCode != 0 ? exitCode : throw new ArgumentException("Exit code cannot be zero because that signifies success.");
}
///
/// Initializes an instance of .
///
- public CommandException(string message, int exitCode = DefaultExitCode)
+ public CommandException(string? message, int exitCode = DefaultExitCode)
: this(message, null, exitCode)
{
}
diff --git a/CliFx/Extensions.cs b/CliFx/Extensions.cs
index 19953f1..9b93860 100644
--- a/CliFx/Extensions.cs
+++ b/CliFx/Extensions.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reflection;
-using CliFx.Internal;
using CliFx.Models;
using CliFx.Services;
@@ -17,9 +16,6 @@ namespace CliFx
///
public static ICliApplicationBuilder AddCommands(this ICliApplicationBuilder builder, IReadOnlyList commandTypes)
{
- builder.GuardNotNull(nameof(builder));
- commandTypes.GuardNotNull(nameof(commandTypes));
-
foreach (var commandType in commandTypes)
builder.AddCommand(commandType);
@@ -31,9 +27,6 @@ namespace CliFx
///
public static ICliApplicationBuilder AddCommandsFrom(this ICliApplicationBuilder builder, IReadOnlyList commandAssemblies)
{
- builder.GuardNotNull(nameof(builder));
- commandAssemblies.GuardNotNull(nameof(commandAssemblies));
-
foreach (var commandAssembly in commandAssemblies)
builder.AddCommandsFrom(commandAssembly);
@@ -43,21 +36,13 @@ namespace CliFx
///
/// Adds commands from calling assembly to the application.
///
- public static ICliApplicationBuilder AddCommandsFromThisAssembly(this ICliApplicationBuilder builder)
- {
- builder.GuardNotNull(nameof(builder));
- return builder.AddCommandsFrom(Assembly.GetCallingAssembly());
- }
+ public static ICliApplicationBuilder AddCommandsFromThisAssembly(this ICliApplicationBuilder builder) =>
+ builder.AddCommandsFrom(Assembly.GetCallingAssembly());
///
/// Configures application to use specified factory method for creating new instances of .
///
- public static ICliApplicationBuilder UseCommandFactory(this ICliApplicationBuilder builder, Func factoryMethod)
- {
- builder.GuardNotNull(nameof(builder));
- factoryMethod.GuardNotNull(nameof(factoryMethod));
-
- return builder.UseCommandFactory(new DelegateCommandFactory(factoryMethod));
- }
+ public static ICliApplicationBuilder UseCommandFactory(this ICliApplicationBuilder builder, Func factoryMethod) =>
+ builder.UseCommandFactory(new DelegateCommandFactory(factoryMethod));
}
}
\ No newline at end of file
diff --git a/CliFx/ICliApplicationBuilder.cs b/CliFx/ICliApplicationBuilder.cs
index 374a96d..79d979d 100644
--- a/CliFx/ICliApplicationBuilder.cs
+++ b/CliFx/ICliApplicationBuilder.cs
@@ -47,7 +47,7 @@ namespace CliFx
///
/// Sets application description, which appears in the help text.
///
- ICliApplicationBuilder UseDescription(string description);
+ ICliApplicationBuilder UseDescription(string? description);
///
/// Configures application to use specified implementation of .
diff --git a/CliFx/ICommand.cs b/CliFx/ICommand.cs
index 9d7f53a..9fb2c78 100644
--- a/CliFx/ICommand.cs
+++ b/CliFx/ICommand.cs
@@ -1,5 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx.Services;
namespace CliFx
diff --git a/CliFx/Internal/Extensions.cs b/CliFx/Internal/Extensions.cs
index 7018918..e16f015 100644
--- a/CliFx/Internal/Extensions.cs
+++ b/CliFx/Internal/Extensions.cs
@@ -8,8 +8,6 @@ namespace CliFx.Internal
{
internal static class Extensions
{
- public static bool IsNullOrWhiteSpace(this string s) => string.IsNullOrWhiteSpace(s);
-
public static string Repeat(this char c, int count) => new string(c, count);
public static string AsString(this char c) => c.Repeat(1);
@@ -36,9 +34,9 @@ namespace CliFx.Internal
public static bool Implements(this Type type, Type interfaceType) => type.GetInterfaces().Contains(interfaceType);
- public static Type GetNullableUnderlyingType(this Type type) => Nullable.GetUnderlyingType(type);
+ public static Type? GetNullableUnderlyingType(this Type type) => Nullable.GetUnderlyingType(type);
- public static Type GetEnumerableUnderlyingType(this Type type)
+ public static Type? GetEnumerableUnderlyingType(this Type type)
{
if (type.IsPrimitive)
return null;
@@ -65,5 +63,8 @@ namespace CliFx.Internal
return array;
}
+
+ public static bool IsCollection(this Type type) =>
+ type != typeof(string) && type.GetEnumerableUnderlyingType() != null;
}
}
\ No newline at end of file
diff --git a/CliFx/Internal/Guards.cs b/CliFx/Internal/Guards.cs
deleted file mode 100644
index 4328445..0000000
--- a/CliFx/Internal/Guards.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace CliFx.Internal
-{
- internal static class Guards
- {
- public static T GuardNotNull(this T o, string argName = null) where T : class =>
- o ?? throw new ArgumentNullException(argName);
-
- public static int GuardNotZero(this int i, string argName = null) =>
- i != 0 ? i : throw new ArgumentException("Cannot be zero.", argName);
- }
-}
\ No newline at end of file
diff --git a/CliFx/Models/ApplicationConfiguration.cs b/CliFx/Models/ApplicationConfiguration.cs
index 0a56555..ec9f16a 100644
--- a/CliFx/Models/ApplicationConfiguration.cs
+++ b/CliFx/Models/ApplicationConfiguration.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using CliFx.Internal;
namespace CliFx.Models
{
@@ -30,7 +29,7 @@ namespace CliFx.Models
public ApplicationConfiguration(IReadOnlyList commandTypes,
bool isDebugModeAllowed, bool isPreviewModeAllowed)
{
- CommandTypes = commandTypes.GuardNotNull(nameof(commandTypes));
+ CommandTypes = commandTypes;
IsDebugModeAllowed = isDebugModeAllowed;
IsPreviewModeAllowed = isPreviewModeAllowed;
}
diff --git a/CliFx/Models/ApplicationMetadata.cs b/CliFx/Models/ApplicationMetadata.cs
index 5003e95..5c3f3b6 100644
--- a/CliFx/Models/ApplicationMetadata.cs
+++ b/CliFx/Models/ApplicationMetadata.cs
@@ -1,6 +1,4 @@
-using CliFx.Internal;
-
-namespace CliFx.Models
+namespace CliFx.Models
{
///
/// Metadata associated with an application.
@@ -25,17 +23,17 @@ namespace CliFx.Models
///
/// Application description.
///
- public string Description { get; }
+ public string? Description { get; }
///
/// Initializes an instance of .
///
- public ApplicationMetadata(string title, string executableName, string versionText, string description)
+ public ApplicationMetadata(string title, string executableName, string versionText, string? description)
{
- Title = title.GuardNotNull(nameof(title));
- ExecutableName = executableName.GuardNotNull(nameof(executableName));
- VersionText = versionText.GuardNotNull(nameof(versionText));
- Description = description; // can be null
+ Title = title;
+ ExecutableName = executableName;
+ VersionText = versionText;
+ Description = description;
}
}
}
\ No newline at end of file
diff --git a/CliFx/Models/CommandInput.cs b/CliFx/Models/CommandInput.cs
index b06bd1a..62c3003 100644
--- a/CliFx/Models/CommandInput.cs
+++ b/CliFx/Models/CommandInput.cs
@@ -13,7 +13,7 @@ namespace CliFx.Models
/// Specified command name.
/// Can be null if command was not specified.
///
- public string CommandName { get; }
+ public string? CommandName { get; }
///
/// Specified directives.
@@ -33,18 +33,19 @@ namespace CliFx.Models
///
/// Initializes an instance of .
///
- public CommandInput(string commandName, IReadOnlyList directives, IReadOnlyList options, IReadOnlyDictionary environmentVariables)
+ public CommandInput(string? commandName, IReadOnlyList directives, IReadOnlyList options,
+ IReadOnlyDictionary environmentVariables)
{
- CommandName = commandName; // can be null
- Directives = directives.GuardNotNull(nameof(directives));
- Options = options.GuardNotNull(nameof(options));
- EnvironmentVariables = environmentVariables.GuardNotNull(nameof(environmentVariables));
+ CommandName = commandName;
+ Directives = directives;
+ Options = options;
+ EnvironmentVariables = environmentVariables;
}
///
/// Initializes an instance of .
///
- public CommandInput(string commandName, IReadOnlyList directives, IReadOnlyList options)
+ public CommandInput(string? commandName, IReadOnlyList directives, IReadOnlyList options)
: this(commandName, directives, options, EmptyEnvironmentVariables)
{
}
@@ -52,7 +53,7 @@ namespace CliFx.Models
///
/// Initializes an instance of .
///
- public CommandInput(string commandName, IReadOnlyList options, IReadOnlyDictionary environmentVariables)
+ public CommandInput(string? commandName, IReadOnlyList options, IReadOnlyDictionary environmentVariables)
: this(commandName, EmptyDirectives, options, environmentVariables)
{
}
@@ -60,7 +61,7 @@ namespace CliFx.Models
///
/// Initializes an instance of .
///
- public CommandInput(string commandName, IReadOnlyList options)
+ public CommandInput(string? commandName, IReadOnlyList options)
: this(commandName, EmptyDirectives, options)
{
}
@@ -76,7 +77,7 @@ namespace CliFx.Models
///
/// Initializes an instance of .
///
- public CommandInput(string commandName)
+ public CommandInput(string? commandName)
: this(commandName, EmptyOptions)
{
}
@@ -86,7 +87,7 @@ namespace CliFx.Models
{
var buffer = new StringBuilder();
- if (!CommandName.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(CommandName))
buffer.Append(CommandName);
foreach (var directive in Directives)
diff --git a/CliFx/Models/CommandOptionInput.cs b/CliFx/Models/CommandOptionInput.cs
index 819b260..06feb29 100644
--- a/CliFx/Models/CommandOptionInput.cs
+++ b/CliFx/Models/CommandOptionInput.cs
@@ -24,8 +24,8 @@ namespace CliFx.Models
///
public CommandOptionInput(string alias, IReadOnlyList values)
{
- Alias = alias.GuardNotNull(nameof(alias));
- Values = values.GuardNotNull(nameof(values));
+ Alias = alias;
+ Values = values;
}
///
diff --git a/CliFx/Models/CommandOptionSchema.cs b/CliFx/Models/CommandOptionSchema.cs
index 7e47e33..3a66292 100644
--- a/CliFx/Models/CommandOptionSchema.cs
+++ b/CliFx/Models/CommandOptionSchema.cs
@@ -1,6 +1,5 @@
using System.Reflection;
using System.Text;
-using CliFx.Internal;
namespace CliFx.Models
{
@@ -12,12 +11,12 @@ namespace CliFx.Models
///
/// Underlying property.
///
- public PropertyInfo Property { get; }
+ public PropertyInfo? Property { get; }
///
/// Option name.
///
- public string Name { get; }
+ public string? Name { get; }
///
/// Option short name.
@@ -32,24 +31,24 @@ namespace CliFx.Models
///
/// Option description.
///
- public string Description { get; }
+ public string? Description { get; }
///
/// Optional environment variable name that will be used as fallback value if no option value is specified.
///
- public string EnvironmentVariableName { get; }
+ public string? EnvironmentVariableName { get; }
///
/// Initializes an instance of .
///
- public CommandOptionSchema(PropertyInfo property, string name, char? shortName, bool isRequired, string description, string environmentVariableName)
+ public CommandOptionSchema(PropertyInfo? property, string? name, char? shortName, bool isRequired, string? description, string? environmentVariableName)
{
- Property = property; // can be null
- Name = name; // can be null
- ShortName = shortName; // can be null
+ Property = property;
+ Name = name;
+ ShortName = shortName;
IsRequired = isRequired;
- Description = description; // can be null
- EnvironmentVariableName = environmentVariableName; //can be null
+ Description = description;
+ EnvironmentVariableName = environmentVariableName;
}
///
@@ -60,10 +59,10 @@ namespace CliFx.Models
if (IsRequired)
buffer.Append('*');
- if (!Name.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(Name))
buffer.Append(Name);
- if (!Name.IsNullOrWhiteSpace() && ShortName != null)
+ if (!string.IsNullOrWhiteSpace(Name) && ShortName != null)
buffer.Append('|');
if (ShortName != null)
diff --git a/CliFx/Models/CommandSchema.cs b/CliFx/Models/CommandSchema.cs
index 7cf4b51..2725732 100644
--- a/CliFx/Models/CommandSchema.cs
+++ b/CliFx/Models/CommandSchema.cs
@@ -13,17 +13,17 @@ namespace CliFx.Models
///
/// Underlying type.
///
- public Type Type { get; }
+ public Type? Type { get; }
///
/// Command name.
///
- public string Name { get; }
+ public string? Name { get; }
///
/// Command description.
///
- public string Description { get; }
+ public string? Description { get; }
///
/// Command options.
@@ -33,12 +33,12 @@ namespace CliFx.Models
///
/// Initializes an instance of .
///
- public CommandSchema(Type type, string name, string description, IReadOnlyList options)
+ public CommandSchema(Type? type, string? name, string? description, IReadOnlyList options)
{
- Type = type; // can be null
- Name = name; // can be null
- Description = description; // can be null
- Options = options.GuardNotNull(nameof(options));
+ Type = type;
+ Name = name;
+ Description = description;
+ Options = options;
}
///
@@ -46,7 +46,7 @@ namespace CliFx.Models
{
var buffer = new StringBuilder();
- if (!Name.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(Name))
buffer.Append(Name);
foreach (var option in Options)
diff --git a/CliFx/Models/Extensions.cs b/CliFx/Models/Extensions.cs
index c9e0406..1ae5260 100644
--- a/CliFx/Models/Extensions.cs
+++ b/CliFx/Models/Extensions.cs
@@ -13,13 +13,11 @@ namespace CliFx.Models
///
/// Finds a command that has specified name, or null if not found.
///
- public static CommandSchema FindByName(this IReadOnlyList commandSchemas, string commandName)
+ public static CommandSchema? FindByName(this IReadOnlyList commandSchemas, string? commandName)
{
- commandSchemas.GuardNotNull(nameof(commandSchemas));
-
// If looking for default command, don't compare names directly
// ...because null and empty are both valid names for default command
- if (commandName.IsNullOrWhiteSpace())
+ if (string.IsNullOrWhiteSpace(commandName))
return commandSchemas.FirstOrDefault(c => c.IsDefault());
return commandSchemas.FirstOrDefault(c => string.Equals(c.Name, commandName, StringComparison.OrdinalIgnoreCase));
@@ -28,12 +26,10 @@ namespace CliFx.Models
///
/// Finds parent command to the command that has specified name, or null if not found.
///
- public static CommandSchema FindParent(this IReadOnlyList commandSchemas, string commandName)
+ public static CommandSchema? FindParent(this IReadOnlyList commandSchemas, string? commandName)
{
- commandSchemas.GuardNotNull(nameof(commandSchemas));
-
// If command has no name, it's the default command so it doesn't have a parent
- if (commandName.IsNullOrWhiteSpace())
+ if (string.IsNullOrWhiteSpace(commandName))
return null;
// Repeatedly cut off individual words from the name until we find a command with that name
@@ -56,12 +52,9 @@ namespace CliFx.Models
///
public static bool MatchesAlias(this CommandOptionSchema optionSchema, string alias)
{
- optionSchema.GuardNotNull(nameof(optionSchema));
- alias.GuardNotNull(nameof(alias));
-
// Compare against name. Case is ignored.
var matchesByName =
- !optionSchema.Name.IsNullOrWhiteSpace() &&
+ !string.IsNullOrWhiteSpace(optionSchema.Name) &&
string.Equals(optionSchema.Name, alias, StringComparison.OrdinalIgnoreCase);
// Compare against short name. Case is NOT ignored.
@@ -75,13 +68,8 @@ namespace CliFx.Models
///
/// Finds an option input that matches the option schema specified, or null if not found.
///
- public static CommandOptionInput FindByOptionSchema(this IReadOnlyList optionInputs, CommandOptionSchema optionSchema)
- {
- optionInputs.GuardNotNull(nameof(optionInputs));
- optionSchema.GuardNotNull(nameof(optionSchema));
-
- return optionInputs.FirstOrDefault(o => optionSchema.MatchesAlias(o.Alias));
- }
+ public static CommandOptionInput? FindByOptionSchema(this IReadOnlyList optionInputs, CommandOptionSchema optionSchema) =>
+ optionInputs.FirstOrDefault(o => optionSchema.MatchesAlias(o.Alias));
///
/// Gets valid aliases for the option.
@@ -90,8 +78,8 @@ namespace CliFx.Models
{
var result = new List(2);
- if (!optionSchema.Name.IsNullOrWhiteSpace())
- result.Add(optionSchema.Name);
+ if (!string.IsNullOrWhiteSpace(optionSchema.Name))
+ result.Add(optionSchema.Name!);
if (optionSchema.ShortName != null)
result.Add(optionSchema.ShortName.Value.AsString());
@@ -102,37 +90,25 @@ namespace CliFx.Models
///
/// Gets whether a command was specified in the input.
///
- public static bool IsCommandSpecified(this CommandInput commandInput)
- {
- commandInput.GuardNotNull(nameof(commandInput));
- return !commandInput.CommandName.IsNullOrWhiteSpace();
- }
+ public static bool IsCommandSpecified(this CommandInput commandInput) => !string.IsNullOrWhiteSpace(commandInput.CommandName);
///
/// Gets whether debug directive was specified in the input.
///
- public static bool IsDebugDirectiveSpecified(this CommandInput commandInput)
- {
- commandInput.GuardNotNull(nameof(commandInput));
- return commandInput.Directives.Contains("debug", StringComparer.OrdinalIgnoreCase);
- }
+ public static bool IsDebugDirectiveSpecified(this CommandInput commandInput) =>
+ commandInput.Directives.Contains("debug", StringComparer.OrdinalIgnoreCase);
///
/// Gets whether preview directive was specified in the input.
///
- public static bool IsPreviewDirectiveSpecified(this CommandInput commandInput)
- {
- commandInput.GuardNotNull(nameof(commandInput));
- return commandInput.Directives.Contains("preview", StringComparer.OrdinalIgnoreCase);
- }
+ public static bool IsPreviewDirectiveSpecified(this CommandInput commandInput) =>
+ commandInput.Directives.Contains("preview", StringComparer.OrdinalIgnoreCase);
///
/// Gets whether help option was specified in the input.
///
public static bool IsHelpOptionSpecified(this CommandInput commandInput)
{
- commandInput.GuardNotNull(nameof(commandInput));
-
var firstOption = commandInput.Options.FirstOrDefault();
return firstOption != null && CommandOptionSchema.HelpOption.MatchesAlias(firstOption.Alias);
}
@@ -142,8 +118,6 @@ namespace CliFx.Models
///
public static bool IsVersionOptionSpecified(this CommandInput commandInput)
{
- commandInput.GuardNotNull(nameof(commandInput));
-
var firstOption = commandInput.Options.FirstOrDefault();
return firstOption != null && CommandOptionSchema.VersionOption.MatchesAlias(firstOption.Alias);
}
@@ -151,10 +125,6 @@ namespace CliFx.Models
///
/// Gets whether this command is the default command, i.e. without a name.
///
- public static bool IsDefault(this CommandSchema commandSchema)
- {
- commandSchema.GuardNotNull(nameof(commandSchema));
- return commandSchema.Name.IsNullOrWhiteSpace();
- }
+ public static bool IsDefault(this CommandSchema commandSchema) => string.IsNullOrWhiteSpace(commandSchema.Name);
}
}
\ No newline at end of file
diff --git a/CliFx/Models/HelpTextSource.cs b/CliFx/Models/HelpTextSource.cs
index f1968d0..556f522 100644
--- a/CliFx/Models/HelpTextSource.cs
+++ b/CliFx/Models/HelpTextSource.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using CliFx.Internal;
namespace CliFx.Models
{
@@ -30,9 +29,9 @@ namespace CliFx.Models
IReadOnlyList availableCommandSchemas,
CommandSchema targetCommandSchema)
{
- ApplicationMetadata = applicationMetadata.GuardNotNull(nameof(applicationMetadata));
- AvailableCommandSchemas = availableCommandSchemas.GuardNotNull(nameof(availableCommandSchemas));
- TargetCommandSchema = targetCommandSchema.GuardNotNull(nameof(targetCommandSchema));
+ ApplicationMetadata = applicationMetadata;
+ AvailableCommandSchemas = availableCommandSchemas;
+ TargetCommandSchema = targetCommandSchema;
}
}
}
\ No newline at end of file
diff --git a/CliFx/Services/CommandFactory.cs b/CliFx/Services/CommandFactory.cs
index 261d9a4..9ddb184 100644
--- a/CliFx/Services/CommandFactory.cs
+++ b/CliFx/Services/CommandFactory.cs
@@ -1,5 +1,4 @@
using System;
-using CliFx.Internal;
using CliFx.Models;
namespace CliFx.Services
@@ -10,10 +9,6 @@ namespace CliFx.Services
public class CommandFactory : ICommandFactory
{
///
- public ICommand CreateCommand(CommandSchema commandSchema)
- {
- commandSchema.GuardNotNull(nameof(commandSchema));
- return (ICommand) Activator.CreateInstance(commandSchema.Type);
- }
+ public ICommand CreateCommand(CommandSchema commandSchema) => (ICommand) Activator.CreateInstance(commandSchema.Type);
}
}
\ No newline at end of file
diff --git a/CliFx/Services/CommandInitializer.cs b/CliFx/Services/CommandInitializer.cs
index 046b071..e35d749 100644
--- a/CliFx/Services/CommandInitializer.cs
+++ b/CliFx/Services/CommandInitializer.cs
@@ -18,8 +18,8 @@ namespace CliFx.Services
///
public CommandInitializer(ICommandOptionInputConverter commandOptionInputConverter, IEnvironmentVariablesParser environmentVariablesParser)
{
- _commandOptionInputConverter = commandOptionInputConverter.GuardNotNull(nameof(commandOptionInputConverter));
- _environmentVariablesParser = environmentVariablesParser.GuardNotNull(nameof(environmentVariablesParser));
+ _commandOptionInputConverter = commandOptionInputConverter;
+ _environmentVariablesParser = environmentVariablesParser;
}
///
@@ -41,29 +41,29 @@ namespace CliFx.Services
///
public void InitializeCommand(ICommand command, CommandSchema commandSchema, CommandInput commandInput)
{
- command.GuardNotNull(nameof(command));
- commandSchema.GuardNotNull(nameof(commandSchema));
- commandInput.GuardNotNull(nameof(commandInput));
-
// Keep track of unset required options to report an error at a later stage
var unsetRequiredOptions = commandSchema.Options.Where(o => o.IsRequired).ToList();
//Set command options
foreach (var optionSchema in commandSchema.Options)
{
+ // Ignore special options that are not backed by a property
+ if (optionSchema.Property == null)
+ continue;
+
//Find matching option input
var optionInput = commandInput.Options.FindByOptionSchema(optionSchema);
//If no option input is available fall back to environment variable values
- if (optionInput == null && !optionSchema.EnvironmentVariableName.IsNullOrWhiteSpace())
+ if (optionInput == null && !string.IsNullOrWhiteSpace(optionSchema.EnvironmentVariableName))
{
- var fallbackEnvironmentVariableExists = commandInput.EnvironmentVariables.ContainsKey(optionSchema.EnvironmentVariableName);
+ var fallbackEnvironmentVariableExists = commandInput.EnvironmentVariables.ContainsKey(optionSchema.EnvironmentVariableName!);
//If no environment variable is found or there is no valid value for this option skip it
- if (!fallbackEnvironmentVariableExists || commandInput.EnvironmentVariables[optionSchema.EnvironmentVariableName].IsNullOrWhiteSpace())
+ if (!fallbackEnvironmentVariableExists || string.IsNullOrWhiteSpace(commandInput.EnvironmentVariables[optionSchema.EnvironmentVariableName!]))
continue;
- optionInput = _environmentVariablesParser.GetCommandOptionInputFromEnvironmentVariable(commandInput.EnvironmentVariables[optionSchema.EnvironmentVariableName], optionSchema);
+ optionInput = _environmentVariablesParser.GetCommandOptionInputFromEnvironmentVariable(commandInput.EnvironmentVariables[optionSchema.EnvironmentVariableName!], optionSchema);
}
//No fallback available and no option input was specified, skip option
diff --git a/CliFx/Services/CommandInputParser.cs b/CliFx/Services/CommandInputParser.cs
index ac78cd4..1f3416f 100644
--- a/CliFx/Services/CommandInputParser.cs
+++ b/CliFx/Services/CommandInputParser.cs
@@ -19,8 +19,6 @@ namespace CliFx.Services
///
public CommandInputParser(IEnvironmentVariablesProvider environmentVariablesProvider)
{
- environmentVariablesProvider.GuardNotNull(nameof(environmentVariablesProvider));
-
_environmentVariablesProvider = environmentVariablesProvider;
}
@@ -35,8 +33,6 @@ namespace CliFx.Services
///
public CommandInput ParseCommandInput(IReadOnlyList commandLineArguments)
{
- commandLineArguments.GuardNotNull(nameof(commandLineArguments));
-
var commandNameBuilder = new StringBuilder();
var directives = new List();
var optionsDic = new Dictionary>();
@@ -71,7 +67,7 @@ namespace CliFx.Services
}
// Encountered directive or (part of) command name
- else if (lastOptionAlias.IsNullOrWhiteSpace())
+ else if (string.IsNullOrWhiteSpace(lastOptionAlias))
{
if (commandLineArgument.StartsWith("[", StringComparison.OrdinalIgnoreCase) &&
commandLineArgument.EndsWith("]", StringComparison.OrdinalIgnoreCase))
@@ -89,7 +85,7 @@ namespace CliFx.Services
}
// Encountered option value
- else if (!lastOptionAlias.IsNullOrWhiteSpace())
+ else if (!string.IsNullOrWhiteSpace(lastOptionAlias))
{
optionsDic[lastOptionAlias].Add(commandLineArgument);
}
diff --git a/CliFx/Services/CommandOptionInputConverter.cs b/CliFx/Services/CommandOptionInputConverter.cs
index a9f9c89..c4006fc 100644
--- a/CliFx/Services/CommandOptionInputConverter.cs
+++ b/CliFx/Services/CommandOptionInputConverter.cs
@@ -20,7 +20,7 @@ namespace CliFx.Services
///
public CommandOptionInputConverter(IFormatProvider formatProvider)
{
- _formatProvider = formatProvider.GuardNotNull(nameof(formatProvider));
+ _formatProvider = formatProvider;
}
///
@@ -34,10 +34,8 @@ namespace CliFx.Services
///
/// Converts a single string value to specified target type.
///
- protected virtual object ConvertValue(string value, Type targetType)
+ protected virtual object? ConvertValue(string value, Type targetType)
{
- targetType.GuardNotNull(nameof(targetType));
-
try
{
// String or object
@@ -46,7 +44,7 @@ namespace CliFx.Services
// Bool
if (targetType == typeof(bool))
- return value.IsNullOrWhiteSpace() || bool.Parse(value);
+ return string.IsNullOrWhiteSpace(value) || bool.Parse(value);
// Char
if (targetType == typeof(char))
@@ -115,7 +113,7 @@ namespace CliFx.Services
// Nullable
var nullableUnderlyingType = targetType.GetNullableUnderlyingType();
if (nullableUnderlyingType != null)
- return !value.IsNullOrWhiteSpace() ? ConvertValue(value, nullableUnderlyingType) : null;
+ return !string.IsNullOrWhiteSpace(value) ? ConvertValue(value, nullableUnderlyingType) : null;
// Has a constructor that accepts a single string
var stringConstructor = GetStringConstructor(targetType);
@@ -143,11 +141,8 @@ namespace CliFx.Services
}
///
- public virtual object ConvertOptionInput(CommandOptionInput optionInput, Type targetType)
+ public virtual object? ConvertOptionInput(CommandOptionInput optionInput, Type targetType)
{
- optionInput.GuardNotNull(nameof(optionInput));
- targetType.GuardNotNull(nameof(targetType));
-
// Get the underlying type of IEnumerable if it's implemented by the target type.
// Ignore string type because it's IEnumerable but we don't treat it as such.
var enumerableUnderlyingType = targetType != typeof(string) ? targetType.GetEnumerableUnderlyingType() : null;
diff --git a/CliFx/Services/CommandSchemaResolver.cs b/CliFx/Services/CommandSchemaResolver.cs
index 7820980..23ff8be 100644
--- a/CliFx/Services/CommandSchemaResolver.cs
+++ b/CliFx/Services/CommandSchemaResolver.cs
@@ -36,7 +36,7 @@ namespace CliFx.Services
// Make sure there are no other options with the same name
var existingOptionWithSameName = result
- .Where(o => !o.Name.IsNullOrWhiteSpace())
+ .Where(o => !string.IsNullOrWhiteSpace(o.Name))
.FirstOrDefault(o => string.Equals(o.Name, optionSchema.Name, StringComparison.OrdinalIgnoreCase));
if (existingOptionWithSameName != null)
@@ -68,8 +68,6 @@ namespace CliFx.Services
///
public IReadOnlyList GetCommandSchemas(IReadOnlyList commandTypes)
{
- commandTypes.GuardNotNull(nameof(commandTypes));
-
// Make sure there's at least one command defined
if (!commandTypes.Any())
{
diff --git a/CliFx/Services/DelegateCommandFactory.cs b/CliFx/Services/DelegateCommandFactory.cs
index e855b5d..5dcdb92 100644
--- a/CliFx/Services/DelegateCommandFactory.cs
+++ b/CliFx/Services/DelegateCommandFactory.cs
@@ -1,5 +1,4 @@
using System;
-using CliFx.Internal;
using CliFx.Models;
namespace CliFx.Services
@@ -16,14 +15,10 @@ namespace CliFx.Services
///
public DelegateCommandFactory(Func factoryMethod)
{
- _factoryMethod = factoryMethod.GuardNotNull(nameof(factoryMethod));
+ _factoryMethod = factoryMethod;
}
///
- public ICommand CreateCommand(CommandSchema commandSchema)
- {
- commandSchema.GuardNotNull(nameof(commandSchema));
- return _factoryMethod(commandSchema);
- }
+ public ICommand CreateCommand(CommandSchema commandSchema) => _factoryMethod(commandSchema);
}
}
\ No newline at end of file
diff --git a/CliFx/Services/EnvironmentVariablesParser.cs b/CliFx/Services/EnvironmentVariablesParser.cs
index 23aad29..c678d7a 100644
--- a/CliFx/Services/EnvironmentVariablesParser.cs
+++ b/CliFx/Services/EnvironmentVariablesParser.cs
@@ -11,17 +11,14 @@ namespace CliFx.Services
///
public CommandOptionInput GetCommandOptionInputFromEnvironmentVariable(string environmentVariableValue, CommandOptionSchema targetOptionSchema)
{
- environmentVariableValue.GuardNotNull(nameof(environmentVariableValue));
- targetOptionSchema.GuardNotNull(nameof(targetOptionSchema));
-
//If the option is not a collection do not split environment variable values
- var optionIsCollection = targetOptionSchema.Property.PropertyType.IsCollection();
+ var optionIsCollection = targetOptionSchema.Property != null && targetOptionSchema.Property.PropertyType.IsCollection();
if (!optionIsCollection) return new CommandOptionInput(targetOptionSchema.EnvironmentVariableName, environmentVariableValue);
//If the option is a collection split the values using System separator, empty values are discarded
var environmentVariableValues = environmentVariableValue.Split(Path.PathSeparator)
- .Where(v => !v.IsNullOrWhiteSpace())
+ .Where(v => !string.IsNullOrWhiteSpace(v))
.ToList();
return new CommandOptionInput(targetOptionSchema.EnvironmentVariableName, environmentVariableValues);
diff --git a/CliFx/Services/Extensions.cs b/CliFx/Services/Extensions.cs
index 4828dd5..7c39bd7 100644
--- a/CliFx/Services/Extensions.cs
+++ b/CliFx/Services/Extensions.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using CliFx.Internal;
namespace CliFx.Services
{
@@ -14,9 +12,6 @@ namespace CliFx.Services
///
public static void WithForegroundColor(this IConsole console, ConsoleColor foregroundColor, Action action)
{
- console.GuardNotNull(nameof(console));
- action.GuardNotNull(nameof(action));
-
var lastColor = console.ForegroundColor;
console.ForegroundColor = foregroundColor;
@@ -30,9 +25,6 @@ namespace CliFx.Services
///
public static void WithBackgroundColor(this IConsole console, ConsoleColor backgroundColor, Action action)
{
- console.GuardNotNull(nameof(console));
- action.GuardNotNull(nameof(action));
-
var lastColor = console.BackgroundColor;
console.BackgroundColor = backgroundColor;
@@ -44,32 +36,7 @@ namespace CliFx.Services
///
/// Sets console foreground and background colors, executes specified action, and sets the colors back to the original values.
///
- public static void WithColors(this IConsole console, ConsoleColor foregroundColor, ConsoleColor backgroundColor, Action action)
- {
- console.GuardNotNull(nameof(console));
- action.GuardNotNull(nameof(action));
-
+ public static void WithColors(this IConsole console, ConsoleColor foregroundColor, ConsoleColor backgroundColor, Action action) =>
console.WithForegroundColor(foregroundColor, () => console.WithBackgroundColor(backgroundColor, action));
- }
-
- ///
- /// Gets wether a string representing an environment variable value is escaped (i.e.: surrounded by double quotation marks)
- ///
- public static bool IsEnvironmentVariableEscaped(this string environmentVariableValue)
- {
- environmentVariableValue.GuardNotNull(nameof(environmentVariableValue));
-
- return environmentVariableValue.StartsWith("\"") && environmentVariableValue.EndsWith("\"");
- }
-
- ///
- /// Gets wether the supplied is a collection implementing
- ///
- public static bool IsCollection(this Type type)
- {
- type.GuardNotNull(nameof(type));
-
- return type != typeof(string) && type.GetEnumerableUnderlyingType() != null;
- }
}
}
\ No newline at end of file
diff --git a/CliFx/Services/HelpTextRenderer.cs b/CliFx/Services/HelpTextRenderer.cs
index 9a521d1..4efd9b4 100644
--- a/CliFx/Services/HelpTextRenderer.cs
+++ b/CliFx/Services/HelpTextRenderer.cs
@@ -14,9 +14,6 @@ namespace CliFx.Services
///
public void RenderHelpText(IConsole console, HelpTextSource source)
{
- console.GuardNotNull(nameof(console));
- source.GuardNotNull(nameof(source));
-
// Track position
var column = 0;
var row = 0;
@@ -105,7 +102,7 @@ namespace CliFx.Services
RenderNewLine();
// Description
- if (!source.ApplicationMetadata.Description.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(source.ApplicationMetadata.Description))
{
Render(source.ApplicationMetadata.Description);
RenderNewLine();
@@ -114,7 +111,7 @@ namespace CliFx.Services
void RenderDescription()
{
- if (source.TargetCommandSchema.Description.IsNullOrWhiteSpace())
+ if (string.IsNullOrWhiteSpace(source.TargetCommandSchema.Description))
return;
// Margin
@@ -142,7 +139,7 @@ namespace CliFx.Services
Render(source.ApplicationMetadata.ExecutableName);
// Command name
- if (!source.TargetCommandSchema.IsDefault())
+ if (!string.IsNullOrWhiteSpace(source.TargetCommandSchema.Name))
{
Render(" ");
RenderWithColor(source.TargetCommandSchema.Name, ConsoleColor.Cyan);
@@ -195,19 +192,19 @@ namespace CliFx.Services
}
// Delimiter
- if (!optionSchema.Name.IsNullOrWhiteSpace() && optionSchema.ShortName != null)
+ if (!string.IsNullOrWhiteSpace(optionSchema.Name) && optionSchema.ShortName != null)
{
Render("|");
}
// Name
- if (!optionSchema.Name.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(optionSchema.Name))
{
RenderWithColor($"--{optionSchema.Name}", ConsoleColor.White);
}
// Description
- if (!optionSchema.Description.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(optionSchema.Description))
{
RenderColumnIndent();
Render(optionSchema.Description);
@@ -231,14 +228,14 @@ namespace CliFx.Services
// Child commands
foreach (var childCommandSchema in childCommandSchemas)
{
- var relativeCommandName = GetRelativeCommandName(childCommandSchema, source.TargetCommandSchema);
+ var relativeCommandName = GetRelativeCommandName(childCommandSchema, source.TargetCommandSchema)!;
// Name
RenderIndent();
RenderWithColor(relativeCommandName, ConsoleColor.Cyan);
// Description
- if (!childCommandSchema.Description.IsNullOrWhiteSpace())
+ if (!string.IsNullOrWhiteSpace(childCommandSchema.Description))
{
RenderColumnIndent();
Render(childCommandSchema.Description);
@@ -254,7 +251,7 @@ namespace CliFx.Services
Render("You can run `");
Render(source.ApplicationMetadata.ExecutableName);
- if (!source.TargetCommandSchema.IsDefault())
+ if (!string.IsNullOrWhiteSpace(source.TargetCommandSchema.Name))
{
Render(" ");
RenderWithColor(source.TargetCommandSchema.Name, ConsoleColor.Cyan);
@@ -285,8 +282,8 @@ namespace CliFx.Services
public partial class HelpTextRenderer
{
- private static string GetRelativeCommandName(CommandSchema commandSchema, CommandSchema parentCommandSchema) =>
- parentCommandSchema.Name.IsNullOrWhiteSpace()
+ private static string? GetRelativeCommandName(CommandSchema commandSchema, CommandSchema parentCommandSchema) =>
+ string.IsNullOrWhiteSpace(parentCommandSchema.Name) || string.IsNullOrWhiteSpace(commandSchema.Name)
? commandSchema.Name
: commandSchema.Name.Substring(parentCommandSchema.Name.Length + 1);
}
diff --git a/CliFx/Services/ICommandOptionInputConverter.cs b/CliFx/Services/ICommandOptionInputConverter.cs
index 42cdcfe..8e51b09 100644
--- a/CliFx/Services/ICommandOptionInputConverter.cs
+++ b/CliFx/Services/ICommandOptionInputConverter.cs
@@ -11,6 +11,6 @@ namespace CliFx.Services
///
/// Converts an option to specified target type.
///
- object ConvertOptionInput(CommandOptionInput optionInput, Type targetType);
+ object? ConvertOptionInput(CommandOptionInput optionInput, Type targetType);
}
}
\ No newline at end of file
diff --git a/CliFx/Services/SystemConsole.cs b/CliFx/Services/SystemConsole.cs
index 47456e5..865edad 100644
--- a/CliFx/Services/SystemConsole.cs
+++ b/CliFx/Services/SystemConsole.cs
@@ -9,7 +9,7 @@ namespace CliFx.Services
///
public class SystemConsole : IConsole
{
- private CancellationTokenSource _cancellationTokenSource;
+ private CancellationTokenSource? _cancellationTokenSource;
///
public TextReader Input => Console.In;
diff --git a/CliFx/Services/VirtualConsole.cs b/CliFx/Services/VirtualConsole.cs
index 73ce481..05382fb 100644
--- a/CliFx/Services/VirtualConsole.cs
+++ b/CliFx/Services/VirtualConsole.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Threading;
-using CliFx.Internal;
namespace CliFx.Services
{
@@ -46,11 +45,11 @@ namespace CliFx.Services
TextWriter error, bool isErrorRedirected,
CancellationToken cancellationToken = default)
{
- Input = input.GuardNotNull(nameof(input));
+ Input = input;
IsInputRedirected = isInputRedirected;
- Output = output.GuardNotNull(nameof(output));
+ Output = output;
IsOutputRedirected = isOutputRedirected;
- Error = error.GuardNotNull(nameof(error));
+ Error = error;
IsErrorRedirected = isErrorRedirected;
_cancellationToken = cancellationToken;
}