mirror of
				https://github.com/Tyrrrz/CliFx.git
				synced 2025-10-25 15:19:17 +00:00 
			
		
		
		
	Add xml documentation
This commit is contained in:
		| @@ -1,20 +1,34 @@ | ||||
| using System; | ||||
| using CliFx.Internal; | ||||
|  | ||||
| namespace CliFx.Attributes | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Annotates a type that defines a command. | ||||
|     /// </summary> | ||||
|     [AttributeUsage(AttributeTargets.Class, Inherited = false)] | ||||
|     public class CommandAttribute : Attribute | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Command name. | ||||
|         /// </summary> | ||||
|         public string Name { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Command description, which is used in help text. | ||||
|         /// </summary> | ||||
|         public string Description { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandAttribute(string name) | ||||
|         { | ||||
|             Name = name; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandAttribute() | ||||
|             : this(null) | ||||
|         { | ||||
|   | ||||
| @@ -2,35 +2,65 @@ | ||||
|  | ||||
| namespace CliFx.Attributes | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Annotates a property that defines a command option. | ||||
|     /// </summary> | ||||
|     [AttributeUsage(AttributeTargets.Property)] | ||||
|     public class CommandOptionAttribute : Attribute | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Option name. | ||||
|         /// </summary> | ||||
|         public string Name { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option short name. | ||||
|         /// </summary> | ||||
|         public char? ShortName { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option group name. | ||||
|         /// </summary> | ||||
|         public string GroupName { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Whether an option is required. | ||||
|         /// </summary> | ||||
|         public bool IsRequired { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option description, which is used in help text. | ||||
|         /// </summary> | ||||
|         public string Description { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionAttribute(string name, char? shortName) | ||||
|         { | ||||
|             Name = name; | ||||
|             ShortName = shortName; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionAttribute(string name, char shortName) | ||||
|             : this(name, (char?) shortName) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionAttribute(string name) | ||||
|             : this(name, null) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionAttribute"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionAttribute(char shortName) | ||||
|             : this(null, shortName) | ||||
|         { | ||||
|   | ||||
| @@ -10,6 +10,9 @@ using CliFx.Services; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICliApplication"/>. | ||||
|     /// </summary> | ||||
|     public partial class CliApplication : ICliApplication | ||||
|     { | ||||
|         private readonly ApplicationMetadata _applicationMetadata; | ||||
| @@ -22,6 +25,9 @@ namespace CliFx | ||||
|         private readonly ICommandInitializer _commandInitializer; | ||||
|         private readonly ICommandHelpTextRenderer _commandHelpTextRenderer; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CliApplication"/>. | ||||
|         /// </summary> | ||||
|         public CliApplication(ApplicationMetadata applicationMetadata, IReadOnlyList<Type> commandTypes, | ||||
|             IConsole console, ICommandInputParser commandInputParser, ICommandSchemaResolver commandSchemaResolver, | ||||
|             ICommandFactory commandFactory, ICommandInitializer commandInitializer, ICommandHelpTextRenderer commandHelpTextRenderer) | ||||
| @@ -98,6 +104,7 @@ namespace CliFx | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public async Task<int> RunAsync(IReadOnlyList<string> commandLineArguments) | ||||
|         { | ||||
|             try | ||||
|   | ||||
| @@ -9,6 +9,9 @@ using CliFx.Services; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICliApplicationBuilder"/>. | ||||
|     /// </summary> | ||||
|     public class CliApplicationBuilder : ICliApplicationBuilder | ||||
|     { | ||||
|         private readonly HashSet<Type> _commandTypes = new HashSet<Type>(); | ||||
| @@ -19,12 +22,14 @@ namespace CliFx | ||||
|         private IConsole _console; | ||||
|         private ICommandFactory _commandFactory; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder WithCommand(Type commandType) | ||||
|         { | ||||
|             _commandTypes.Add(commandType); | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder WithCommandsFrom(Assembly commandAssembly) | ||||
|         { | ||||
|             var commandTypes = commandAssembly.ExportedTypes.Where(t => t.Implements(typeof(ICommand))); | ||||
| @@ -35,30 +40,35 @@ namespace CliFx | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder UseTitle(string title) | ||||
|         { | ||||
|             _title = title; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ICliApplicationBuilder UseExecutableName(string exeName) | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder UseExecutableName(string executableName) | ||||
|         { | ||||
|             _executableName = exeName; | ||||
|             _executableName = executableName; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder UseVersionText(string version) | ||||
|         { | ||||
|             _versionText = version; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder UseConsole(IConsole console) | ||||
|         { | ||||
|             _console = console; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplicationBuilder UseCommandFactory(ICommandFactory factory) | ||||
|         { | ||||
|             _commandFactory = factory; | ||||
| @@ -86,6 +96,7 @@ namespace CliFx | ||||
|                 UseCommandFactory(new CommandFactory()); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICliApplication Build() | ||||
|         { | ||||
|             // Use defaults for required parameters that were not configured | ||||
|   | ||||
| @@ -2,17 +2,29 @@ | ||||
|  | ||||
| namespace CliFx.Exceptions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Thrown when an input command option can't be converted. | ||||
|     /// </summary> | ||||
|     public class CannotConvertCommandOptionException : CliFxException | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CannotConvertCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public CannotConvertCommandOptionException() | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CannotConvertCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public CannotConvertCommandOptionException(string message) | ||||
|             : base(message) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CannotConvertCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public CannotConvertCommandOptionException(string message, Exception innerException) | ||||
|             : base(message, innerException) | ||||
|         { | ||||
|   | ||||
| @@ -2,18 +2,30 @@ | ||||
|  | ||||
| namespace CliFx.Exceptions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Domain exception thrown within CliFx. | ||||
|     /// </summary> | ||||
|     public abstract class CliFxException : Exception | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CliFxException"/>. | ||||
|         /// </summary> | ||||
|         protected CliFxException(string message) | ||||
|             : base(message) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CliFxException"/>. | ||||
|         /// </summary> | ||||
|         protected CliFxException(string message, Exception innerException) | ||||
|             : base(message, innerException) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CliFxException"/>. | ||||
|         /// </summary> | ||||
|         protected CliFxException() | ||||
|         { | ||||
|         } | ||||
|   | ||||
| @@ -2,26 +2,45 @@ | ||||
|  | ||||
| namespace CliFx.Exceptions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Thrown when a command cannot proceed with normal execution due to error. | ||||
|     /// Use this exception if you want to specify an exit code to use when the process terminates. | ||||
|     /// </summary> | ||||
|     public class CommandErrorException : CliFxException | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Process exit code. | ||||
|         /// </summary> | ||||
|         public int ExitCode { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandErrorException"/>. | ||||
|         /// </summary> | ||||
|         public CommandErrorException(int exitCode, string message, Exception innerException) | ||||
|             : base(message, innerException) | ||||
|         { | ||||
|             ExitCode = exitCode; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandErrorException"/>. | ||||
|         /// </summary> | ||||
|         public CommandErrorException(int exitCode, Exception innerException) | ||||
|             : this(exitCode, null, innerException) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandErrorException"/>. | ||||
|         /// </summary> | ||||
|         public CommandErrorException(int exitCode, string message) | ||||
|             : this(exitCode, message, null) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandErrorException"/>. | ||||
|         /// </summary> | ||||
|         public CommandErrorException(int exitCode) | ||||
|             : this(exitCode, null, null) | ||||
|         { | ||||
|   | ||||
| @@ -2,17 +2,29 @@ | ||||
|  | ||||
| namespace CliFx.Exceptions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Thrown when a required command option was not set. | ||||
|     /// </summary> | ||||
|     public class MissingCommandOptionException : CliFxException | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="MissingCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public MissingCommandOptionException() | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="MissingCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public MissingCommandOptionException(string message) | ||||
|             : base(message) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="MissingCommandOptionException"/>. | ||||
|         /// </summary> | ||||
|         public MissingCommandOptionException(string message, Exception innerException) | ||||
|             : base(message, innerException) | ||||
|         { | ||||
|   | ||||
| @@ -5,8 +5,14 @@ using CliFx.Services; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Extensions for <see cref="CliFx"/>. | ||||
|     /// </summary> | ||||
|     public static class Extensions | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Adds multiple commands to the application. | ||||
|         /// </summary> | ||||
|         public static ICliApplicationBuilder WithCommands(this ICliApplicationBuilder builder, IReadOnlyList<Type> commandTypes) | ||||
|         { | ||||
|             foreach (var commandType in commandTypes) | ||||
| @@ -15,6 +21,9 @@ namespace CliFx | ||||
|             return builder; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Adds commands from specified assemblies to the application. | ||||
|         /// </summary> | ||||
|         public static ICliApplicationBuilder WithCommandsFrom(this ICliApplicationBuilder builder, IReadOnlyList<Assembly> commandAssemblies) | ||||
|         { | ||||
|             foreach (var commandAssembly in commandAssemblies) | ||||
| @@ -23,9 +32,15 @@ namespace CliFx | ||||
|             return builder; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Adds commands from calling assembly to the application. | ||||
|         /// </summary> | ||||
|         public static ICliApplicationBuilder WithCommandsFromThisAssembly(this ICliApplicationBuilder builder) => | ||||
|             builder.WithCommandsFrom(Assembly.GetCallingAssembly()); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Configures application to use specified factory method for creating new instances of <see cref="ICommand"/>. | ||||
|         /// </summary> | ||||
|         public static ICliApplicationBuilder UseCommandFactory(this ICliApplicationBuilder builder, Func<Type, ICommand> factoryMethod) => | ||||
|             builder.UseCommandFactory(new DelegateCommandFactory(factoryMethod)); | ||||
|     } | ||||
|   | ||||
| @@ -3,8 +3,15 @@ using System.Threading.Tasks; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Entry point for a command line application. | ||||
|     /// </summary> | ||||
|     public interface ICliApplication | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Runs application with specified command line arguments. | ||||
|         /// Returns exit code. | ||||
|         /// </summary> | ||||
|         Task<int> RunAsync(IReadOnlyList<string> commandLineArguments); | ||||
|     } | ||||
| } | ||||
| @@ -4,22 +4,50 @@ using CliFx.Services; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Builds an instance of <see cref="ICliApplication"/>. | ||||
|     /// </summary> | ||||
|     public interface ICliApplicationBuilder | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Adds a command of specified type to the application. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder WithCommand(Type commandType); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Adds commands from specified assembly to the application. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder WithCommandsFrom(Assembly commandAssembly); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Sets application title, which appears in the help text. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder UseTitle(string title); | ||||
|  | ||||
|         ICliApplicationBuilder UseExecutableName(string exeName); | ||||
|         /// <summary> | ||||
|         /// Sets application executable name, which appears in the help text. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder UseExecutableName(string executableName); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Sets application version text, which appears in the help text and when the user requests version information. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder UseVersionText(string version); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Configures application to use specified implementation of <see cref="IConsole"/>. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder UseConsole(IConsole console); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Configures application to use specified implementation of <see cref="ICommandFactory"/>. | ||||
|         /// </summary> | ||||
|         ICliApplicationBuilder UseCommandFactory(ICommandFactory factory); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Creates an instance of <see cref="ICliApplication"/> using configured parameters. | ||||
|         /// Default values are used in place of parameters that were not specified. | ||||
|         /// </summary> | ||||
|         ICliApplication Build(); | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,15 @@ using CliFx.Services; | ||||
|  | ||||
| namespace CliFx | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Point of interaction between a user and command line interface. | ||||
|     /// </summary> | ||||
|     public interface ICommand | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Executes command using specified implementation of <see cref="IConsole"/>. | ||||
|         /// This method is called when the command is invoked by a user through command line interface. | ||||
|         /// </summary> | ||||
|         Task ExecuteAsync(IConsole console); | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +1,28 @@ | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Metadata associated with an application. | ||||
|     /// </summary> | ||||
|     public class ApplicationMetadata | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Application title. | ||||
|         /// </summary> | ||||
|         public string Title { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Application executable name. | ||||
|         /// </summary> | ||||
|         public string ExecutableName { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Application version text. | ||||
|         /// </summary> | ||||
|         public string VersionText { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="ApplicationMetadata"/>. | ||||
|         /// </summary> | ||||
|         public ApplicationMetadata(string title, string executableName, string versionText) | ||||
|         { | ||||
|             Title = title; | ||||
|   | ||||
| @@ -4,33 +4,55 @@ using CliFx.Internal; | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Parsed command line input. | ||||
|     /// </summary> | ||||
|     public partial class CommandInput | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Specified command name. | ||||
|         /// </summary> | ||||
|         public string CommandName { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Specified options. | ||||
|         /// </summary> | ||||
|         public IReadOnlyList<CommandOptionInput> Options { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandInput(string commandName, IReadOnlyList<CommandOptionInput> options) | ||||
|         { | ||||
|             CommandName = commandName; | ||||
|             Options = options; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandInput(IReadOnlyList<CommandOptionInput> options) | ||||
|             : this(null, options) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandInput(string commandName) | ||||
|             : this(commandName, new CommandOptionInput[0]) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandInput() | ||||
|             : this(null, new CommandOptionInput[0]) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var buffer = new StringBuilder(); | ||||
| @@ -53,6 +75,9 @@ namespace CliFx.Models | ||||
|  | ||||
|     public partial class CommandInput | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Empty input. | ||||
|         /// </summary> | ||||
|         public static CommandInput Empty { get; } = new CommandInput(); | ||||
|     } | ||||
| } | ||||
| @@ -3,28 +3,47 @@ using System.Text; | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Parsed option from command line input. | ||||
|     /// </summary> | ||||
|     public class CommandOptionInput | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Specified option alias. | ||||
|         /// </summary> | ||||
|         public string Alias { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Specified values. | ||||
|         /// </summary> | ||||
|         public IReadOnlyList<string> Values { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionInput(string alias, IReadOnlyList<string> values) | ||||
|         { | ||||
|             Alias = alias; | ||||
|             Values = values; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionInput(string alias, string value) | ||||
|             : this(alias, new[] {value}) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionInput"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionInput(string alias) | ||||
|             : this(alias, new string[0]) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var buffer = new StringBuilder(); | ||||
|   | ||||
| @@ -4,20 +4,44 @@ using CliFx.Internal; | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Schema of a defined command option. | ||||
|     /// </summary> | ||||
|     public class CommandOptionSchema | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Underlying property. | ||||
|         /// </summary> | ||||
|         public PropertyInfo Property { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option name. | ||||
|         /// </summary> | ||||
|         public string Name { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option short name. | ||||
|         /// </summary> | ||||
|         public char? ShortName { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option group name. | ||||
|         /// </summary> | ||||
|         public string GroupName { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Whether an option is required. | ||||
|         /// </summary> | ||||
|         public bool IsRequired { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Option description. | ||||
|         /// </summary> | ||||
|         public string Description { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionSchema"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionSchema(PropertyInfo property, string name, char? shortName, | ||||
|             string groupName, bool isRequired, string description) | ||||
|         { | ||||
| @@ -29,6 +53,7 @@ namespace CliFx.Models | ||||
|             Description = description; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var buffer = new StringBuilder(); | ||||
|   | ||||
| @@ -5,16 +5,34 @@ using CliFx.Internal; | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Schema of a defined command. | ||||
|     /// </summary> | ||||
|     public class CommandSchema | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Underlying type. | ||||
|         /// </summary> | ||||
|         public Type Type { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Command name. | ||||
|         /// </summary> | ||||
|         public string Name { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Command description. | ||||
|         /// </summary> | ||||
|         public string Description { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Command options. | ||||
|         /// </summary> | ||||
|         public IReadOnlyList<CommandOptionSchema> Options { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandSchema"/>. | ||||
|         /// </summary> | ||||
|         public CommandSchema(Type type, string name, string description, IReadOnlyList<CommandOptionSchema> options) | ||||
|         { | ||||
|             Type = type; | ||||
| @@ -23,6 +41,7 @@ namespace CliFx.Models | ||||
|             Options = options; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var buffer = new StringBuilder(); | ||||
|   | ||||
| @@ -5,10 +5,19 @@ using CliFx.Internal; | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Extensions for <see cref="Models"/>. | ||||
|     /// </summary> | ||||
|     public static class Extensions | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets whether a command was specified in the input. | ||||
|         /// </summary> | ||||
|         public static bool IsCommandSpecified(this CommandInput commandInput) => !commandInput.CommandName.IsNullOrWhiteSpace(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets whether help was requested in the input. | ||||
|         /// </summary> | ||||
|         public static bool IsHelpRequested(this CommandInput commandInput) | ||||
|         { | ||||
|             var firstOptionAlias = commandInput.Options.FirstOrDefault()?.Alias; | ||||
| @@ -18,6 +27,9 @@ namespace CliFx.Models | ||||
|                    string.Equals(firstOptionAlias, "?", StringComparison.Ordinal); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets whether version information was requested in the input. | ||||
|         /// </summary> | ||||
|         public static bool IsVersionRequested(this CommandInput commandInput) | ||||
|         { | ||||
|             var firstOptionAlias = commandInput.Options.FirstOrDefault()?.Alias; | ||||
| @@ -25,11 +37,20 @@ namespace CliFx.Models | ||||
|             return string.Equals(firstOptionAlias, "version", StringComparison.OrdinalIgnoreCase); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets whether this command is the default command, i.e. without a name. | ||||
|         /// </summary> | ||||
|         public static bool IsDefault(this CommandSchema commandSchema) => commandSchema.Name.IsNullOrWhiteSpace(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Finds a command that has specified name, or null if not found. | ||||
|         /// </summary> | ||||
|         public static CommandSchema FindByName(this IReadOnlyList<CommandSchema> commandSchemas, string commandName) => | ||||
|             commandSchemas.FirstOrDefault(c => string.Equals(c.Name, commandName, StringComparison.OrdinalIgnoreCase)); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Finds parent command to the command that has specified name, or null if not found. | ||||
|         /// </summary> | ||||
|         public static CommandSchema FindParent(this IReadOnlyList<CommandSchema> commandSchemas, string commandName) | ||||
|         { | ||||
|             // If command has no name, it's the default command so it doesn't have a parent | ||||
| @@ -51,6 +72,9 @@ namespace CliFx.Models | ||||
|             return commandSchemas.FirstOrDefault(c => c.IsDefault()); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Finds an option that matches specified alias, or null if not found. | ||||
|         /// </summary> | ||||
|         public static CommandOptionSchema FindByAlias(this IReadOnlyList<CommandOptionSchema> optionSchemas, string alias) | ||||
|         { | ||||
|             foreach (var optionSchema in optionSchemas) | ||||
|   | ||||
| @@ -2,14 +2,29 @@ | ||||
|  | ||||
| namespace CliFx.Models | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Source information used to generate help text. | ||||
|     /// </summary> | ||||
|     public class HelpTextSource | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Application metadata. | ||||
|         /// </summary> | ||||
|         public ApplicationMetadata ApplicationMetadata { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Schemas of commands available in the application. | ||||
|         /// </summary> | ||||
|         public IReadOnlyList<CommandSchema> AvailableCommandSchemas { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Schema of the command for which help text is to be generated. | ||||
|         /// </summary> | ||||
|         public CommandSchema TargetCommandSchema { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="HelpTextSource"/>. | ||||
|         /// </summary> | ||||
|         public HelpTextSource(ApplicationMetadata applicationMetadata, | ||||
|             IReadOnlyList<CommandSchema> availableCommandSchemas, | ||||
|             CommandSchema targetCommandSchema) | ||||
|   | ||||
| @@ -2,8 +2,12 @@ | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandFactory"/>. | ||||
|     /// </summary> | ||||
|     public class CommandFactory : ICommandFactory | ||||
|     { | ||||
|         /// <inheritdoc /> | ||||
|         public ICommand CreateCommand(Type commandType) => (ICommand) Activator.CreateInstance(commandType); | ||||
|     } | ||||
| } | ||||
| @@ -6,8 +6,12 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandHelpTextRenderer"/>. | ||||
|     /// </summary> | ||||
|     public partial class CommandHelpTextRenderer : ICommandHelpTextRenderer | ||||
|     { | ||||
|         /// <inheritdoc /> | ||||
|         public void RenderHelpText(IConsole console, HelpTextSource source) => new Impl(console, source).RenderHelpText(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -7,20 +7,30 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandInitializer"/>. | ||||
|     /// </summary> | ||||
|     public class CommandInitializer : ICommandInitializer | ||||
|     { | ||||
|         private readonly ICommandOptionInputConverter _commandOptionInputConverter; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInitializer"/>. | ||||
|         /// </summary> | ||||
|         public CommandInitializer(ICommandOptionInputConverter commandOptionInputConverter) | ||||
|         { | ||||
|             _commandOptionInputConverter = commandOptionInputConverter; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandInitializer"/>. | ||||
|         /// </summary> | ||||
|         public CommandInitializer() | ||||
|             : this(new CommandOptionInputConverter()) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public void InitializeCommand(ICommand command, CommandSchema schema, CommandInput input) | ||||
|         { | ||||
|             // Set command options | ||||
|   | ||||
| @@ -6,9 +6,13 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandInputParser"/>. | ||||
|     /// </summary> | ||||
|     public class CommandInputParser : ICommandInputParser | ||||
|     { | ||||
|         // TODO: refactor | ||||
|         /// <inheritdoc /> | ||||
|         public CommandInput ParseInput(IReadOnlyList<string> commandLineArguments) | ||||
|         { | ||||
|             // Initialize command name placeholder | ||||
|   | ||||
| @@ -8,15 +8,24 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandOptionInputConverter"/>. | ||||
|     /// </summary> | ||||
|     public class CommandOptionInputConverter : ICommandOptionInputConverter | ||||
|     { | ||||
|         private readonly IFormatProvider _formatProvider; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionInputConverter"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionInputConverter(IFormatProvider formatProvider) | ||||
|         { | ||||
|             _formatProvider = formatProvider; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="CommandOptionInputConverter"/>. | ||||
|         /// </summary> | ||||
|         public CommandOptionInputConverter() | ||||
|             : this(CultureInfo.InvariantCulture) | ||||
|         { | ||||
| @@ -232,6 +241,7 @@ namespace CliFx.Services | ||||
|         } | ||||
|  | ||||
|         // TODO: refactor this | ||||
|         /// <inheritdoc /> | ||||
|         public object ConvertOption(CommandOptionInput option, Type targetType) | ||||
|         { | ||||
|             if (targetType != typeof(string) && targetType.IsEnumerable()) | ||||
|   | ||||
| @@ -7,6 +7,9 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Default implementation of <see cref="ICommandSchemaResolver"/>. | ||||
|     /// </summary> | ||||
|     public class CommandSchemaResolver : ICommandSchemaResolver | ||||
|     { | ||||
|         private CommandOptionSchema GetCommandOptionSchema(PropertyInfo optionProperty) | ||||
| @@ -24,7 +27,7 @@ namespace CliFx.Services | ||||
|                 attribute.Description); | ||||
|         } | ||||
|  | ||||
|         // TODO: validate stuff like duplicate names, multiple default commands, etc | ||||
|         /// <inheritdoc /> | ||||
|         public CommandSchema GetCommandSchema(Type commandType) | ||||
|         { | ||||
|             if (!commandType.Implements(typeof(ICommand))) | ||||
|   | ||||
| @@ -2,15 +2,22 @@ | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Implementation of <see cref="ICommandFactory"/> that uses a factory method to create commands. | ||||
|     /// </summary> | ||||
|     public class DelegateCommandFactory : ICommandFactory | ||||
|     { | ||||
|         private readonly Func<Type, ICommand> _factoryMethod; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="DelegateCommandFactory"/>. | ||||
|         /// </summary> | ||||
|         public DelegateCommandFactory(Func<Type, ICommand> factoryMethod) | ||||
|         { | ||||
|             _factoryMethod = factoryMethod; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ICommand CreateCommand(Type commandType) => _factoryMethod(commandType); | ||||
|     } | ||||
| } | ||||
| @@ -5,12 +5,20 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Extensions for <see cref="Services"/> | ||||
|     /// </summary> | ||||
|     public static class Extensions | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Resolves command schemas for commands of specified types. | ||||
|         /// </summary> | ||||
|         public static IReadOnlyList<CommandSchema> GetCommandSchemas(this ICommandSchemaResolver resolver, | ||||
|             IReadOnlyList<Type> commandTypes) => | ||||
|             commandTypes.Select(resolver.GetCommandSchema).ToArray(); | ||||
|             IReadOnlyList<Type> commandTypes) => commandTypes.Select(resolver.GetCommandSchema).ToArray(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Sets console foreground color, executes specified action, and sets the color back to the original value. | ||||
|         /// </summary> | ||||
|         public static void WithForegroundColor(this IConsole console, ConsoleColor foregroundColor, Action action) | ||||
|         { | ||||
|             var lastColor = console.ForegroundColor; | ||||
| @@ -21,6 +29,9 @@ namespace CliFx.Services | ||||
|             console.ForegroundColor = lastColor; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Sets console background color, executes specified action, and sets the color back to the original value. | ||||
|         /// </summary> | ||||
|         public static void WithBackgroundColor(this IConsole console, ConsoleColor backgroundColor, Action action) | ||||
|         { | ||||
|             var lastColor = console.BackgroundColor; | ||||
| @@ -31,6 +42,9 @@ namespace CliFx.Services | ||||
|             console.BackgroundColor = lastColor; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Sets console foreground and background colors, executes specified action, and sets the colors back to the original values. | ||||
|         /// </summary> | ||||
|         public static void WithColors(this IConsole console, ConsoleColor foregroundColor, ConsoleColor backgroundColor, Action action) => | ||||
|             console.WithForegroundColor(foregroundColor, () => console.WithBackgroundColor(backgroundColor, action)); | ||||
|     } | ||||
|   | ||||
| @@ -2,8 +2,14 @@ | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Initializes new instances of <see cref="ICommand"/>. | ||||
|     /// </summary> | ||||
|     public interface ICommandFactory | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="ICommand"/> of specified type. | ||||
|         /// </summary> | ||||
|         ICommand CreateCommand(Type commandType); | ||||
|     } | ||||
| } | ||||
| @@ -2,8 +2,14 @@ | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Renders help text to the console. | ||||
|     /// </summary> | ||||
|     public interface ICommandHelpTextRenderer | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Renders help text using specified console and source information. | ||||
|         /// </summary> | ||||
|         void RenderHelpText(IConsole console, HelpTextSource source); | ||||
|     } | ||||
| } | ||||
| @@ -2,8 +2,14 @@ | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Populates <see cref="ICommand"/> instances with input according to its schema. | ||||
|     /// </summary> | ||||
|     public interface ICommandInitializer | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Populates an instance of <see cref="ICommand"/> with specified input according to specified schema. | ||||
|         /// </summary> | ||||
|         void InitializeCommand(ICommand command, CommandSchema schema, CommandInput input); | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,14 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Parses command line arguments. | ||||
|     /// </summary> | ||||
|     public interface ICommandInputParser | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Parses specified command line arguments. | ||||
|         /// </summary> | ||||
|         CommandInput ParseInput(IReadOnlyList<string> commandLineArguments); | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,14 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Converts input command options. | ||||
|     /// </summary> | ||||
|     public interface ICommandOptionInputConverter | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Converts an option to specified target type. | ||||
|         /// </summary> | ||||
|         object ConvertOption(CommandOptionInput option, Type targetType); | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,14 @@ using CliFx.Models; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Resolves command schemas. | ||||
|     /// </summary> | ||||
|     public interface ICommandSchemaResolver | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Resolves schema of a command of specified type. | ||||
|         /// </summary> | ||||
|         CommandSchema GetCommandSchema(Type commandType); | ||||
|     } | ||||
| } | ||||
| @@ -3,24 +3,54 @@ using System.IO; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Abstraction for interacting with the console. | ||||
|     /// </summary> | ||||
|     public interface IConsole | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Input stream (stdin). | ||||
|         /// </summary> | ||||
|         TextReader Input { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Whether the input stream is redirected. | ||||
|         /// </summary> | ||||
|         bool IsInputRedirected { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Output stream (stdout). | ||||
|         /// </summary> | ||||
|         TextWriter Output { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Whether the output stream is redirected. | ||||
|         /// </summary> | ||||
|         bool IsOutputRedirected { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Error stream (stderr). | ||||
|         /// </summary> | ||||
|         TextWriter Error { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Whether the error stream is redirected. | ||||
|         /// </summary> | ||||
|         bool IsErrorRedirected { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Current foreground color. | ||||
|         /// </summary> | ||||
|         ConsoleColor ForegroundColor { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Current background color. | ||||
|         /// </summary> | ||||
|         ConsoleColor BackgroundColor { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets foreground and background color to default values. | ||||
|         /// </summary> | ||||
|         void ResetColor(); | ||||
|     } | ||||
| } | ||||
| @@ -3,32 +3,44 @@ using System.IO; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Implementation of <see cref="IConsole"/> that wraps around <see cref="Console"/>. | ||||
|     /// </summary> | ||||
|     public class SystemConsole : IConsole | ||||
|     { | ||||
|         /// <inheritdoc /> | ||||
|         public TextReader Input => Console.In; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsInputRedirected => Console.IsInputRedirected; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public TextWriter Output => Console.Out; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsOutputRedirected => Console.IsOutputRedirected; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public TextWriter Error => Console.Error; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsErrorRedirected => Console.IsErrorRedirected; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ConsoleColor ForegroundColor | ||||
|         { | ||||
|             get => Console.ForegroundColor; | ||||
|             set => Console.ForegroundColor = value; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ConsoleColor BackgroundColor | ||||
|         { | ||||
|             get => Console.BackgroundColor; | ||||
|             set => Console.BackgroundColor = value; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public void ResetColor() => Console.ResetColor(); | ||||
|     } | ||||
| } | ||||
| @@ -3,24 +3,40 @@ using System.IO; | ||||
|  | ||||
| namespace CliFx.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Implementation of <see cref="IConsole"/> that routes data to specified streams. | ||||
|     /// Does not leak to <see cref="Console"/> in any way. | ||||
|     /// Provides an isolated instance of <see cref="IConsole"/> which is useful for testing purposes. | ||||
|     /// </summary> | ||||
|     public class TestConsole : IConsole | ||||
|     { | ||||
|         /// <inheritdoc /> | ||||
|         public TextReader Input { get; } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsInputRedirected => true; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public TextWriter Output { get; } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsOutputRedirected => true; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public TextWriter Error { get; } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public bool IsErrorRedirected => true; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ConsoleColor ForegroundColor { get; set; } = ConsoleColor.Gray; | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="TestConsole"/>. | ||||
|         /// </summary> | ||||
|         public TestConsole(TextReader input, TextWriter output, TextWriter error) | ||||
|         { | ||||
|             Input = input; | ||||
| @@ -28,16 +44,25 @@ namespace CliFx.Services | ||||
|             Error = error; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="TestConsole"/> using output stream (stdout) and error stream (stderr). | ||||
|         /// Input stream (stdin) is considered empty. | ||||
|         /// </summary> | ||||
|         public TestConsole(TextWriter output, TextWriter error) | ||||
|             : this(TextReader.Null, output, error) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes an instance of <see cref="TestConsole"/> using output stream (stdout). | ||||
|         /// Input stream (stdin) and error stream (stderr) are considered empty. | ||||
|         /// </summary> | ||||
|         public TestConsole(TextWriter output) | ||||
|             : this(output, TextWriter.Null) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc /> | ||||
|         public void ResetColor() | ||||
|         { | ||||
|             ForegroundColor = ConsoleColor.Gray; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user