├── .config └── dotnet-tools.json ├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Feature_request.md │ ├── Question.md │ └── config.yml └── workflows │ ├── ci.yml │ ├── docs.yml │ └── stale.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CommandLineUtils.sln ├── Directory.Build.props ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── build.ps1 ├── docs ├── .nojekyll ├── README.md ├── api │ └── index.md ├── docfx.json ├── docs │ ├── advanced │ │ ├── dependency-injection.md │ │ └── generic-host.md │ ├── arguments.md │ ├── help-text.md │ ├── intro.md │ ├── options.md │ ├── response-file-parsing.md │ └── toc.md ├── filterConfig.yml ├── generate.ps1 ├── index.md ├── logo.png ├── push.ps1 ├── samples │ ├── .gitignore │ ├── Directory.Build.props │ ├── Directory.Build.targets │ ├── attributes │ │ ├── Attributes.csproj │ │ └── Program.cs │ ├── custom-attribute │ │ ├── CustomAttribute.csproj │ │ └── Program.cs │ ├── custom-conventions │ │ ├── CustomConvention.csproj │ │ └── Program.cs │ ├── dependency-injection │ │ ├── custom │ │ │ ├── CustomServices.csproj │ │ │ └── Program.cs │ │ ├── generic-host │ │ │ ├── GenericHostDI.csproj │ │ │ └── Program.cs │ │ └── standard │ │ │ ├── Program.cs │ │ │ └── StandardServices.csproj │ ├── generic-host │ │ ├── AttributeApi │ │ │ ├── AttributeApi.csproj │ │ │ └── Program.cs │ │ └── BuilderApi │ │ │ ├── BuilderApi.csproj │ │ │ └── Program.cs │ ├── helloworld-async-attributes │ │ ├── AsyncAttributes.csproj │ │ └── Program.cs │ ├── helloworld-async │ │ ├── AsyncBuilderApi.csproj │ │ └── Program.cs │ ├── helloworld-attributes │ │ ├── HelloWorldAttributes.csproj │ │ └── Program.cs │ ├── helloworld │ │ ├── HelloWorld.csproj │ │ └── Program.cs │ ├── interactive-prompts │ │ ├── Program.cs │ │ └── Prompt.csproj │ ├── pager │ │ ├── Pager.csproj │ │ └── Program.cs │ ├── passthru-args │ │ ├── attributes │ │ │ ├── AttributesPassThru.csproj │ │ │ └── Program.cs │ │ └── builder-api │ │ │ ├── BuilderApiPassThru.csproj │ │ │ └── Program.cs │ ├── response-file-parsing │ │ ├── attributes │ │ │ ├── Program.cs │ │ │ └── RspAttributes.csproj │ │ ├── builder-api │ │ │ ├── Program.cs │ │ │ └── RspBuilderApi.csproj │ │ └── input.txt │ ├── samples.sln │ ├── subcommands │ │ ├── builder-api │ │ │ ├── BuilderApiSubcommands.csproj │ │ │ └── Program.cs │ │ ├── inheritance │ │ │ ├── InheritanceSubcommands.csproj │ │ │ └── Program.cs │ │ └── nested-types │ │ │ ├── NestedTypeSubcommands.csproj │ │ │ └── Program.cs │ └── validation │ │ ├── attributes │ │ ├── Program.cs │ │ └── ValidationAttributes.csproj │ │ └── builder-api │ │ ├── Program.cs │ │ └── ValidationBuilderApi.csproj ├── theme │ └── partials │ │ ├── logo.tmpl.partial │ │ └── scripts.tmpl.partial ├── toc.yml ├── v2.2 │ ├── api │ │ ├── .manifest │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.yml │ │ ├── index.md │ │ └── toc.yml │ └── toc.yml ├── v2.3 │ ├── api │ │ ├── .manifest │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandNameFromTypeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.MissingParameterlessConstructorException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Pager.yml │ │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.yml │ │ ├── Microsoft.Extensions.Hosting.HostBuilderExtensions.yml │ │ ├── Microsoft.Extensions.Hosting.yml │ │ ├── index.md │ │ └── toc.yml │ └── toc.yml ├── v2.4 │ ├── api │ │ ├── .manifest │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandNameFromTypeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.HangingIndentWriter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.MissingParameterlessConstructorException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Pager.yml │ │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathNotExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.yml │ │ ├── Microsoft.Extensions.Hosting.HostBuilderExtensions.yml │ │ ├── Microsoft.Extensions.Hosting.yml │ │ ├── index.md │ │ └── toc.yml │ └── toc.yml ├── v2.5 │ ├── api │ │ ├── .manifest │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandNameFromTypeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.HangingIndentWriter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.MissingParameterlessConstructorException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Pager.yml │ │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathNotExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.yml │ │ ├── Microsoft.Extensions.Hosting.HostBuilderExtensions.yml │ │ ├── Microsoft.Extensions.Hosting.yml │ │ ├── index.md │ │ └── toc.yml │ └── toc.yml ├── v2.6 │ ├── api │ │ ├── .manifest │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParser.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandNameFromTypeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Errors.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryNotExistsAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.HangingIndentWriter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.MissingParameterlessConstructorException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Pager.yml │ │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedArgumentHandling.yml │ │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathNotExistsAttributeBase.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ │ ├── McMaster.Extensions.CommandLineUtils.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler.yml │ │ ├── McMaster.Extensions.Hosting.CommandLine.yml │ │ ├── Microsoft.Extensions.Hosting.HostBuilderExtensions.yml │ │ ├── Microsoft.Extensions.Hosting.yml │ │ ├── index.md │ │ └── toc.yml │ ├── docs │ │ ├── advanced │ │ │ ├── dependency-injection.md │ │ │ └── generic-host.md │ │ ├── arguments.md │ │ ├── help-text.md │ │ ├── intro.md │ │ ├── options.md │ │ ├── response-file-parsing.md │ │ └── toc.md │ ├── index.md │ ├── samples │ │ ├── .gitignore │ │ ├── Directory.Build.props │ │ ├── Directory.Build.targets │ │ ├── attributes │ │ │ ├── Attributes.csproj │ │ │ └── Program.cs │ │ ├── custom-attribute │ │ │ ├── CustomAttribute.csproj │ │ │ └── Program.cs │ │ ├── custom-conventions │ │ │ ├── CustomConvention.csproj │ │ │ └── Program.cs │ │ ├── dependency-injection │ │ │ ├── custom │ │ │ │ ├── CustomServices.csproj │ │ │ │ └── Program.cs │ │ │ ├── generic-host │ │ │ │ ├── GenericHostDI.csproj │ │ │ │ └── Program.cs │ │ │ └── standard │ │ │ │ ├── Program.cs │ │ │ │ └── StandardServices.csproj │ │ ├── generic-host │ │ │ ├── GenericHost.csproj │ │ │ └── Program.cs │ │ ├── helloworld-async-attributes │ │ │ ├── AsyncAttributes.csproj │ │ │ └── Program.cs │ │ ├── helloworld-async │ │ │ ├── AsyncBuilderApi.csproj │ │ │ └── Program.cs │ │ ├── interactive-prompts │ │ │ ├── Program.cs │ │ │ └── Prompt.csproj │ │ ├── pager │ │ │ ├── Pager.csproj │ │ │ └── Program.cs │ │ ├── passthru-args │ │ │ ├── attributes │ │ │ │ ├── AttributesPassThru.csproj │ │ │ │ └── Program.cs │ │ │ └── builder-api │ │ │ │ ├── BuilderApiPassThru.csproj │ │ │ │ └── Program.cs │ │ ├── response-file-parsing │ │ │ ├── attributes │ │ │ │ ├── Program.cs │ │ │ │ └── RspAttributes.csproj │ │ │ ├── builder-api │ │ │ │ ├── Program.cs │ │ │ │ └── RspBuilderApi.csproj │ │ │ └── input.txt │ │ ├── samples-2.x.sln │ │ ├── subcommands │ │ │ ├── builder-api │ │ │ │ ├── BuilderApiSubcommands.csproj │ │ │ │ └── Program.cs │ │ │ ├── inheritance │ │ │ │ ├── InheritanceSubcommands.csproj │ │ │ │ └── Program.cs │ │ │ └── nested-types │ │ │ │ ├── NestedTypeSubcommands.csproj │ │ │ │ └── Program.cs │ │ └── validation │ │ │ ├── attributes │ │ │ ├── Program.cs │ │ │ └── ValidationAttributes.csproj │ │ │ └── builder-api │ │ │ ├── Program.cs │ │ │ └── ValidationBuilderApi.csproj │ └── toc.yml └── v3.0 │ ├── api │ ├── .manifest │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.CommandLineContext.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IModelAccessor.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.IValueParser.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ParseResult.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParser.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.ValueParserProvider.yml │ ├── McMaster.Extensions.CommandLineUtils.Abstractions.yml │ ├── McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.ArgumentAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.ArgumentEscaper.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument-1.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandArgument.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication-1.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplication.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandOption-1.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandOption.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandOptionType.yml │ ├── McMaster.Extensions.CommandLineUtils.CommandParsingException.yml │ ├── McMaster.Extensions.CommandLineUtils.ConsoleExtensions.yml │ ├── McMaster.Extensions.CommandLineUtils.ConsoleReporter.yml │ ├── McMaster.Extensions.CommandLineUtils.ConventionBuilderExtensions.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AppNameFromEntryAssemblyConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ArgumentAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.AttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.CommandNameFromTypeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConstructorInjectionConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ConventionContext.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.DefaultHelpOptionConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.HelpOptionAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IConventionBuilder.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.IMemberConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.OptionAttributeConventionBase-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ParentPropertyConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.RemainingArgsPropertyConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.SubcommandPropertyConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.ValidationErrorMethodConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.VersionOptionFromMemberAttributeConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Conventions.yml │ ├── McMaster.Extensions.CommandLineUtils.DebugHelper.yml │ ├── McMaster.Extensions.CommandLineUtils.DirectoryExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.DirectoryNotExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.DotNetCliContext.yml │ ├── McMaster.Extensions.CommandLineUtils.DotNetExe.yml │ ├── McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException.yml │ ├── McMaster.Extensions.CommandLineUtils.Errors.yml │ ├── McMaster.Extensions.CommandLineUtils.FileExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.FileNotExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.FileOrDirectoryNotExistsAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.HelpOptionAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator.yml │ ├── McMaster.Extensions.CommandLineUtils.HelpText.HangingIndentWriter.yml │ ├── McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator.yml │ ├── McMaster.Extensions.CommandLineUtils.HelpText.yml │ ├── McMaster.Extensions.CommandLineUtils.IConsole.yml │ ├── McMaster.Extensions.CommandLineUtils.IReporter.yml │ ├── McMaster.Extensions.CommandLineUtils.LegalFilePathAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.MissingParameterlessConstructorException.yml │ ├── McMaster.Extensions.CommandLineUtils.NullConsole.yml │ ├── McMaster.Extensions.CommandLineUtils.NullReporter.yml │ ├── McMaster.Extensions.CommandLineUtils.OptionAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.OptionAttributeBase.yml │ ├── McMaster.Extensions.CommandLineUtils.Pager.yml │ ├── McMaster.Extensions.CommandLineUtils.PhysicalConsole.yml │ ├── McMaster.Extensions.CommandLineUtils.Prompt.yml │ ├── McMaster.Extensions.CommandLineUtils.ResponseFileHandling.yml │ ├── McMaster.Extensions.CommandLineUtils.SubcommandAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.SuppressDefaultHelpOptionAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedArgumentHandling.yml │ ├── McMaster.Extensions.CommandLineUtils.UnrecognizedCommandParsingException.yml │ ├── McMaster.Extensions.CommandLineUtils.ValidateMethodConvention.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.AttributeValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.DelegateValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathExistsAttributeBase.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.FilePathNotExistsAttributeBase.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidationBuilder.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IArgumentValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.ICommandValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidationBuilder.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IOptionValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidationBuilder.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.IValidator.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder-1.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.ValidationBuilder.yml │ ├── McMaster.Extensions.CommandLineUtils.Validation.yml │ ├── McMaster.Extensions.CommandLineUtils.ValidationExtensions.yml │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.VersionOptionFromMemberAttribute.yml │ ├── McMaster.Extensions.CommandLineUtils.yml │ ├── McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler.yml │ ├── McMaster.Extensions.Hosting.CommandLine.yml │ ├── Microsoft.Extensions.Hosting.HostBuilderExtensions.yml │ ├── Microsoft.Extensions.Hosting.yml │ └── toc.yml │ ├── toc.yml │ └── upgrade-guide.md ├── src ├── CommandLineUtils │ ├── Abstractions │ │ ├── CommandLineContext.cs │ │ ├── IModelAccessor.cs │ │ ├── IValueParser.cs │ │ ├── IValueParser{T}.cs │ │ ├── ParseResult.cs │ │ └── ValueParserProvider.cs │ ├── Attributes │ │ ├── AllowedValuesAttribute.cs │ │ ├── ArgumentAttribute.cs │ │ ├── CommandAttribute.cs │ │ ├── DirectoryExistsAttribute.cs │ │ ├── DirectoryNotExistsAttribute.cs │ │ ├── FileExistsAttribute.cs │ │ ├── FileNotExistsAttribute.cs │ │ ├── FileOrDirectoryExistsAttribute.cs │ │ ├── FileOrDirectoryNotExistsAttribute.cs │ │ ├── FilePathExistsAttributeBase.cs │ │ ├── FilePathNotExistsAttributeBase.cs │ │ ├── HelpOptionAttribute.cs │ │ ├── LegalFilePathAttribute.cs │ │ ├── OptionAttribute.cs │ │ ├── OptionAttributeBase.cs │ │ ├── SubcommandAttribute.cs │ │ ├── SuppressDefaultHelpOptionAttribute.cs │ │ ├── VersionOptionAttribute.cs │ │ └── VersionOptionFromMemberAttribute.cs │ ├── CommandArgument.cs │ ├── CommandArgument{T}.cs │ ├── CommandLineApplication.Execute.cs │ ├── CommandLineApplication.Validation.cs │ ├── CommandLineApplication.cs │ ├── CommandLineApplicationExtensions.cs │ ├── CommandLineApplication{T}.cs │ ├── CommandOption.cs │ ├── CommandOptionType.cs │ ├── CommandOption{T}.cs │ ├── CommandParsingException.cs │ ├── Conventions │ │ ├── AppNameFromEntryAssemblyConvention.cs │ │ ├── ArgumentAttributeConvention.cs │ │ ├── AttributeConvention.cs │ │ ├── CommandAttributeConvention.cs │ │ ├── CommandNameFromTypeConvention.cs │ │ ├── ConstructorInjectionConvention.cs │ │ ├── ConventionBuilderExtensions.cs │ │ ├── ConventionContext.cs │ │ ├── DefaultHelpOptionConvention.cs │ │ ├── ExecuteMethodConvention.cs │ │ ├── HelpOptionAttributeConvention.cs │ │ ├── IConvention.cs │ │ ├── IConventionBuilder.cs │ │ ├── IMemberConvention.cs │ │ ├── OptionAttributeConvention.cs │ │ ├── OptionAttributeConventionBase.cs │ │ ├── ParentPropertyConvention.cs │ │ ├── RemainingArgsPropertyConvention.cs │ │ ├── SubcommandAttributeConvention.cs │ │ ├── SubcommandPropertyConvention.cs │ │ ├── ValidateMethodConvention.cs │ │ ├── ValidationErrorMethodConvention.cs │ │ ├── VersionOptionAttributeConvention.cs │ │ └── VersionOptionFromMemberAttributeConvention.cs │ ├── Errors │ │ ├── MissingParameterlessConstructorException.cs │ │ ├── SubcommandCycleException.cs │ │ └── UnrecognizedCommandParsingException.cs │ ├── HelpText │ │ ├── DefaultHelpTextGenerator.cs │ │ ├── HangingIndentWriter.cs │ │ └── IHelpTextGenerator.cs │ ├── IO │ │ ├── ConsoleExtensions.cs │ │ ├── ConsoleReporter.cs │ │ ├── IConsole.cs │ │ ├── IReporter.cs │ │ ├── NullConsole.cs │ │ ├── NullReporter.cs │ │ ├── Pager.cs │ │ └── PhysicalConsole.cs │ ├── Internal │ │ ├── AnsiConsole.cs │ │ ├── CollectionParserProvider.cs │ │ ├── CommandLineProcessor.cs │ │ ├── CommandLineValidationContext.cs │ │ ├── CommandOptionTypeMapper.cs │ │ ├── DefaultCommandLineContext.cs │ │ ├── Delegates.cs │ │ ├── FilePathType.cs │ │ ├── ICollectionParser.cs │ │ ├── IInternalCommandParamOfT.cs │ │ ├── ITupleValueParser.cs │ │ ├── ParserConfig.cs │ │ ├── ReflectionHelper.cs │ │ ├── ResponseFileParser.cs │ │ ├── StringDistance.cs │ │ ├── StringExtensions.cs │ │ ├── SuggestionCreator.cs │ │ └── ValueParsers │ │ │ ├── ArrayParser.cs │ │ │ ├── EnumParser.cs │ │ │ ├── HashSetParser.cs │ │ │ ├── ListParser.cs │ │ │ ├── NullableValueParser.cs │ │ │ ├── StockValueParsers.cs │ │ │ ├── TupleValueParser.cs │ │ │ ├── TypeDescriptorValueParserFactory.cs │ │ │ ├── ValueParser.cs │ │ │ └── ValueTupleValueParser.cs │ ├── McMaster.Extensions.CommandLineUtils.csproj │ ├── Properties │ │ ├── InternalsVisibleTo.cs │ │ ├── NullabilityHelpers.cs │ │ └── Strings.cs │ ├── PublicAPI.Shipped.txt │ ├── PublicAPI.Unshipped.txt │ ├── ResponseFileHandling.cs │ ├── UnrecognizedArgumentHandling.cs │ ├── Utilities │ │ ├── ArgumentEscaper.cs │ │ ├── DebugHelper.cs │ │ ├── DotNetCliContext.cs │ │ ├── DotNetExe.cs │ │ └── Prompt.cs │ ├── Validation │ │ ├── AttributeValidator.cs │ │ ├── DelegateValidator.cs │ │ ├── IArgumentValidationBuilder.cs │ │ ├── IArgumentValidationBuilder{T}.cs │ │ ├── IArgumentValidator.cs │ │ ├── ICommandValidator.cs │ │ ├── IOptionValidationBuilder.cs │ │ ├── IOptionValidationBuilder{T}.cs │ │ ├── IOptionValidator.cs │ │ ├── IValidationBuilder.cs │ │ ├── IValidationBuilder{T}.cs │ │ ├── IValidator.cs │ │ ├── ValidationBuilder.cs │ │ ├── ValidationBuilder{T}.cs │ │ └── ValidationExtensions.cs │ └── releasenotes.props ├── Directory.Build.targets ├── Hosting.CommandLine │ ├── HostBuilderContextExtensions.cs │ ├── HostBuilderExtensions.cs │ ├── HostExtensions.cs │ ├── IUnhandledExceptionHandler.cs │ ├── Internal │ │ ├── CommandLineLifetime.cs │ │ ├── CommandLineService.cs │ │ ├── CommandLineService{T}.cs │ │ ├── CommandLineState.cs │ │ ├── ICommandLineService.cs │ │ └── StoreExceptionHandler.cs │ ├── McMaster.Extensions.Hosting.CommandLine.csproj │ ├── PublicAPI.Shipped.txt │ ├── PublicAPI.Unshipped.txt │ └── releasenotes.props ├── StrongName.snk └── common.psm1 └── test ├── CommandLineUtils.Tests ├── AllowedValuesAttributeTests.cs ├── ApiTests.cs ├── AppNameFromEntryAssemblyConventionTests.cs ├── ArgumentAttributeTests.cs ├── ArgumentEscaperTests.cs ├── AttributeConventionTests.cs ├── AttributeValidatorTests.cs ├── CommandArgumentTests.cs ├── CommandAttributeTests.cs ├── CommandLineApplicationExecutorTests.cs ├── CommandLineApplicationOfTTests.cs ├── CommandLineApplicationTests.cs ├── CommandLineProcessorTests.cs ├── CommandNameFromTypeConventionTests.cs ├── CommandOptionTests.cs ├── CommandOptionTypeMapperTests.cs ├── ConstructorInjectionConventionTests.cs ├── CustomValidationAttributeTest.cs ├── DefaultHelpOptionTests.cs ├── DefaultHelpTextGeneratorTests.cs ├── DotNetExeTests.cs ├── ExecuteMethodConventionTests.cs ├── FilePathExistsAttributeTests.cs ├── FilePathNotExistsAttributeTests.cs ├── HangingIndentWriterTests.cs ├── HelpOptionAttributeTests.cs ├── LegalFilePathAttributeTests.cs ├── McMaster.Extensions.CommandLineUtils.Tests.csproj ├── OptionAttributeTests.cs ├── ParentPropertyConventionTests.cs ├── RemainingArgsPropertyConventionTests.cs ├── ResponseFileTests.cs ├── StringDistanceTests.cs ├── StringExtensionsTests.cs ├── SubcommandAttributeTests.cs ├── SubcommandPropertyConventionTests.cs ├── Utilities │ ├── CommandLineParser.cs │ ├── ConventionTestBase.cs │ ├── TestConsole.cs │ └── XunitTextWriter.cs ├── ValidateMethodConventionTests.cs ├── ValidationTests.cs ├── ValueParserProviderCustomTests.cs ├── ValueParserProviderTests.cs ├── VersionOptionAttributeTests.cs ├── VersionOptionFromMemberAttributeTests.cs └── xunit.runner.json ├── Directory.Build.props └── Hosting.CommandLine.Tests ├── CustomValueParserTests.cs ├── HostBuilderExtensionsAttributeAPITests.cs ├── HostBuilderExtensionsBuilderAPITests.cs ├── McMaster.Extensions.Hosting.CommandLine.Tests.csproj ├── Utilities ├── TestConsole.cs └── XunitTextWriter.cs └── xunit.runner.json /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-format": { 6 | "version": "5.1.250801", 7 | "commands": [ 8 | "dotnet-format" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.doc diff=astextplain 2 | *.DOC diff=astextplain 3 | *.docx diff=astextplain 4 | *.DOCX diff=astextplain 5 | *.dot diff=astextplain 6 | *.DOT diff=astextplain 7 | *.pdf diff=astextplain 8 | *.PDF diff=astextplain 9 | *.rtf diff=astextplain 10 | *.RTF diff=astextplain 11 | 12 | *.jpg binary 13 | *.png binary 14 | *.gif binary 15 | 16 | *.cs text=auto diff=csharp 17 | *.vb text=auto 18 | *.resx text=auto 19 | *.c text=auto 20 | *.cpp text=auto 21 | *.cxx text=auto 22 | *.h text=auto 23 | *.hxx text=auto 24 | *.py text=auto 25 | *.rb text=auto 26 | *.java text=auto 27 | *.html text=auto 28 | *.htm text=auto 29 | *.css text=auto 30 | *.scss text=auto 31 | *.sass text=auto 32 | *.less text=auto 33 | *.js text=auto 34 | *.lisp text=auto 35 | *.clj text=auto 36 | *.sql text=auto 37 | *.php text=auto 38 | *.lua text=auto 39 | *.m text=auto 40 | *.asm text=auto 41 | *.erl text=auto 42 | *.fs text=auto 43 | *.fsx text=auto 44 | *.hs text=auto 45 | 46 | *.csproj text=auto 47 | *.vbproj text=auto 48 | *.fsproj text=auto 49 | *.dbproj text=auto 50 | *.sln text=auto eol=crlf 51 | 52 | *.sh eol=lf 53 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @natemcmaster 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Using this version of the library '...' 16 | 2. Run this code '....' 17 | 3. With these arguments '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. 12 | Example. I'm am trying to do [...] but [...] 13 | 14 | **Describe the solution you'd like** 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you've considered** 18 | A description of any alternative solutions or features you've considered. 19 | 20 | **Additional context** 21 | Add any other context or screenshots about the feature request here. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question 4 | title: "[Question] " 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | If you're not exactly sure what to say, here are some suggestions: https://stackoverflow.com/help/how-to-ask 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'docs/**' 9 | - 'src/*/PublicAPI.*.txt' 10 | - '.github/workflows/docs.yml' 11 | 12 | pull_request: 13 | paths: 14 | - 'docs/**' 15 | - 'src/*/PublicAPI.*.txt' 16 | - '.github/workflows/docs.yml' 17 | 18 | jobs: 19 | generate_docs: 20 | runs-on: windows-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Setup .NET 25 | uses: actions/setup-dotnet@v3 26 | with: 27 | dotnet-version: | 28 | 6.0.x 29 | 8.0.x 30 | - name: Run docs generation 31 | run: ./docs/generate.ps1 32 | 33 | - name: Publish docs to GH Pages 34 | if: github.event_name == 'push' 35 | run: ./docs/push.ps1 -a ${{ github.token }} 36 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | debug-only: 6 | description: Run in debug mode 7 | required: false 8 | default: 'false' 9 | schedule: 10 | - cron: '30 1 * * *' 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@v5 17 | with: 18 | debug-only: ${{ github.event.inputs.debug-only == 'true' }} 19 | days-before-stale: 365 20 | days-before-close: 14 21 | stale-issue-label: stale 22 | close-issue-label: closed-stale 23 | close-issue-reason: not_planned 24 | exempt-issue-labels: announcement,planning 25 | exempt-all-milestones: true 26 | exempt-all-assignees: true 27 | stale-issue-message: > 28 | This issue has been automatically marked as stale because it has no recent activity. 29 | It will be closed if no further activity occurs. Please comment if you believe this 30 | should remain open, otherwise it will be closed in 14 days. 31 | Thank you for your contributions to this project. 32 | close-issue-message: > 33 | Closing due to inactivity. 34 | 35 | If you are looking at this issue in the future and think it should be reopened, 36 | please make a commented here and mention natemcmaster so he sees the notification. 37 | stale-pr-message: > 38 | This pull request appears to be stale. Please comment if you believe this should remain 39 | open and reviewed. If there are no updates, it will be closed in 14 days. 40 | close-pr-message: > 41 | Thank you for your contributions to this project. This pull request has been closed due to inactivity. 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Oo]bj/ 2 | [Bb]in/ 3 | TestResults/ 4 | .nuget/ 5 | .testPublish/ 6 | *.sln.ide/ 7 | _ReSharper.*/ 8 | packages/ 9 | artifacts/ 10 | PublishProfiles/ 11 | .vs/ 12 | bower_components/ 13 | node_modules/ 14 | **/wwwroot/lib/ 15 | debugSettings.json 16 | project.lock.json 17 | *.user 18 | *.suo 19 | *.cache 20 | *.docstates 21 | _ReSharper.* 22 | *.exe 23 | *.psess 24 | *.vsp 25 | *.pidb 26 | *.userprefs 27 | *DS_Store 28 | *.ncrunchsolution 29 | *.*sdf 30 | *.ipch 31 | .settings 32 | *.sln.ide 33 | node_modules/ 34 | **/[Cc]ompiler/[Rr]esources/**/*.js 35 | .vscode/ 36 | .idea/ 37 | *.iml 38 | .build/ 39 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing Guide 2 | ================== 3 | 4 | Contributions are welcome! If you would like to help out, here are some suggestions for how to get involved. 5 | 6 | ## Get involved 7 | [Watch][watchers] this repository to get notifications about all conversations. GitHub issues and pull requests are the authoritative 8 | source of truth for design reviews, release schedules, and bug fixes. 9 | 10 | ## You don't have to contribute code 11 | 12 | There are more ways to help that don't involve writing code. 13 | * Respond to new issues. Users often open an issue to ask a question. You are welcome to offer your answer on the thread. 14 | * :+1: Up vote features that you think are important. 15 | * Look through issues labeled [closed-stale][closed-stale] to see if there are feature requests worth reviving. 16 | * Review pull requests. 17 | 18 | ## Contributing to the documentation 19 | 20 | If you are contributing to the documentation, you can build and preview the docs by executing `./docs/generate.ps1`. The `/docs` folder contains the source which **DocFX** uses generates the documentation. 21 | The results of this are saved to the `gh-pages` branch of the repository. 22 | 23 | Run `./docs/generate.ps1 -Serve` to build the docs and serve them on . 24 | 25 | ## Contributing code 26 | 27 | * Open issues labeled ["help wanted"][help-wanted] are issues that I think are worth doing, but no one has volunteered to do the work yet. 28 | Make a comment on issues you want assigned to yourself. 29 | * Pull requests are more likely to be accepted if I have first agreed to accept a feature or bug fix. Open an issue first if you aren't sure. 30 | 31 | ## Questions? 32 | 33 | Open a GitHub issue if you'd like to help and don't know where to begin. 34 | 35 | [watchers]: https://github.com/natemcmaster/CommandLineUtils/watchers 36 | [closed-stale]: https://github.com/natemcmaster/CommandLineUtils/labels/closed-stale 37 | [help-wanted]: https://github.com/natemcmaster/CommandLineUtils/labels/help%20wanted 38 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | This project is a fork of https://github.com/aspnet/Common and https://github.com/aspnet/DotNetTools. 2 | The modified work is available under the license found in LICENSE.txt in the root of this project. 3 | Any files that have been modified include a notice stating that they have been modified. 4 | 5 | The unmodified work was originally licensed under the following terms: 6 | ---------------------------------------------------------------------------------------------------- 7 | 8 | Copyright (c) .NET Foundation and Contributors 9 | 10 | All rights reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 13 | this file except in compliance with the License. You may obtain a copy of the 14 | License at 15 | 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | Unless required by applicable law or agreed to in writing, software distributed 19 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 20 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 21 | specific language governing permissions and limitations under the License. 22 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | [CmdletBinding(PositionalBinding = $false)] 3 | param( 4 | [ValidateSet('Debug', 'Release')] 5 | $Configuration = $null, 6 | [switch] 7 | $ci 8 | ) 9 | 10 | Set-StrictMode -Version 1 11 | $ErrorActionPreference = 'Stop' 12 | 13 | Import-Module -Force -Scope Local "$PSScriptRoot/src/common.psm1" 14 | 15 | if (!$Configuration) { 16 | $Configuration = if ($ci) { 'Release' } else { 'Debug' } 17 | } 18 | 19 | if (-not (Test-Path variable:\IsCoreCLR)) { 20 | $IsWindows = $true 21 | } 22 | 23 | $artifacts = "$PSScriptRoot/artifacts/" 24 | 25 | Remove-Item -Recurse $artifacts -ErrorAction Ignore 26 | 27 | exec dotnet tool restore 28 | 29 | [string[]] $formatArgs=@() 30 | if ($ci) { 31 | $formatArgs += '--check' 32 | } 33 | 34 | exec dotnet tool run dotnet-format -- -v detailed @formatArgs "$PSScriptRoot/CommandLineUtils.sln" 35 | exec dotnet tool run dotnet-format -- -v detailed @formatArgs "$PSScriptRoot/docs/samples/samples.sln" 36 | exec dotnet build --configuration $Configuration '-warnaserror:CS1591' 37 | exec dotnet pack --no-build --configuration $Configuration -o $artifacts 38 | exec dotnet build --configuration $Configuration "$PSScriptRoot/docs/samples/samples.sln" 39 | 40 | [string[]] $testArgs=@() 41 | if (-not $IsWindows) { 42 | $testArgs += '-p:TestFullFramework=false' 43 | } 44 | 45 | exec dotnet test --no-build --configuration $Configuration ` 46 | --collect:"XPlat Code Coverage" ` 47 | @testArgs 48 | 49 | write-host -f green 'BUILD SUCCEEDED' 50 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natemcmaster/CommandLineUtils/210871add72e8ad22661194c6f630fc1ecee140f/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Looking to read docs? Visit https://natemcmaster.github.io/CommandLineUtils/ 2 | 3 | Looking to help write docs? Checkout [CONTRIBUTING.md](../CONTRIBUTING.md) 4 | -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: latest_api_ref 3 | --- 4 | API Reference 5 | ============= 6 | 7 | **Version 3.0** 8 | 9 | McMaster.Extensions.CommandLineUtils supports two target frameworks. 10 | 11 | - .NET Standard 2.0 12 | - .NET Framework 4.5 13 | 14 | The API is almost identical between all of the frameworks. 15 | 16 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 17 | 18 | For apps built using attributes, these are the most common attributes used: 19 | 20 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 21 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 22 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 23 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 24 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 25 | 26 | Other commonly used types include 27 | 28 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 29 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 30 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 31 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 32 | -------------------------------------------------------------------------------- /docs/docs/toc.md: -------------------------------------------------------------------------------- 1 | # [Introduction](xref:doc-intro) 2 | # [Options](xref:options) 3 | # [Arguments](xref:arguments) 4 | # [Help Text](xref:help-text) 5 | # [@-files (Response File Parsing)](xref:response-file-parsing) 6 | # Advanced concepts 7 | ## [Dependency Injection](xref:dependency-injection) 8 | ## [Integration with Generic Host](xref:generic-host) 9 | -------------------------------------------------------------------------------- /docs/filterConfig.yml: -------------------------------------------------------------------------------- 1 | apiRules: 2 | - exclude: 3 | uidRegex: ^System\.Object 4 | type: Type 5 | - exclude: 6 | uidRegex: ^System\.Attribute 7 | type: Type 8 | - exclude: 9 | uidRegex: ^System\.ComponentModel\.DataAnnotations\.ValidationAttribute 10 | type: Type 11 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natemcmaster/CommandLineUtils/210871add72e8ad22661194c6f630fc1ecee140f/docs/logo.png -------------------------------------------------------------------------------- /docs/push.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 5 2 | param( 3 | [string]$SourceCommit, 4 | [string]$ApiToken, 5 | [switch]$DryRun 6 | ) 7 | 8 | $ErrorActionPreference = 'Stop' 9 | Set-StrictMode -Version 2 10 | 11 | Import-Module -Force -Scope Local "$PSScriptRoot/../src/common.psm1" 12 | 13 | $workdir = "$PSScriptRoot/../.build/docs/gh-pages" 14 | Push-Location $workdir 15 | try { 16 | 17 | if ($env:CI) { 18 | exec git config --global credential.helper store 19 | Add-Content "$HOME\.git-credentials" "https://x-access-token:${ApiToken}@github.com`n" 20 | exec git config --global user.email 'actions@users.noreply.github.com' 21 | exec git config --global user.name "GitHub Workflow (${env:GITHUB_ACTOR})" 22 | $SourceCommit = $env:GITHUB_SHA 23 | } 24 | 25 | if (-not $SourceCommit) { 26 | Push-Location $PSScriptRoot 27 | $SourceCommit = $(git rev-parse HEAD) 28 | Pop-Location 29 | } 30 | exec git commit --allow-empty -m "Generate documentation from $SourceCommit" 31 | exec git push --quiet origin gh-pages 32 | } 33 | finally { 34 | Pop-Location 35 | } 36 | -------------------------------------------------------------------------------- /docs/samples/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/samples/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/samples/attributes/Attributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/custom-attribute/CustomAttribute.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/custom-conventions/CustomConvention.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/dependency-injection/custom/CustomServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/samples/dependency-injection/custom/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace CustomServices 6 | { 7 | #region Program 8 | [Command(Name = "di", Description = "Dependency Injection sample project")] 9 | [HelpOption] 10 | class Program 11 | { 12 | public static int Main(string[] args) 13 | { 14 | var services = new ServiceCollection() 15 | .AddSingleton() 16 | .AddSingleton(PhysicalConsole.Singleton) 17 | .BuildServiceProvider(); 18 | 19 | var app = new CommandLineApplication(); 20 | app.Conventions 21 | .UseDefaultConventions() 22 | .UseConstructorInjection(services); 23 | return app.Execute(args); 24 | } 25 | 26 | private readonly IMyService _myService; 27 | 28 | public Program(IMyService myService) 29 | { 30 | _myService = myService; 31 | } 32 | 33 | private void OnExecute() 34 | { 35 | _myService.Invoke(); 36 | } 37 | } 38 | #endregion 39 | 40 | #region IMyService 41 | interface IMyService 42 | { 43 | void Invoke(); 44 | } 45 | #endregion 46 | 47 | #region MyServiceImplementation 48 | class MyServiceImplementation : IMyService 49 | { 50 | private readonly IConsole _console; 51 | 52 | public MyServiceImplementation(IConsole console) 53 | { 54 | _console = console; 55 | } 56 | 57 | public void Invoke() 58 | { 59 | _console.WriteLine("Hello dependency injection!"); 60 | } 61 | } 62 | #endregion 63 | } 64 | -------------------------------------------------------------------------------- /docs/samples/dependency-injection/generic-host/GenericHostDI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/samples/dependency-injection/standard/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | 5 | namespace StandardServices 6 | { 7 | [Command(Name = "di", Description = "Dependency Injection sample project")] 8 | [HelpOption] 9 | class Program 10 | { 11 | private readonly IConsole _console; 12 | 13 | static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); 14 | 15 | public Program(IConsole console) 16 | { 17 | _console = console; 18 | } 19 | 20 | private int OnExecute() 21 | { 22 | _console.WriteLine("Hello from your first application"); 23 | 24 | return 0; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/samples/dependency-injection/standard/StandardServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/generic-host/AttributeApi/AttributeApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/samples/generic-host/AttributeApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | class Program 7 | { 8 | static Task Main(string[] args) 9 | => new HostBuilder() 10 | .RunCommandLineApplicationAsync(args); 11 | 12 | [Option] 13 | public int Port { get; } = 8080; 14 | 15 | private IHostEnvironment _env; 16 | 17 | public Program(IHostEnvironment env) 18 | { 19 | _env = env; 20 | } 21 | 22 | private void OnExecute() 23 | { 24 | Console.WriteLine($"Starting on port {Port}, env = {_env.EnvironmentName}"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/samples/generic-host/BuilderApi/BuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/samples/generic-host/BuilderApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | class Program 8 | { 9 | static Task Main(string[] args) 10 | => new HostBuilder() 11 | .RunCommandLineApplicationAsync(args, (app) => 12 | { 13 | var portOption = app.Option("-p|--port ", "Port", CommandOptionType.SingleValue); 14 | 15 | app.OnExecute(() => 16 | { 17 | var port = portOption.HasValue() ? portOption.ParsedValue : 8080; 18 | var env = app.GetRequiredService(); 19 | Console.WriteLine($"Starting on port {port}, env = {env.EnvironmentName}"); 20 | }); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /docs/samples/helloworld-async-attributes/AsyncAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/helloworld-async-attributes/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using McMaster.Extensions.CommandLineUtils; 7 | 8 | /// 9 | /// You can use async with attributes by calling 10 | /// and using a method named "OnExecuteAsync" on your app type. 11 | /// 12 | public class AsyncWithAttributes 13 | { 14 | public static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); 15 | 16 | [Option(Description = "The subject")] 17 | public string Subject { get; } 18 | 19 | [Option(ShortName = "n")] 20 | public int Count { get; } 21 | 22 | private async Task OnExecuteAsync() 23 | { 24 | var subject = Subject ?? "world"; 25 | 26 | // This pause here is just for indication that some awaitable operation could happens here. 27 | await Task.Delay(5000); 28 | 29 | for (var i = 0; i < Count; i++) 30 | { 31 | Console.WriteLine($"Hello {subject}!"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docs/samples/helloworld-async/AsyncBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/helloworld-async/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | 5 | var app = new CommandLineApplication(); 6 | 7 | app.HelpOption(); 8 | var subject = app.Option("-s|--subject ", "The subject", CommandOptionType.SingleValue); 9 | subject.DefaultValue = "world"; 10 | 11 | var repeat = app.Option("-n|--count ", "Repeat", CommandOptionType.SingleValue); 12 | repeat.DefaultValue = 1; 13 | 14 | app.OnExecuteAsync(async cancellationToken => 15 | { 16 | for (var i = 0; i < repeat.ParsedValue; i++) 17 | { 18 | Console.Write($"Hello"); 19 | 20 | // Pause for dramatic effect 21 | await Task.Delay(2000, cancellationToken); 22 | 23 | Console.WriteLine($" {subject.Value()}!"); 24 | } 25 | }); 26 | 27 | return app.Execute(args); 28 | -------------------------------------------------------------------------------- /docs/samples/helloworld-attributes/HelloWorldAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/samples/helloworld-attributes/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | public class Program 5 | { 6 | public static int Main(string[] args) 7 | => CommandLineApplication.Execute(args); 8 | 9 | [Option(Description = "The subject")] 10 | public string Subject { get; } = "world"; 11 | 12 | [Option(ShortName = "n")] 13 | public int Count { get; } = 1; 14 | 15 | private void OnExecute() 16 | { 17 | for (var i = 0; i < Count; i++) 18 | { 19 | Console.WriteLine($"Hello {Subject}!"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /docs/samples/helloworld/HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/samples/helloworld/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | var app = new CommandLineApplication(); 5 | 6 | app.HelpOption(); 7 | var subject = app.Option("-s|--subject ", "The subject", CommandOptionType.SingleValue); 8 | subject.DefaultValue = "world"; 9 | var repeat = app.Option("-n|--count ", "Repeat", CommandOptionType.SingleValue); 10 | repeat.DefaultValue = 1; 11 | 12 | app.OnExecute(() => 13 | { 14 | for (var i = 0; i < repeat.ParsedValue; i++) 15 | { 16 | Console.WriteLine($"Hello {subject.Value()}!"); 17 | } 18 | }); 19 | 20 | return app.Execute(args); 21 | -------------------------------------------------------------------------------- /docs/samples/interactive-prompts/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils; 6 | 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | var proceed = Prompt.GetYesNo("Do you want to proceed with this demo?", 12 | defaultAnswer: true, 13 | promptColor: ConsoleColor.Black, 14 | promptBgColor: ConsoleColor.White); 15 | 16 | if (!proceed) return; 17 | 18 | var name = Prompt.GetString("What is your name?", 19 | promptColor: ConsoleColor.White, 20 | promptBgColor: ConsoleColor.DarkGreen); 21 | 22 | Console.WriteLine($"Hello, there { name ?? "anonymous console user"}."); 23 | 24 | var age = Prompt.GetInt("How old are you?", 25 | promptColor: ConsoleColor.White, 26 | promptBgColor: ConsoleColor.DarkRed); 27 | 28 | var password = Prompt.GetPassword("What is your password?", 29 | promptColor: ConsoleColor.White, 30 | promptBgColor: ConsoleColor.DarkBlue); 31 | 32 | Console.Write($"Your password contains {password.Length} characters. "); 33 | switch (password.Length) 34 | { 35 | case int _ when (password.Length < 2): 36 | Console.WriteLine("Your password is so short you might as well not have one."); 37 | break; 38 | case int _ when (password.Length < 4): 39 | Console.WriteLine("Your password is too short. You should pick a better one"); 40 | break; 41 | case int _ when (password.Length < 10): 42 | Console.WriteLine("Your password is too okay, I guess."); 43 | break; 44 | default: 45 | Console.WriteLine("Your password is probably adequate."); 46 | break; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/samples/interactive-prompts/Prompt.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/pager/Pager.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/pager/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | class Program 5 | { 6 | static void Main(string[] args) 7 | { 8 | // Instead of writing to stdout directly with Console.WriteLine, 9 | // this will create a console pager and display output in a 10 | // searchable, scrollable view. 11 | 12 | using (var pager = new Pager()) 13 | { 14 | for (var i = 1; i <= 1000; i++) 15 | { 16 | pager.Writer.WriteLine($"This is sentence {i} of 1,000"); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/samples/passthru-args/attributes/AttributesPassThru.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/passthru-args/attributes/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using McMaster.Extensions.CommandLineUtils; 5 | 6 | [Command( 7 | UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect, 8 | AllowArgumentSeparator = true)] 9 | public class Program 10 | { 11 | public static int Main(string[] args) => CommandLineApplication.Execute(args); 12 | 13 | [Option("-m", Description = "Show time in milliseconds")] 14 | public bool Milliseconds { get; } 15 | 16 | public string[] RemainingArguments { get; } // = { "ls", "-a", "-l" } 17 | 18 | private void OnExecute() 19 | { 20 | var timer = Stopwatch.StartNew(); 21 | if (RemainingArguments != null && RemainingArguments.Length > 0) 22 | { 23 | var process = new Process 24 | { 25 | StartInfo = 26 | { 27 | FileName = RemainingArguments[0], 28 | Arguments = ArgumentEscaper.EscapeAndConcatenate(RemainingArguments.Skip(1)), 29 | } 30 | }; 31 | process.Start(); 32 | process.WaitForExit(); 33 | } 34 | 35 | timer.Stop(); 36 | 37 | if (Milliseconds) 38 | { 39 | Console.WriteLine($"Time = {timer.Elapsed.TotalMilliseconds} ms"); 40 | } 41 | else 42 | { 43 | Console.WriteLine($"Time = {timer.Elapsed.TotalSeconds}s"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/samples/passthru-args/builder-api/BuilderApiPassThru.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/passthru-args/builder-api/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using McMaster.Extensions.CommandLineUtils; 5 | 6 | public class Program 7 | { 8 | public static int Main(string[] args) 9 | { 10 | var app = new CommandLineApplication 11 | { 12 | AllowArgumentSeparator = true, 13 | UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect, 14 | }; 15 | 16 | var showMilliseconds = app.Option("-m", "Show time in milliseconds", CommandOptionType.NoValue); 17 | 18 | app.OnExecute(() => 19 | { 20 | var timer = Stopwatch.StartNew(); 21 | if (app.RemainingArguments != null && app.RemainingArguments.Count > 0) 22 | { 23 | var process = new Process 24 | { 25 | StartInfo = 26 | { 27 | FileName = app.RemainingArguments[0], 28 | Arguments = ArgumentEscaper.EscapeAndConcatenate(app.RemainingArguments.Skip(1)), 29 | } 30 | }; 31 | process.Start(); 32 | process.WaitForExit(); 33 | } 34 | 35 | timer.Stop(); 36 | 37 | if (showMilliseconds.HasValue()) 38 | { 39 | Console.WriteLine($"Time = {timer.Elapsed.TotalMilliseconds} ms"); 40 | } 41 | else 42 | { 43 | Console.WriteLine($"Time = {timer.Elapsed.TotalSeconds}s"); 44 | } 45 | }); 46 | 47 | return app.Execute(args); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/samples/response-file-parsing/attributes/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | namespace ResponseFileParsing 5 | { 6 | [Command(Name = "done", Description = "Keep track on things you've done", ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated)] 7 | [Subcommand(typeof(ListCommand))] 8 | class Program 9 | { 10 | public static int Main(string[] args) => CommandLineApplication.Execute(args); 11 | 12 | [Argument(0, "The description of what you've done")] 13 | public string Description { get; } 14 | 15 | [Option(CommandOptionType.MultipleValue, LongName = "tag", Description = "A tag for the item")] 16 | public string[] Tags { get; } 17 | 18 | private void OnExecute() 19 | { 20 | //... 21 | } 22 | } 23 | 24 | [Command(Description = "List all done items", ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated)] 25 | class ListCommand 26 | { 27 | [Option(CommandOptionType.MultipleValue, LongName = "tag", Description = "Only list items with the corresponding tag(s)")] 28 | public string[] Tags { get; } 29 | 30 | private void OnExecute() 31 | { 32 | //... 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/samples/response-file-parsing/attributes/RspAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/response-file-parsing/builder-api/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | namespace ResponseFileParsing 5 | { 6 | class Program 7 | { 8 | public static int Main(string[] args) 9 | { 10 | var app = new CommandLineApplication 11 | { 12 | Name = "done", 13 | Description = "Keep track on things you've done", 14 | ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated 15 | }; 16 | 17 | app.HelpOption(inherited: true); 18 | var argumentDescription = app.Argument("Description", "The description of what you've done"); 19 | var optionTags = app.Option("-t|--tag ", "A tag for the item", CommandOptionType.MultipleValue); 20 | 21 | app.Command("list", listCommand => 22 | { 23 | listCommand.ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated; 24 | 25 | var optionListTags = listCommand.Option("-t|--tag ", "Only list items with the corresponding tag(s)", CommandOptionType.MultipleValue); 26 | 27 | listCommand.OnExecute(() => 28 | { 29 | //... 30 | }); 31 | }); 32 | 33 | app.OnExecute(() => 34 | { 35 | //... 36 | }); 37 | 38 | return app.Execute(args); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/samples/response-file-parsing/builder-api/RspBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/response-file-parsing/input.txt: -------------------------------------------------------------------------------- 1 | "Completed the Boston marathon" --tag major --tag fitness -------------------------------------------------------------------------------- /docs/samples/subcommands/builder-api/BuilderApiSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/subcommands/inheritance/InheritanceSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/subcommands/nested-types/NestedTypeSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/validation/attributes/ValidationAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/validation/builder-api/ValidationBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/theme/partials/logo.tmpl.partial: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/theme/partials/scripts.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /docs/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home 2 | href: index.md 3 | - name: Documentation 4 | href: docs/ 5 | - name: API Reference 6 | href: api/index.md 7 | dropdown: true 8 | items: 9 | - name: Latest (v3.0) 10 | href: api/index.md 11 | - name: v2.6 12 | topicHref: /CommandLineUtils/v2.6/api/index.html 13 | - name: v2.5 14 | topicHref: /CommandLineUtils/v2.5/api/index.html 15 | - name: v2.4 16 | topicHref: /CommandLineUtils/v2.4/api/index.html 17 | - name: v2.3 18 | topicHref: /CommandLineUtils/v2.3/api/index.html 19 | - name: v2.2 20 | topicHref: /CommandLineUtils/v2.2/api/index.html 21 | - name: Unstable 22 | topicHref: /CommandLineUtils/unstable/api/McMaster.Extensions.CommandLineUtils.html 23 | - name: GitHub 24 | href: https://github.com/natemcmaster/CommandLineUtils 25 | -------------------------------------------------------------------------------- /docs/v2.2/api/McMaster.Extensions.CommandLineUtils.HelpText.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.HelpText 4 | commentId: N:McMaster.Extensions.CommandLineUtils.HelpText 5 | id: McMaster.Extensions.CommandLineUtils.HelpText 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 8 | - McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 9 | langs: 10 | - csharp 11 | - vb 12 | name: McMaster.Extensions.CommandLineUtils.HelpText 13 | nameWithType: McMaster.Extensions.CommandLineUtils.HelpText 14 | fullName: McMaster.Extensions.CommandLineUtils.HelpText 15 | type: Namespace 16 | assemblies: 17 | - McMaster.Extensions.CommandLineUtils 18 | references: 19 | - uid: McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 20 | commentId: T:McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 21 | parent: McMaster.Extensions.CommandLineUtils.HelpText 22 | name: DefaultHelpTextGenerator 23 | nameWithType: DefaultHelpTextGenerator 24 | fullName: McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 25 | - uid: McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 26 | commentId: T:McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 27 | parent: McMaster.Extensions.CommandLineUtils.HelpText 28 | name: IHelpTextGenerator 29 | nameWithType: IHelpTextGenerator 30 | fullName: McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 31 | - uid: McMaster.Extensions.CommandLineUtils.HelpText 32 | commentId: N:McMaster.Extensions.CommandLineUtils.HelpText 33 | name: McMaster.Extensions.CommandLineUtils.HelpText 34 | nameWithType: McMaster.Extensions.CommandLineUtils.HelpText 35 | fullName: McMaster.Extensions.CommandLineUtils.HelpText 36 | -------------------------------------------------------------------------------- /docs/v2.2/api/index.md: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | **Version 2.2** 5 | 6 | McMaster.Extensions.CommandLineUtils supports three target frameworks. 7 | 8 | - .NET Standard 2.0 9 | - .NET Standard 1.6 10 | - .NET Framework 4.5 11 | 12 | The API is almost identical between all of the frameworks. 13 | 14 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 15 | 16 | For apps built using attributes, these are the most common attributes used: 17 | 18 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 19 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 20 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 21 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 22 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 23 | 24 | Other commonly used types include 25 | 26 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 27 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 28 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 29 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 30 | -------------------------------------------------------------------------------- /docs/v2.2/toc.yml: -------------------------------------------------------------------------------- 1 | - name: API Reference 2 | href: api/index.md 3 | -------------------------------------------------------------------------------- /docs/v2.3/api/McMaster.Extensions.CommandLineUtils.HelpText.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.HelpText 4 | commentId: N:McMaster.Extensions.CommandLineUtils.HelpText 5 | id: McMaster.Extensions.CommandLineUtils.HelpText 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 8 | - McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 9 | langs: 10 | - csharp 11 | - vb 12 | name: McMaster.Extensions.CommandLineUtils.HelpText 13 | nameWithType: McMaster.Extensions.CommandLineUtils.HelpText 14 | fullName: McMaster.Extensions.CommandLineUtils.HelpText 15 | type: Namespace 16 | assemblies: 17 | - McMaster.Extensions.CommandLineUtils 18 | references: 19 | - uid: McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 20 | commentId: T:McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 21 | parent: McMaster.Extensions.CommandLineUtils.HelpText 22 | name: DefaultHelpTextGenerator 23 | nameWithType: DefaultHelpTextGenerator 24 | fullName: McMaster.Extensions.CommandLineUtils.HelpText.DefaultHelpTextGenerator 25 | - uid: McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 26 | commentId: T:McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 27 | parent: McMaster.Extensions.CommandLineUtils.HelpText 28 | name: IHelpTextGenerator 29 | nameWithType: IHelpTextGenerator 30 | fullName: McMaster.Extensions.CommandLineUtils.HelpText.IHelpTextGenerator 31 | - uid: McMaster.Extensions.CommandLineUtils.HelpText 32 | commentId: N:McMaster.Extensions.CommandLineUtils.HelpText 33 | name: McMaster.Extensions.CommandLineUtils.HelpText 34 | nameWithType: McMaster.Extensions.CommandLineUtils.HelpText 35 | fullName: McMaster.Extensions.CommandLineUtils.HelpText 36 | -------------------------------------------------------------------------------- /docs/v2.3/api/McMaster.Extensions.Hosting.CommandLine.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.Hosting.CommandLine 4 | commentId: N:McMaster.Extensions.Hosting.CommandLine 5 | id: McMaster.Extensions.Hosting.CommandLine 6 | children: 7 | - McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.Hosting.CommandLine 12 | nameWithType: McMaster.Extensions.Hosting.CommandLine 13 | fullName: McMaster.Extensions.Hosting.CommandLine 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 19 | commentId: T:McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 20 | name: IUnhandledExceptionHandler 21 | nameWithType: IUnhandledExceptionHandler 22 | fullName: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 23 | -------------------------------------------------------------------------------- /docs/v2.3/api/Microsoft.Extensions.Hosting.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: Microsoft.Extensions.Hosting 4 | commentId: N:Microsoft.Extensions.Hosting 5 | id: Microsoft.Extensions.Hosting 6 | children: 7 | - Microsoft.Extensions.Hosting.HostBuilderExtensions 8 | langs: 9 | - csharp 10 | - vb 11 | name: Microsoft.Extensions.Hosting 12 | nameWithType: Microsoft.Extensions.Hosting 13 | fullName: Microsoft.Extensions.Hosting 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: Microsoft.Extensions.Hosting.HostBuilderExtensions 19 | commentId: T:Microsoft.Extensions.Hosting.HostBuilderExtensions 20 | name: HostBuilderExtensions 21 | nameWithType: HostBuilderExtensions 22 | fullName: Microsoft.Extensions.Hosting.HostBuilderExtensions 23 | -------------------------------------------------------------------------------- /docs/v2.3/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: latest_api_ref 3 | --- 4 | API Reference 5 | ============= 6 | 7 | **Version 2.3** 8 | 9 | McMaster.Extensions.CommandLineUtils supports three target frameworks. 10 | 11 | - .NET Standard 2.0 12 | - .NET Standard 1.6 13 | - .NET Framework 4.5 14 | 15 | The API is almost identical between all of the frameworks. 16 | 17 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 18 | 19 | For apps built using attributes, these are the most common attributes used: 20 | 21 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 22 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 23 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 24 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 25 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 26 | 27 | Other commonly used types include 28 | 29 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 30 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 31 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 32 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 33 | -------------------------------------------------------------------------------- /docs/v2.3/toc.yml: -------------------------------------------------------------------------------- 1 | - name: API Reference 2 | href: api/index.md 3 | -------------------------------------------------------------------------------- /docs/v2.4/api/McMaster.Extensions.CommandLineUtils.Errors.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.Errors 4 | commentId: N:McMaster.Extensions.CommandLineUtils.Errors 5 | id: McMaster.Extensions.CommandLineUtils.Errors 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.CommandLineUtils.Errors 12 | nameWithType: McMaster.Extensions.CommandLineUtils.Errors 13 | fullName: McMaster.Extensions.CommandLineUtils.Errors 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.CommandLineUtils 17 | references: 18 | - uid: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 19 | commentId: T:McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 20 | name: SubcommandCycleException 21 | nameWithType: SubcommandCycleException 22 | fullName: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 23 | -------------------------------------------------------------------------------- /docs/v2.4/api/McMaster.Extensions.Hosting.CommandLine.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.Hosting.CommandLine 4 | commentId: N:McMaster.Extensions.Hosting.CommandLine 5 | id: McMaster.Extensions.Hosting.CommandLine 6 | children: 7 | - McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.Hosting.CommandLine 12 | nameWithType: McMaster.Extensions.Hosting.CommandLine 13 | fullName: McMaster.Extensions.Hosting.CommandLine 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 19 | commentId: T:McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 20 | name: IUnhandledExceptionHandler 21 | nameWithType: IUnhandledExceptionHandler 22 | fullName: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 23 | -------------------------------------------------------------------------------- /docs/v2.4/api/Microsoft.Extensions.Hosting.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: Microsoft.Extensions.Hosting 4 | commentId: N:Microsoft.Extensions.Hosting 5 | id: Microsoft.Extensions.Hosting 6 | children: 7 | - Microsoft.Extensions.Hosting.HostBuilderExtensions 8 | langs: 9 | - csharp 10 | - vb 11 | name: Microsoft.Extensions.Hosting 12 | nameWithType: Microsoft.Extensions.Hosting 13 | fullName: Microsoft.Extensions.Hosting 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: Microsoft.Extensions.Hosting.HostBuilderExtensions 19 | commentId: T:Microsoft.Extensions.Hosting.HostBuilderExtensions 20 | name: HostBuilderExtensions 21 | nameWithType: HostBuilderExtensions 22 | fullName: Microsoft.Extensions.Hosting.HostBuilderExtensions 23 | -------------------------------------------------------------------------------- /docs/v2.4/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: latest_api_ref 3 | --- 4 | API Reference 5 | ============= 6 | 7 | **Version 2.4** 8 | 9 | McMaster.Extensions.CommandLineUtils supports three target frameworks. 10 | 11 | - .NET Standard 2.0 12 | - .NET Standard 1.6 13 | - .NET Framework 4.5 14 | 15 | The API is almost identical between all of the frameworks. 16 | 17 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 18 | 19 | For apps built using attributes, these are the most common attributes used: 20 | 21 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 22 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 23 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 24 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 25 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 26 | 27 | Other commonly used types include 28 | 29 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 30 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 31 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 32 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 33 | -------------------------------------------------------------------------------- /docs/v2.4/toc.yml: -------------------------------------------------------------------------------- 1 | - name: API Reference 2 | href: api/index.md 3 | -------------------------------------------------------------------------------- /docs/v2.5/api/McMaster.Extensions.CommandLineUtils.Errors.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.Errors 4 | commentId: N:McMaster.Extensions.CommandLineUtils.Errors 5 | id: McMaster.Extensions.CommandLineUtils.Errors 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.CommandLineUtils.Errors 12 | nameWithType: McMaster.Extensions.CommandLineUtils.Errors 13 | fullName: McMaster.Extensions.CommandLineUtils.Errors 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.CommandLineUtils 17 | references: 18 | - uid: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 19 | commentId: T:McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 20 | name: SubcommandCycleException 21 | nameWithType: SubcommandCycleException 22 | fullName: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 23 | -------------------------------------------------------------------------------- /docs/v2.5/api/McMaster.Extensions.Hosting.CommandLine.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.Hosting.CommandLine 4 | commentId: N:McMaster.Extensions.Hosting.CommandLine 5 | id: McMaster.Extensions.Hosting.CommandLine 6 | children: 7 | - McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.Hosting.CommandLine 12 | nameWithType: McMaster.Extensions.Hosting.CommandLine 13 | fullName: McMaster.Extensions.Hosting.CommandLine 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 19 | commentId: T:McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 20 | name: IUnhandledExceptionHandler 21 | nameWithType: IUnhandledExceptionHandler 22 | fullName: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 23 | -------------------------------------------------------------------------------- /docs/v2.5/api/Microsoft.Extensions.Hosting.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: Microsoft.Extensions.Hosting 4 | commentId: N:Microsoft.Extensions.Hosting 5 | id: Microsoft.Extensions.Hosting 6 | children: 7 | - Microsoft.Extensions.Hosting.HostBuilderExtensions 8 | langs: 9 | - csharp 10 | - vb 11 | name: Microsoft.Extensions.Hosting 12 | nameWithType: Microsoft.Extensions.Hosting 13 | fullName: Microsoft.Extensions.Hosting 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: Microsoft.Extensions.Hosting.HostBuilderExtensions 19 | commentId: T:Microsoft.Extensions.Hosting.HostBuilderExtensions 20 | name: HostBuilderExtensions 21 | nameWithType: HostBuilderExtensions 22 | fullName: Microsoft.Extensions.Hosting.HostBuilderExtensions 23 | -------------------------------------------------------------------------------- /docs/v2.5/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: latest_api_ref 3 | --- 4 | API Reference 5 | ============= 6 | 7 | **Version 2.5** 8 | 9 | McMaster.Extensions.CommandLineUtils supports three target frameworks. 10 | 11 | - .NET Standard 2.0 12 | - .NET Standard 1.6 13 | - .NET Framework 4.5 14 | 15 | The API is almost identical between all of the frameworks. 16 | 17 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 18 | 19 | For apps built using attributes, these are the most common attributes used: 20 | 21 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 22 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 23 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 24 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 25 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 26 | 27 | Other commonly used types include 28 | 29 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 30 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 31 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 32 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 33 | -------------------------------------------------------------------------------- /docs/v2.5/toc.yml: -------------------------------------------------------------------------------- 1 | - name: API Reference 2 | href: api/index.md 3 | -------------------------------------------------------------------------------- /docs/v2.6/api/McMaster.Extensions.CommandLineUtils.Errors.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.Errors 4 | commentId: N:McMaster.Extensions.CommandLineUtils.Errors 5 | id: McMaster.Extensions.CommandLineUtils.Errors 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.CommandLineUtils.Errors 12 | nameWithType: McMaster.Extensions.CommandLineUtils.Errors 13 | fullName: McMaster.Extensions.CommandLineUtils.Errors 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.CommandLineUtils 17 | references: 18 | - uid: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 19 | commentId: T:McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 20 | name: SubcommandCycleException 21 | nameWithType: SubcommandCycleException 22 | fullName: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 23 | -------------------------------------------------------------------------------- /docs/v2.6/api/McMaster.Extensions.Hosting.CommandLine.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.Hosting.CommandLine 4 | commentId: N:McMaster.Extensions.Hosting.CommandLine 5 | id: McMaster.Extensions.Hosting.CommandLine 6 | children: 7 | - McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.Hosting.CommandLine 12 | nameWithType: McMaster.Extensions.Hosting.CommandLine 13 | fullName: McMaster.Extensions.Hosting.CommandLine 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 19 | commentId: T:McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 20 | name: IUnhandledExceptionHandler 21 | nameWithType: IUnhandledExceptionHandler 22 | fullName: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 23 | -------------------------------------------------------------------------------- /docs/v2.6/api/Microsoft.Extensions.Hosting.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: Microsoft.Extensions.Hosting 4 | commentId: N:Microsoft.Extensions.Hosting 5 | id: Microsoft.Extensions.Hosting 6 | children: 7 | - Microsoft.Extensions.Hosting.HostBuilderExtensions 8 | langs: 9 | - csharp 10 | - vb 11 | name: Microsoft.Extensions.Hosting 12 | nameWithType: Microsoft.Extensions.Hosting 13 | fullName: Microsoft.Extensions.Hosting 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: Microsoft.Extensions.Hosting.HostBuilderExtensions 19 | commentId: T:Microsoft.Extensions.Hosting.HostBuilderExtensions 20 | name: HostBuilderExtensions 21 | nameWithType: HostBuilderExtensions 22 | fullName: Microsoft.Extensions.Hosting.HostBuilderExtensions 23 | -------------------------------------------------------------------------------- /docs/v2.6/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: latest_2_x_api_ref 3 | --- 4 | API Reference 5 | ============= 6 | 7 | **Version 2.6** 8 | 9 | McMaster.Extensions.CommandLineUtils supports three target frameworks. 10 | 11 | - .NET Standard 2.0 12 | - .NET Standard 1.6 13 | - .NET Framework 4.5 14 | 15 | The API is almost identical between all of the frameworks. 16 | 17 | The main entry point for most command line applications is [CommandLineApplication](xref:McMaster.Extensions.CommandLineUtils.CommandLineApplication). 18 | 19 | For apps built using attributes, these are the most common attributes used: 20 | 21 | - [OptionAttribute](xref:McMaster.Extensions.CommandLineUtils.OptionAttribute) 22 | - [ArgumentAttribute](xref:McMaster.Extensions.CommandLineUtils.ArgumentAttribute) 23 | - [CommandAttribute](xref:McMaster.Extensions.CommandLineUtils.CommandAttribute) 24 | - [SubcommandAttribute](xref:McMaster.Extensions.CommandLineUtils.SubcommandAttribute) 25 | - [HelpOptionAttribute](xref:McMaster.Extensions.CommandLineUtils.HelpOptionAttribute) 26 | 27 | Other commonly used types include 28 | 29 | - [DotNetExe](xref:McMaster.Extensions.CommandLineUtils.DotNetExe) 30 | - [Prompt](xref:McMaster.Extensions.CommandLineUtils.Prompt) 31 | - [ArgumentEscaper](xref:McMaster.Extensions.CommandLineUtils.ArgumentEscaper) 32 | - [IConsole](xref:McMaster.Extensions.CommandLineUtils.IConsole) 33 | -------------------------------------------------------------------------------- /docs/v2.6/docs/advanced/generic-host.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: generic-host 3 | --- 4 | # Integration with Generic Host 5 | 6 | The McMaster.Extensions.Hosting.CommandLine package provides support for integrating command line parsing with 7 | .NET's [generic host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host). 8 | 9 | ## Get started 10 | 11 | To get started, install the `McMaster.Extensions.Hosting.CommandLine` package. 12 | The main usage for generic host is `RunCommandLineApplicationAsync(args)`, where `TApp` is a class 13 | which will be bound to command line arguments and options using attributes and `CommandLineApplication.Execute`. 14 | 15 | ### Sample 16 | 17 | This minimal sample shows how to take advantage of generic host features, such as `IHostingEnvironment`, 18 | as well as command line parsing options with this library. 19 | 20 | [!code-csharp[](../../samples/generic-host/Program.cs)] 21 | 22 | ## Dependency injection 23 | 24 | Generic host integration allows you to use the most current DI configuration approach indicated by the aspnet project. The basic approach starts by creating the builder: 25 | 26 | [!code-csharp[Program](../../samples/dependency-injection/generic-host/Program.cs?range=26-26)] 27 | 28 | Then you can configure your features: 29 | 30 | [!code-csharp[Program](../../samples/dependency-injection/generic-host/Program.cs?range=27-34)] 31 | 32 | And finally, run your program: 33 | 34 | [!code-csharp[Program](../../samples/dependency-injection/generic-host/Program.cs?range=35-35)] 35 | 36 | Below is the full source code for the generic host services example. Notice that instance of `IGreeter` will be injected into the `Program` constructor thanks to the dependency injection. 37 | 38 | [!code-csharp[Program](../../samples/dependency-injection/custom/Program.cs?highlight=32)] 39 | 40 | -------------------------------------------------------------------------------- /docs/v2.6/docs/toc.md: -------------------------------------------------------------------------------- 1 | # [Introduction](xref:doc-intro) 2 | # [Options](xref:options) 3 | # [Arguments](xref:arguments) 4 | # [Help Text](xref:help-text) 5 | # [@-files (Response File Parsing)](xref:response-file-parsing) 6 | # Advanced concepts 7 | ## [Dependency Injection](xref:dependency-injection) 8 | ## [Integration with Generic Host](xref:generic-host) 9 | -------------------------------------------------------------------------------- /docs/v2.6/samples/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7.3 4 | true 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/v2.6/samples/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/v2.6/samples/attributes/Attributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/custom-attribute/CustomAttribute.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/custom-conventions/CustomConvention.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/dependency-injection/custom/CustomServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/dependency-injection/custom/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using McMaster.Extensions.CommandLineUtils; 4 | 5 | namespace CustomServices 6 | { 7 | #region Program 8 | [Command(Name = "di", Description = "Dependency Injection sample project")] 9 | [HelpOption] 10 | class Program 11 | { 12 | public static int Main(string[] args) 13 | { 14 | var services = new ServiceCollection() 15 | .AddSingleton() 16 | .AddSingleton(PhysicalConsole.Singleton) 17 | .BuildServiceProvider(); 18 | 19 | var app = new CommandLineApplication(); 20 | app.Conventions 21 | .UseDefaultConventions() 22 | .UseConstructorInjection(services); 23 | return app.Execute(args); 24 | } 25 | 26 | private readonly IMyService _myService; 27 | 28 | public Program(IMyService myService) 29 | { 30 | _myService = myService; 31 | } 32 | 33 | private void OnExecute() 34 | { 35 | _myService.Invoke(); 36 | } 37 | } 38 | #endregion 39 | 40 | #region IMyService 41 | interface IMyService 42 | { 43 | void Invoke(); 44 | } 45 | #endregion 46 | 47 | #region MyServiceImplementation 48 | class MyServiceImplementation : IMyService 49 | { 50 | private readonly IConsole _console; 51 | 52 | public MyServiceImplementation(IConsole console) 53 | { 54 | _console = console; 55 | } 56 | 57 | public void Invoke() 58 | { 59 | _console.WriteLine("Hello dependency injection!"); 60 | } 61 | } 62 | #endregion 63 | } 64 | -------------------------------------------------------------------------------- /docs/v2.6/samples/dependency-injection/generic-host/GenericHostDI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/v2.6/samples/dependency-injection/standard/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | 5 | namespace StandardServices 6 | { 7 | [Command(Name = "di", Description = "Dependency Injection sample project")] 8 | [HelpOption] 9 | class Program 10 | { 11 | private readonly IConsole _console; 12 | 13 | static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); 14 | 15 | public Program(IConsole console) 16 | { 17 | _console = console; 18 | } 19 | 20 | private int OnExecute() 21 | { 22 | _console.WriteLine("Hello from your first application"); 23 | 24 | return 0; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/v2.6/samples/dependency-injection/standard/StandardServices.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/generic-host/GenericHost.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.3 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/generic-host/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using McMaster.Extensions.CommandLineUtils; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | class Program 7 | { 8 | static Task Main(string[] args) 9 | => new HostBuilder() 10 | .RunCommandLineApplicationAsync(args); 11 | 12 | [Option] 13 | public int Port { get; } = 8080; 14 | 15 | private IHostingEnvironment _env; 16 | 17 | public Program(IHostingEnvironment env) 18 | { 19 | _env = env; 20 | } 21 | 22 | private void OnExecute() 23 | { 24 | Console.WriteLine($"Starting on port {Port}, env = {_env.EnvironmentName}"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/v2.6/samples/helloworld-async-attributes/AsyncAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/helloworld-async-attributes/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using McMaster.Extensions.CommandLineUtils; 7 | 8 | /// 9 | /// You can use async with attributes by calling 10 | /// and using a method named "OnExecuteAsync" on your app type. 11 | /// 12 | public class AsyncWithAttributes 13 | { 14 | public static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); 15 | 16 | [Option(Description = "The subject")] 17 | public string Subject { get; } 18 | 19 | [Option(ShortName = "n")] 20 | public int Count { get; } 21 | 22 | private async Task OnExecuteAsync() 23 | { 24 | var subject = Subject ?? "world"; 25 | 26 | // This pause here is just for indication that some awaitable operation could happens here. 27 | await Task.Delay(5000); 28 | 29 | for (var i = 0; i < Count; i++) 30 | { 31 | Console.WriteLine($"Hello {subject}!"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docs/v2.6/samples/helloworld-async/AsyncBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7.1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v2.6/samples/helloworld-async/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using McMaster.Extensions.CommandLineUtils; 7 | 8 | /// 9 | /// You can call 10 | /// with an async lambda to have your application execute asynchronously. 11 | /// 12 | public class AsyncWithBuilderApi 13 | { 14 | public static int Main(string[] args) 15 | { 16 | var app = new CommandLineApplication(); 17 | 18 | app.HelpOption("-h|--help"); 19 | var optionSubject = app.Option("-s|--subject ", "The subject", CommandOptionType.SingleValue); 20 | var optionRepeat = app.Option("-n|--count ", "Repeat", CommandOptionType.SingleValue); 21 | 22 | app.OnExecuteAsync(async cancellationToken => 23 | { 24 | var subject = optionSubject.HasValue() 25 | ? optionSubject.Value() 26 | : "world"; 27 | 28 | var count = optionRepeat.HasValue() ? optionRepeat.ParsedValue : 1; 29 | for (var i = 0; i < count; i++) 30 | { 31 | Console.Write($"Hello"); 32 | 33 | // This pause here is just for indication that some awaitable operation could happens here. 34 | await Task.Delay(5000, cancellationToken); 35 | Console.WriteLine($" {subject}!"); 36 | } 37 | }); 38 | 39 | return app.Execute(args); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/v2.6/samples/interactive-prompts/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils; 6 | 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | var proceed = Prompt.GetYesNo("Do you want to proceed with this demo?", 12 | defaultAnswer: true, 13 | promptColor: ConsoleColor.Black, 14 | promptBgColor: ConsoleColor.White); 15 | 16 | if (!proceed) return; 17 | 18 | var name = Prompt.GetString("What is your name?", 19 | promptColor: ConsoleColor.White, 20 | promptBgColor: ConsoleColor.DarkGreen); 21 | 22 | Console.WriteLine($"Hello, there { name ?? "anonymous console user"}."); 23 | 24 | var age = Prompt.GetInt("How old are you?", 25 | promptColor: ConsoleColor.White, 26 | promptBgColor: ConsoleColor.DarkRed); 27 | 28 | var password = Prompt.GetPassword("What is your password?", 29 | promptColor: ConsoleColor.White, 30 | promptBgColor: ConsoleColor.DarkBlue); 31 | 32 | Console.Write($"Your password contains {password.Length} characters. "); 33 | switch (password.Length) 34 | { 35 | case int _ when (password.Length < 2): 36 | Console.WriteLine("Your password is so short you might as well not have one."); 37 | break; 38 | case int _ when (password.Length < 4): 39 | Console.WriteLine("Your password is too short. You should pick a better one"); 40 | break; 41 | case int _ when (password.Length < 10): 42 | Console.WriteLine("Your password is too okay, I guess."); 43 | break; 44 | default: 45 | Console.WriteLine("Your password is probably adequate."); 46 | break; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/v2.6/samples/interactive-prompts/Prompt.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/pager/Pager.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/pager/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | class Program 5 | { 6 | static void Main(string[] args) 7 | { 8 | // Instead of writing to stdout directly with Console.WriteLine, 9 | // this will create a console pager and display output in a 10 | // searchable, scrollable view. 11 | 12 | using (var pager = new Pager()) 13 | { 14 | for (var i = 1; i <= 1000; i++) 15 | { 16 | pager.Writer.WriteLine($"This is sentence {i} of 1,000"); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/v2.6/samples/passthru-args/attributes/AttributesPassThru.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/passthru-args/attributes/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using McMaster.Extensions.CommandLineUtils; 5 | 6 | [Command( 7 | UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect, 8 | AllowArgumentSeparator = true)] 9 | public class Program 10 | { 11 | public static int Main(string[] args) => CommandLineApplication.Execute(args); 12 | 13 | [Option("-m", Description = "Show time in milliseconds")] 14 | public bool Milliseconds { get; } 15 | 16 | public string[] RemainingArguments { get; } // = { "ls", "-a", "-l" } 17 | 18 | private void OnExecute() 19 | { 20 | var timer = Stopwatch.StartNew(); 21 | if (RemainingArguments != null && RemainingArguments.Length > 0) 22 | { 23 | var process = new Process 24 | { 25 | StartInfo = 26 | { 27 | FileName = RemainingArguments[0], 28 | Arguments = ArgumentEscaper.EscapeAndConcatenate(RemainingArguments.Skip(1)), 29 | } 30 | }; 31 | process.Start(); 32 | process.WaitForExit(); 33 | } 34 | 35 | timer.Stop(); 36 | 37 | if (Milliseconds) 38 | { 39 | Console.WriteLine($"Time = {timer.Elapsed.TotalMilliseconds} ms"); 40 | } 41 | else 42 | { 43 | Console.WriteLine($"Time = {timer.Elapsed.TotalSeconds}s"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/v2.6/samples/passthru-args/builder-api/BuilderApiPassThru.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/passthru-args/builder-api/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using McMaster.Extensions.CommandLineUtils; 5 | 6 | public class Program 7 | { 8 | public static int Main(string[] args) 9 | { 10 | var app = new CommandLineApplication 11 | { 12 | AllowArgumentSeparator = true, 13 | UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect, 14 | }; 15 | 16 | var showMilliseconds = app.Option("-m", "Show time in milliseconds", CommandOptionType.NoValue); 17 | 18 | app.OnExecute(() => 19 | { 20 | var timer = Stopwatch.StartNew(); 21 | if (app.RemainingArguments != null && app.RemainingArguments.Count > 0) 22 | { 23 | var process = new Process 24 | { 25 | StartInfo = 26 | { 27 | FileName = app.RemainingArguments[0], 28 | Arguments = ArgumentEscaper.EscapeAndConcatenate(app.RemainingArguments.Skip(1)), 29 | } 30 | }; 31 | process.Start(); 32 | process.WaitForExit(); 33 | } 34 | 35 | timer.Stop(); 36 | 37 | if (showMilliseconds.HasValue()) 38 | { 39 | Console.WriteLine($"Time = {timer.Elapsed.TotalMilliseconds} ms"); 40 | } 41 | else 42 | { 43 | Console.WriteLine($"Time = {timer.Elapsed.TotalSeconds}s"); 44 | } 45 | }); 46 | 47 | return app.Execute(args); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/v2.6/samples/response-file-parsing/attributes/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | namespace ResponseFileParsing 5 | { 6 | [Command(Name = "done", Description = "Keep track on things you've done", ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated)] 7 | [Subcommand(typeof(ListCommand))] 8 | class Program 9 | { 10 | public static int Main(string[] args) => CommandLineApplication.Execute(args); 11 | 12 | [Argument(0, "The description of what you've done")] 13 | public string Description { get; } 14 | 15 | [Option(CommandOptionType.MultipleValue, LongName = "tag", Description = "A tag for the item")] 16 | public string[] Tags { get; } 17 | 18 | private void OnExecute() 19 | { 20 | //... 21 | } 22 | } 23 | 24 | [Command(Description = "List all done items", ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated)] 25 | class ListCommand 26 | { 27 | [Option(CommandOptionType.MultipleValue, LongName = "tag", Description = "Only list items with the corresponding tag(s)")] 28 | public string[] Tags { get; } 29 | 30 | private void OnExecute() 31 | { 32 | //... 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/v2.6/samples/response-file-parsing/attributes/RspAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/response-file-parsing/builder-api/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using McMaster.Extensions.CommandLineUtils; 3 | 4 | namespace ResponseFileParsing 5 | { 6 | class Program 7 | { 8 | public static int Main(string[] args) 9 | { 10 | var app = new CommandLineApplication 11 | { 12 | Name = "done", 13 | Description = "Keep track on things you've done", 14 | ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated 15 | }; 16 | 17 | app.HelpOption(inherited: true); 18 | var argumentDescription = app.Argument("Description", "The description of what you've done"); 19 | var optionTags = app.Option("-t|--tag ", "A tag for the item", CommandOptionType.MultipleValue); 20 | 21 | app.Command("list", listCommand => 22 | { 23 | listCommand.ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated; 24 | 25 | var optionListTags = listCommand.Option("-t|--tag ", "Only list items with the corresponding tag(s)", CommandOptionType.MultipleValue); 26 | 27 | listCommand.OnExecute(() => 28 | { 29 | //... 30 | }); 31 | }); 32 | 33 | app.OnExecute(() => 34 | { 35 | //... 36 | }); 37 | 38 | return app.Execute(args); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/v2.6/samples/response-file-parsing/builder-api/RspBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/response-file-parsing/input.txt: -------------------------------------------------------------------------------- 1 | "Completed the Boston marathon" --tag major --tag fitness -------------------------------------------------------------------------------- /docs/v2.6/samples/subcommands/builder-api/BuilderApiSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/subcommands/inheritance/InheritanceSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/subcommands/nested-types/NestedTypeSubcommands.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/validation/attributes/ValidationAttributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/samples/validation/builder-api/ValidationBuilderApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/v2.6/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home (v2.6) 2 | href: index.md 3 | - name: Documentation 4 | href: docs/ 5 | - name: 2.x API Reference 6 | href: api/index.md 7 | - name: GitHub 8 | href: https://github.com/natemcmaster/CommandLineUtils 9 | -------------------------------------------------------------------------------- /docs/v3.0/api/McMaster.Extensions.CommandLineUtils.Errors.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.CommandLineUtils.Errors 4 | commentId: N:McMaster.Extensions.CommandLineUtils.Errors 5 | id: McMaster.Extensions.CommandLineUtils.Errors 6 | children: 7 | - McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.CommandLineUtils.Errors 12 | nameWithType: McMaster.Extensions.CommandLineUtils.Errors 13 | fullName: McMaster.Extensions.CommandLineUtils.Errors 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.CommandLineUtils 17 | references: 18 | - uid: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 19 | commentId: T:McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 20 | name: SubcommandCycleException 21 | nameWithType: SubcommandCycleException 22 | fullName: McMaster.Extensions.CommandLineUtils.Errors.SubcommandCycleException 23 | -------------------------------------------------------------------------------- /docs/v3.0/api/McMaster.Extensions.Hosting.CommandLine.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: McMaster.Extensions.Hosting.CommandLine 4 | commentId: N:McMaster.Extensions.Hosting.CommandLine 5 | id: McMaster.Extensions.Hosting.CommandLine 6 | children: 7 | - McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 8 | langs: 9 | - csharp 10 | - vb 11 | name: McMaster.Extensions.Hosting.CommandLine 12 | nameWithType: McMaster.Extensions.Hosting.CommandLine 13 | fullName: McMaster.Extensions.Hosting.CommandLine 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 19 | commentId: T:McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 20 | name: IUnhandledExceptionHandler 21 | nameWithType: IUnhandledExceptionHandler 22 | fullName: McMaster.Extensions.Hosting.CommandLine.IUnhandledExceptionHandler 23 | -------------------------------------------------------------------------------- /docs/v3.0/api/Microsoft.Extensions.Hosting.yml: -------------------------------------------------------------------------------- 1 | ### YamlMime:ManagedReference 2 | items: 3 | - uid: Microsoft.Extensions.Hosting 4 | commentId: N:Microsoft.Extensions.Hosting 5 | id: Microsoft.Extensions.Hosting 6 | children: 7 | - Microsoft.Extensions.Hosting.HostBuilderExtensions 8 | langs: 9 | - csharp 10 | - vb 11 | name: Microsoft.Extensions.Hosting 12 | nameWithType: Microsoft.Extensions.Hosting 13 | fullName: Microsoft.Extensions.Hosting 14 | type: Namespace 15 | assemblies: 16 | - McMaster.Extensions.Hosting.CommandLine 17 | references: 18 | - uid: Microsoft.Extensions.Hosting.HostBuilderExtensions 19 | commentId: T:Microsoft.Extensions.Hosting.HostBuilderExtensions 20 | name: HostBuilderExtensions 21 | nameWithType: HostBuilderExtensions 22 | fullName: Microsoft.Extensions.Hosting.HostBuilderExtensions 23 | -------------------------------------------------------------------------------- /docs/v3.0/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Upgrade Guide 2 | href: upgrade-guide.md 3 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Abstractions/IModelAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | /// 9 | /// Provides access to a command line application model. 10 | /// 11 | public interface IModelAccessor 12 | { 13 | /// 14 | /// Gets the type of the model. 15 | /// 16 | /// The type. 17 | Type GetModelType(); 18 | 19 | /// 20 | /// Gets the model. 21 | /// 22 | /// The model. 23 | object GetModel(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Abstractions/IValueParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Globalization; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 8 | { 9 | /// 10 | /// A parser that can convert string into an object. 11 | /// 12 | public interface IValueParser 13 | { 14 | /// 15 | /// Gets the Type that this value parser is defined for. 16 | /// 17 | Type TargetType { get; } 18 | 19 | /// 20 | /// Parses the raw string value. 21 | /// 22 | /// The name of the argument this value will be bound to. 23 | /// The raw string value to parse. 24 | /// The culture that should be used to parse values. 25 | /// The parsed value object. 26 | /// When the value cannot be parsed. 27 | object? Parse(string? argName, string? value, CultureInfo culture); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Abstractions/IValueParser{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Globalization; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | /// 9 | /// A parser that can convert string into . 10 | /// 11 | public interface IValueParser : IValueParser 12 | { 13 | /// 14 | /// Parses the raw string value. 15 | /// 16 | /// The name of the argument this value will be bound to. 17 | /// The raw string value to parse. 18 | /// The culture that should be used to parse values. 19 | /// The parsed value object. 20 | /// When the value cannot be parsed. 21 | new T Parse(string? argName, string? value, CultureInfo culture); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Abstractions/ParseResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | /// 9 | /// The result of parsing command line arguments. 10 | /// 11 | public class ParseResult 12 | { 13 | /// 14 | /// Initializes . 15 | /// 16 | /// The command selected for execution. 17 | public ParseResult(CommandLineApplication selectedCommand) 18 | { 19 | SelectedCommand = selectedCommand ?? throw new ArgumentNullException(nameof(selectedCommand)); 20 | } 21 | 22 | /// 23 | /// The application or subcommand that matches the command line arguments. 24 | /// 25 | public CommandLineApplication SelectedCommand { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/DirectoryExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must be an already existing directory, not a file. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class DirectoryExistsAttribute : FilePathExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public DirectoryExistsAttribute() 20 | : base(FilePathType.Directory) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/DirectoryNotExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must not be an already existing directory, not a file. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class DirectoryNotExistsAttribute : FilePathNotExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public DirectoryNotExistsAttribute() 20 | : base(FilePathType.Directory) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/FileExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must be an already existing file, not a directory. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class FileExistsAttribute : FilePathExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public FileExistsAttribute() 20 | : base(FilePathType.File) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/FileNotExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must not be an already existing file, not a directory. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class FileNotExistsAttribute : FilePathNotExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public FileNotExistsAttribute() 20 | : base(FilePathType.File) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/FileOrDirectoryExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must be an already existing file or directory. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class FileOrDirectoryExistsAttribute : FilePathExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public FileOrDirectoryExistsAttribute() 20 | : base(FilePathType.Any) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/FileOrDirectoryNotExistsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | using McMaster.Extensions.CommandLineUtils.Validation; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that the data must not be an already existing file or directory. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class FileOrDirectoryNotExistsAttribute : FilePathNotExistsAttributeBase 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public FileOrDirectoryNotExistsAttribute() 20 | : base(FilePathType.Any) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/HelpOptionAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | /// 9 | /// The option used to determine if help text should be displayed. This should only be used once per command line app. 10 | /// 11 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)] 12 | public sealed class HelpOptionAttribute : OptionAttributeBase 13 | { 14 | /// 15 | /// Initializes a new with the template -?|-h|--help. 16 | /// 17 | public HelpOptionAttribute() 18 | : this(Strings.DefaultHelpTemplate) 19 | { 20 | } 21 | 22 | /// 23 | /// Initializes a new . 24 | /// 25 | /// The string template. This is parsed into and . 26 | public HelpOptionAttribute(string template) 27 | { 28 | Template = template; 29 | Description = Strings.DefaultHelpOptionDescription; 30 | } 31 | 32 | /// 33 | /// The option template. This is parsed into the short and long name. 34 | /// 35 | public new string Template { get; set; } 36 | 37 | internal CommandOption Configure(CommandLineApplication app) 38 | { 39 | var opt = app.HelpOption(Template); 40 | Configure(opt); 41 | return opt; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/LegalFilePathAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.IO; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Specifies that a value must be a legal file path. 12 | /// 13 | [AttributeUsage(AttributeTargets.Property)] 14 | public sealed class LegalFilePathAttribute : ValidationAttribute 15 | { 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | public LegalFilePathAttribute() 20 | : base("'{0}' is an invalid file path.") 21 | { 22 | 23 | } 24 | 25 | /// 26 | protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) 27 | { 28 | if (value is string path) 29 | { 30 | try 31 | { 32 | var info = new FileInfo(path); 33 | return ValidationResult.Success; 34 | } 35 | catch 36 | { 37 | } 38 | } 39 | 40 | return new ValidationResult(FormatErrorMessage(value?.ToString() ?? string.Empty)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/SubcommandAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | #pragma warning disable 618 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Represents a subcommand. 12 | /// 13 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 14 | public sealed class SubcommandAttribute : Attribute 15 | { 16 | /// 17 | /// Initializes a new instance of . 18 | /// 19 | /// The subcommand types. 20 | public SubcommandAttribute(params Type[] subcommands) 21 | { 22 | if (subcommands == null) 23 | { 24 | throw new ArgumentNullException(nameof(subcommands)); 25 | } 26 | 27 | if (subcommands.Length == 0) 28 | { 29 | throw new ArgumentException("Value cannot be an empty collection.", nameof(subcommands)); 30 | } 31 | 32 | Types = subcommands; 33 | } 34 | 35 | /// 36 | /// The types of the subcommands. 37 | /// 38 | public Type[] Types { get; private set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Attributes/SuppressDefaultHelpOptionAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Conventions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils 8 | { 9 | /// 10 | /// Suppress . 11 | /// 12 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)] 13 | public sealed class SuppressDefaultHelpOptionAttribute : Attribute 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/CommandLineUtils/CommandParsingException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | using System; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// The exception that is thrown when command line arguments could not be parsed. 12 | /// 13 | public class CommandParsingException : Exception 14 | { 15 | /// 16 | /// Initializes an instance of . 17 | /// 18 | /// The command. 19 | /// The message. 20 | public CommandParsingException(CommandLineApplication command, string message) 21 | : base(message) 22 | { 23 | Command = command; 24 | } 25 | 26 | /// 27 | /// Initializes an instance of . 28 | /// 29 | /// The command. 30 | /// The message. 31 | /// The inner exception 32 | public CommandParsingException(CommandLineApplication command, string message, Exception innerException) 33 | : base(message, innerException) 34 | { 35 | Command = command; 36 | } 37 | 38 | /// 39 | /// The command that is throwing the exception. 40 | /// 41 | public CommandLineApplication Command { get; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/AppNameFromEntryAssemblyConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Conventions 7 | { 8 | /// 9 | /// Sets using the name of the entry assembly 10 | /// to the current application. It is only applied if the name is null. 11 | /// 12 | public class AppNameFromEntryAssemblyConvention : IConvention 13 | { 14 | /// 15 | public virtual void Apply(ConventionContext context) 16 | { 17 | if (context.Application.Name != null || context.Application.Parent != null) 18 | { 19 | return; 20 | } 21 | 22 | var assembly = Assembly.GetEntryAssembly(); 23 | if (assembly == null && context.ModelType != null) 24 | { 25 | assembly = context.ModelType.Assembly; 26 | } 27 | 28 | if (assembly != null) 29 | { 30 | context.Application.Name = assembly.GetName().Name; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/AttributeConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Conventions 8 | { 9 | /// 10 | /// Searches the model type and its members for attributes that implement or . 11 | /// 12 | public class AttributeConvention : IConvention 13 | { 14 | /// 15 | public void Apply(ConventionContext context) 16 | { 17 | if (context.ModelType == null) 18 | { 19 | return; 20 | } 21 | 22 | foreach (var attr in context.ModelType.GetCustomAttributes().OfType()) 23 | { 24 | attr.Apply(context); 25 | } 26 | 27 | var members = ReflectionHelper.GetMembers(context.ModelType); 28 | foreach (var member in members) 29 | { 30 | foreach (var attr in member.GetCustomAttributes().OfType()) 31 | { 32 | attr.Apply(context, member); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/CommandAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Reflection; 6 | using McMaster.Extensions.CommandLineUtils.Abstractions; 7 | using McMaster.Extensions.CommandLineUtils.Validation; 8 | 9 | namespace McMaster.Extensions.CommandLineUtils.Conventions 10 | { 11 | /// 12 | /// Adds settings from and set on the model type for . 13 | /// 14 | /// 15 | public class CommandAttributeConvention : IConvention 16 | { 17 | /// 18 | /// Apply the convention. 19 | /// 20 | /// The context in which the convention is applied. 21 | /// 22 | public virtual void Apply(ConventionContext context) 23 | { 24 | if (context.ModelType == null) 25 | { 26 | return; 27 | } 28 | 29 | var attribute = context.ModelType.GetCustomAttribute(); 30 | attribute?.Configure(context.Application); 31 | 32 | foreach (var subcommand in context.Application.Commands) 33 | { 34 | if (subcommand is IModelAccessor subcommandAccessor) 35 | { 36 | Apply(new ConventionContext(subcommand, subcommandAccessor.GetModelType())); 37 | } 38 | } 39 | 40 | foreach (var attr in context.ModelType.GetCustomAttributes()) 41 | { 42 | context.Application.Validators.Add(new AttributeValidator(attr)); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/CommandNameFromTypeConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Conventions 7 | { 8 | /// 9 | /// Sets the command name based on the model type, if is not otherwise set. 10 | /// 11 | /// This attempts to infer a command name using a few rules, such as using kebab-case 12 | /// and trimming "Command" from the name of the type. 13 | /// AddCommand => "add" 14 | /// RemoveItemCommand => "remove-item" 15 | /// 16 | /// 17 | public class CommandNameFromTypeConvention : IConvention 18 | { 19 | /// 20 | public void Apply(ConventionContext context) 21 | { 22 | if (!string.IsNullOrEmpty(context.Application.Name)) 23 | { 24 | return; 25 | } 26 | 27 | if (context.ModelType == null) 28 | { 29 | return; 30 | } 31 | 32 | var commandName = GetCommandName(context.ModelType.Name); 33 | 34 | if (!string.IsNullOrEmpty(commandName)) 35 | { 36 | context.Application.Name = commandName; 37 | } 38 | } 39 | 40 | internal static string GetCommandName(string typeName) 41 | { 42 | const string cmd = "Command"; 43 | if (typeName.Length > cmd.Length && typeName.EndsWith(cmd, StringComparison.Ordinal)) 44 | { 45 | typeName = typeName.Substring(0, typeName.Length - cmd.Length); 46 | } 47 | 48 | return typeName.ToKebabCase(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/ConventionContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Conventions 8 | { 9 | /// 10 | /// The context in which a convention is applied. 11 | /// 12 | public class ConventionContext 13 | { 14 | /// 15 | /// Initializes an instance of . 16 | /// 17 | /// The application 18 | /// The type of the model. 19 | public ConventionContext(CommandLineApplication application, Type? modelType) 20 | { 21 | Application = application ?? throw new ArgumentNullException(nameof(application)); 22 | ModelType = modelType; 23 | } 24 | 25 | /// 26 | /// The application to which the convention is applied. 27 | /// 28 | public CommandLineApplication Application { get; private set; } 29 | 30 | /// 31 | /// The type of the application model. Can be null when applied to 32 | /// instead of . 33 | /// 34 | public Type? ModelType { get; private set; } 35 | 36 | /// 37 | /// A convenience accessor for getting the application model object. 38 | /// Can be null when applied to instead of 39 | /// . 40 | /// 41 | public IModelAccessor? ModelAccessor => Application as IModelAccessor; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/IConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Conventions 5 | { 6 | /// 7 | /// Defines a convention for an instance of . 8 | /// 9 | public interface IConvention 10 | { 11 | /// 12 | /// Apply the convention. 13 | /// 14 | /// The context in which the convention is applied. 15 | void Apply(ConventionContext context); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/IConventionBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Conventions 5 | { 6 | /// 7 | /// Builds a collection of conventions. 8 | /// 9 | public interface IConventionBuilder 10 | { 11 | /// 12 | /// Add a convention that will be applied later. 13 | /// 14 | /// The convention 15 | IConventionBuilder AddConvention(IConvention convention); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/IMemberConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Conventions 7 | { 8 | /// 9 | /// Defines a convention that is implemented as an attribute on a model type. 10 | /// 11 | public interface IMemberConvention 12 | { 13 | /// 14 | /// Apply the convention given a property or method. 15 | /// 16 | /// The convention context. 17 | /// A member of the model type to which the attribute is applied. 18 | void Apply(ConventionContext context, MemberInfo member); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/ParentPropertyConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Conventions 8 | { 9 | /// 10 | /// Sets a property named Parent on the model type to the value 11 | /// of the model of the parent command. 12 | /// 13 | public class ParentPropertyConvention : IConvention 14 | { 15 | /// 16 | public virtual void Apply(ConventionContext context) 17 | { 18 | var modelAccessor = context.ModelAccessor; 19 | if (context.ModelType == null || modelAccessor == null) 20 | { 21 | return; 22 | } 23 | 24 | var parentProp = context.ModelType.GetProperty("Parent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 25 | if (parentProp == null) 26 | { 27 | return; 28 | } 29 | 30 | var setter = ReflectionHelper.GetPropertySetter(parentProp); 31 | context.Application.OnParsingComplete(r => 32 | { 33 | var subcommand = r.SelectedCommand; 34 | while (subcommand != null) 35 | { 36 | if (ReferenceEquals(context.Application, subcommand)) 37 | { 38 | if (subcommand.Parent is IModelAccessor parentAccessor) 39 | { 40 | setter(modelAccessor.GetModel(), parentAccessor.GetModel()); 41 | } 42 | return; 43 | } 44 | subcommand = subcommand.Parent; 45 | } 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Conventions 8 | { 9 | /// 10 | /// Sets a property named Subcommand to the value of the selected subcommand 11 | /// model type of . 12 | /// 13 | public class SubcommandPropertyConvention : IConvention 14 | { 15 | /// 16 | public virtual void Apply(ConventionContext context) 17 | { 18 | var modelAccessor = context.ModelAccessor; 19 | if (context.ModelType == null || modelAccessor == null) 20 | { 21 | return; 22 | } 23 | 24 | var subcommandProp = context.ModelType.GetProperty("Subcommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 25 | if (subcommandProp == null) 26 | { 27 | return; 28 | } 29 | 30 | var setter = ReflectionHelper.GetPropertySetter(subcommandProp); 31 | context.Application.OnParsingComplete(r => 32 | { 33 | var subCommand = r.SelectedCommand; 34 | while (subCommand != null) 35 | { 36 | if (ReferenceEquals(subCommand.Parent, context.Application)) 37 | { 38 | if (subCommand is IModelAccessor subcmdAccessor) 39 | { 40 | setter(modelAccessor.GetModel(), subcmdAccessor.GetModel()); 41 | } 42 | return; 43 | } 44 | subCommand = subCommand.Parent; 45 | } 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/ValidationErrorMethodConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Conventions 7 | { 8 | /// 9 | /// Invokes a method named OnValidationError on the model type of 10 | /// to handle validation errors. 11 | /// 12 | public class ValidationErrorMethodConvention : IConvention 13 | { 14 | /// 15 | public virtual void Apply(ConventionContext context) 16 | { 17 | var modelAccessor = context.ModelAccessor; 18 | if (context.ModelType == null || modelAccessor == null) 19 | { 20 | return; 21 | } 22 | 23 | const BindingFlags MethodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; 24 | 25 | var method = context.ModelType.GetMethod("OnValidationError", MethodFlags); 26 | if (method == null) 27 | { 28 | return; 29 | } 30 | 31 | context.Application.ValidationErrorHandler = (v) => 32 | { 33 | var arguments = ReflectionHelper.BindParameters(method, context.Application, default); 34 | var result = method.Invoke(modelAccessor.GetModel(), arguments); 35 | if (method.ReturnType == typeof(int)) 36 | { 37 | #pragma warning disable CS8605 // Unboxing a possibly null value. 38 | return (int)result; 39 | #pragma warning restore CS8605 // Unboxing a possibly null value. 40 | } 41 | 42 | return CommandLineApplication.ValidationErrorExitCode; 43 | }; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Conventions/VersionOptionFromMemberAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Conventions 7 | { 8 | /// 9 | /// Sets using settings from 10 | /// on the model type of . 11 | /// 12 | public class VersionOptionFromMemberAttributeConvention : IConvention 13 | { 14 | /// 15 | public virtual void Apply(ConventionContext context) 16 | { 17 | var modelAccessor = context.ModelAccessor; 18 | if (context.ModelType == null || modelAccessor == null) 19 | { 20 | return; 21 | } 22 | 23 | var versionOptionFromMember = context.ModelType.GetCustomAttribute(); 24 | versionOptionFromMember?.Configure(context.Application, context.ModelType, modelAccessor.GetModel); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Errors/MissingParameterlessConstructorException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils 8 | { 9 | /// 10 | /// The exception that is thrown when trying to instantiate a model with no parameterless constructor. 11 | /// 12 | public class MissingParameterlessConstructorException : TargetException 13 | { 14 | /// 15 | /// Gets the type that caused the exception. 16 | /// 17 | public Type Type { get; private set; } 18 | 19 | /// 20 | /// Initializes an instance of . 21 | /// 22 | /// The type missing a parameterless constructor. 23 | /// The original exception. 24 | public MissingParameterlessConstructorException(Type type, Exception innerException) 25 | : base($"Class {type.FullName} does not have a parameterless constructor", innerException) 26 | { 27 | Type = type; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Errors/SubcommandCycleException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Errors 7 | { 8 | /// 9 | /// The exception that is thrown when a subcommand cycle is detected 10 | /// 11 | public class SubcommandCycleException : Exception 12 | { 13 | /// 14 | /// Initializes an instance of . 15 | /// 16 | /// The type of the cycled command model 17 | public SubcommandCycleException(Type modelType) 18 | : base($"Subcommand cycle detected: trying to add command of model {modelType} as its own direct or indirect subcommand") 19 | { 20 | ModelType = modelType ?? throw new ArgumentNullException(nameof(modelType)); 21 | } 22 | 23 | /// 24 | /// The type of the cycled command model 25 | /// 26 | public Type ModelType { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Errors/UnrecognizedCommandParsingException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils 8 | { 9 | /// 10 | /// The exception that is thrown when an invalid argument is given and when we can make suggestions 11 | /// about similar, valid commands or options. 12 | /// 13 | public class UnrecognizedCommandParsingException : CommandParsingException 14 | { 15 | /// 16 | /// Initializes an instance of . 17 | /// 18 | /// 19 | /// The options or commands that 20 | /// 21 | public UnrecognizedCommandParsingException(CommandLineApplication command, 22 | IEnumerable nearestMatches, 23 | string message) 24 | : base(command, message) 25 | { 26 | NearestMatches = nearestMatches ?? throw new ArgumentNullException(nameof(nearestMatches)); 27 | } 28 | 29 | /// 30 | /// A collection of strings representing suggestions about similar and valid commands or options for the invalid 31 | /// argument that caused this . 32 | /// 33 | /// 34 | /// This property always be empty is false. 35 | /// 36 | /// This property get/set the suggestions for an invalid argument. 37 | public IEnumerable NearestMatches { get; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/CommandLineUtils/HelpText/IHelpTextGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.HelpText 7 | { 8 | /// 9 | /// Generates help text for a command line application. 10 | /// 11 | public interface IHelpTextGenerator 12 | { 13 | /// 14 | /// Generate help text for the application. 15 | /// 16 | /// 17 | /// 18 | void Generate(CommandLineApplication application, TextWriter output); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CommandLineUtils/IO/IConsole.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | using System; 7 | using System.IO; 8 | 9 | namespace McMaster.Extensions.CommandLineUtils 10 | { 11 | /// 12 | /// An abstract console. 13 | /// 14 | public interface IConsole 15 | { 16 | /// 17 | /// Raised when Ctrl+C is pressed. 18 | /// 19 | event ConsoleCancelEventHandler? CancelKeyPress; 20 | 21 | /// 22 | /// stdout 23 | /// 24 | TextWriter Out { get; } 25 | 26 | /// 27 | /// stderr 28 | /// 29 | TextWriter Error { get; } 30 | 31 | /// 32 | /// stdin 33 | /// 34 | TextReader In { get; } 35 | 36 | /// 37 | /// Is stdin piped from somewhere? 38 | /// 39 | bool IsInputRedirected { get; } 40 | 41 | /// 42 | /// Is stdout being piped to somewhere? 43 | /// 44 | bool IsOutputRedirected { get; } 45 | 46 | /// 47 | /// Is stderr being piped to somewhere? 48 | /// 49 | bool IsErrorRedirected { get; } 50 | 51 | /// 52 | /// The foreground color of output. 53 | /// 54 | ConsoleColor ForegroundColor { get; set; } 55 | 56 | /// 57 | /// The background color of output. 58 | /// 59 | ConsoleColor BackgroundColor { get; set; } 60 | 61 | /// 62 | /// Resets and . 63 | /// 64 | void ResetColor(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/CommandLineUtils/IO/IReporter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | /// 9 | /// Gathers messages with levels. 10 | /// 11 | public interface IReporter 12 | { 13 | /// 14 | /// Report a verbose message. 15 | /// 16 | /// 17 | void Verbose(string message); 18 | 19 | /// 20 | /// Report console output. 21 | /// 22 | /// 23 | void Output(string message); 24 | 25 | /// 26 | /// Report a warning. 27 | /// 28 | /// 29 | void Warn(string message); 30 | 31 | /// 32 | /// Report an error. 33 | /// 34 | /// 35 | void Error(string message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CommandLineUtils/IO/NullReporter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | /// 9 | /// A reporter that does nothing. 10 | /// 11 | public class NullReporter : IReporter 12 | { 13 | private NullReporter() 14 | { } 15 | 16 | /// 17 | /// A shared instance of . 18 | /// 19 | public static IReporter Singleton { get; } = new NullReporter(); 20 | 21 | /// 22 | public void Verbose(string message) 23 | { } 24 | 25 | /// 26 | public void Output(string message) 27 | { } 28 | 29 | /// 30 | public void Warn(string message) 31 | { } 32 | 33 | /// 34 | public void Error(string message) 35 | { } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/CommandLineValidationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils 8 | { 9 | internal class CommandLineValidationContextFactory 10 | { 11 | private readonly CommandLineApplication _app; 12 | 13 | public CommandLineValidationContextFactory(CommandLineApplication app) 14 | { 15 | _app = app ?? throw new ArgumentNullException(nameof(app)); 16 | } 17 | 18 | public ValidationContext Create(CommandLineApplication app) => new(app, _app, null); 19 | 20 | public ValidationContext Create(CommandArgument argument) => new(argument, _app, null); 21 | 22 | public ValidationContext Create(CommandOption option) => new(option, _app, null); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/DefaultCommandLineContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Internal 8 | { 9 | internal class DefaultCommandLineContext : CommandLineContext 10 | { 11 | public DefaultCommandLineContext() 12 | { 13 | } 14 | 15 | public DefaultCommandLineContext(IConsole console) 16 | { 17 | Console = console; 18 | } 19 | 20 | public DefaultCommandLineContext(IConsole console, string workDir) 21 | : this(console) 22 | { 23 | if (!Path.IsPathRooted(workDir)) 24 | { 25 | workDir = Path.GetFullPath(workDir); 26 | } 27 | 28 | WorkingDirectory = workDir; 29 | } 30 | 31 | public DefaultCommandLineContext(IConsole console, string workDir, string[] args) 32 | : this(console, workDir) 33 | { 34 | Arguments = args; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/Delegates.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils 5 | { 6 | internal delegate void SetPropertyDelegate(object obj, object? value); 7 | 8 | internal delegate object GetPropertyDelegate(object obj); 9 | } 10 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/FilePathType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | /// 9 | /// Represents file path types. 10 | /// 11 | [Flags] 12 | internal enum FilePathType 13 | { 14 | /// 15 | /// A file path to a directory. 16 | /// 17 | Directory = 1 << 0, 18 | 19 | /// 20 | /// A file path to a file. 21 | /// 22 | File = 1 << 1, 23 | 24 | /// 25 | /// Any type of filepath. 26 | /// 27 | Any = Directory | File, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ICollectionParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | internal interface ICollectionParser 9 | { 10 | object Parse(string? argName, IReadOnlyList values); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/IInternalCommandParamOfT.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Globalization; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | internal interface IInternalCommandParamOfT 9 | { 10 | void Parse(CultureInfo culture); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ITupleValueParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Globalization; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils 7 | { 8 | 9 | /// 10 | /// Parses a value to Tuple{bool,} or ValueTuple{bool,} 11 | /// 12 | internal interface ITupleValueParser 13 | { 14 | object Parse(bool hasValue, string argName, string value, CultureInfo culture); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ParserConfig.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils 5 | { 6 | /// 7 | /// Configures the argument parser. 8 | /// 9 | internal class ParserConfig 10 | { 11 | /// 12 | /// Characters used to separate the option name from the value. 13 | /// 14 | /// By default, allowed separators are ' ' (space), :, and = 15 | /// 16 | /// 17 | /// 18 | /// Space actually implies multiple spaces due to the way most operating system shells parse command 19 | /// line arguments before starting a new process. 20 | /// 21 | /// 22 | /// Given --name=value, = is the separator. 23 | /// 24 | public char[]? OptionNameValueSeparators { get; set; } 25 | 26 | /// 27 | /// Set the behavior for how to handle unrecognized arguments. 28 | /// 29 | public UnrecognizedArgumentHandling? UnrecognizedArgumentHandling { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/ArrayParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Globalization; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 9 | { 10 | internal class ArrayParser : ICollectionParser 11 | { 12 | private readonly Type _elementType; 13 | private readonly IValueParser _elementParser; 14 | private readonly CultureInfo _parserCulture; 15 | 16 | public ArrayParser(Type elementType, IValueParser elementParser, CultureInfo parserCulture) 17 | { 18 | _elementType = elementType; 19 | _elementParser = elementParser; 20 | _parserCulture = parserCulture; 21 | } 22 | 23 | public object Parse(string? argName, IReadOnlyList values) 24 | { 25 | var array = Array.CreateInstance(_elementType, values.Count); 26 | for (var i = 0; i < values.Count; i++) 27 | { 28 | array.SetValue(_elementParser.Parse(argName, values[i], _parserCulture), i); 29 | } 30 | return array; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/EnumParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | internal static class EnumParser 9 | { 10 | public static IValueParser Create(Type enumType) => 11 | ValueParser.Create(enumType, (argName, value, culture) => 12 | { 13 | if (value == null) return Enum.ToObject(enumType, 0); 14 | 15 | try 16 | { 17 | return Enum.Parse(enumType, value, ignoreCase: true); 18 | } 19 | catch 20 | { 21 | throw new FormatException( 22 | $"Invalid value specified for {argName}. Allowed values are: {string.Join(", ", Enum.GetNames(enumType))}."); 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/HashSetParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Globalization; 7 | using System.Reflection; 8 | 9 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 10 | { 11 | internal class HashSetParser : ICollectionParser 12 | { 13 | private readonly IValueParser _elementParser; 14 | private readonly Type _listType; 15 | private readonly MethodInfo _addMethod; 16 | private readonly CultureInfo _parserCulture; 17 | 18 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 19 | public HashSetParser(Type elementType, IValueParser elementParser, CultureInfo parserCulture) 20 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 21 | { 22 | _elementParser = elementParser; 23 | _listType = typeof(HashSet<>).MakeGenericType(elementType); 24 | #pragma warning disable CS8601 // Possible null reference assignment. 25 | _addMethod = _listType.GetRuntimeMethod("Add", new[] { elementType }); 26 | #pragma warning restore CS8601 // Possible null reference assignment. 27 | _parserCulture = parserCulture; 28 | } 29 | 30 | public object Parse(string? argName, IReadOnlyList values) 31 | { 32 | var set = Activator.CreateInstance(_listType, Array.Empty()); 33 | foreach (var t in values) 34 | { 35 | _addMethod.Invoke(set, new[] { _elementParser.Parse(argName, t, _parserCulture) }); 36 | } 37 | #pragma warning disable CS8603 // Possible null reference return. 38 | return set; 39 | #pragma warning restore CS8603 // Possible null reference return. 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/ListParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using System.Globalization; 8 | 9 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 10 | { 11 | 12 | internal class ListParser : ICollectionParser 13 | { 14 | private readonly IValueParser _elementParser; 15 | private readonly Type _listType; 16 | private readonly CultureInfo _parserCulture; 17 | 18 | public ListParser(Type elementType, IValueParser elementParser, CultureInfo parserCulture) 19 | { 20 | _elementParser = elementParser; 21 | _listType = typeof(List<>).MakeGenericType(elementType); 22 | _parserCulture = parserCulture; 23 | } 24 | 25 | public object Parse(string? argName, IReadOnlyList values) 26 | { 27 | #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. 28 | var list = (IList)Activator.CreateInstance(_listType, new object[] { values.Count }); 29 | #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. 30 | foreach (var t in values) 31 | { 32 | #pragma warning disable CS8602 // Dereference of a possibly null reference. 33 | list.Add(_elementParser.Parse(argName, t, _parserCulture)); 34 | #pragma warning restore CS8602 // Dereference of a possibly null reference. 35 | } 36 | #pragma warning disable CS8603 // Possible null reference return. 37 | return list; 38 | #pragma warning restore CS8603 // Possible null reference return. 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/NullableValueParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Globalization; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 8 | { 9 | internal class NullableValueParser : IValueParser 10 | { 11 | private readonly IValueParser _wrapped; 12 | 13 | public NullableValueParser(IValueParser boxedParser) 14 | { 15 | _wrapped = boxedParser; 16 | } 17 | 18 | public Type TargetType 19 | { 20 | get 21 | { 22 | throw new InvalidOperationException($"{nameof(NullableValueParser)} does not have a target type"); 23 | } 24 | } 25 | 26 | 27 | public object? Parse(string? argName, string? value, CultureInfo culture) 28 | { 29 | return !string.IsNullOrWhiteSpace(value) 30 | ? _wrapped.Parse(argName, value, culture) 31 | : null; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/TupleValueParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | internal class TupleValueParser 9 | { 10 | public static IValueParser> Create(IValueParser typeParser) 11 | { 12 | if (typeParser == null) throw new ArgumentNullException(nameof(typeParser)); 13 | 14 | return 15 | ValueParser.Create((argName, value, culture) => 16 | value == null 17 | ? Tuple.Create(false, default!) 18 | : Tuple.Create(true, typeParser.Parse(argName, value, culture))); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Internal/ValueParsers/ValueTupleValueParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Abstractions 7 | { 8 | internal static class ValueTupleValueParser 9 | { 10 | public static IValueParser<(bool, T)> Create(IValueParser typeParser) 11 | { 12 | if (typeParser == null) throw new ArgumentNullException(nameof(typeParser)); 13 | 14 | return 15 | ValueParser.Create((argName, value, culture) => 16 | value == null 17 | ? (true, default!) 18 | : (true, typeParser.Parse(argName, value, culture))); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | true 7 | Command-line parsing API. 8 | Command-line parsing API and utilities for console applications. 9 | 10 | Commonly used types: 11 | 12 | McMaster.Extensions.CommandLineUtils.CommandLineApplication 13 | McMaster.Extensions.CommandLineUtils.CommandOption 14 | McMaster.Extensions.CommandLineUtils.IConsole 15 | McMaster.Extensions.CommandLineUtils.Prompt 16 | McMaster.Extensions.CommandLineUtils.ArgumentEscaper 17 | 18 | A community-maintained fork of Microsoft.Extensions.CommandLineUtils, plus many enhancements. 19 | 20 | commandline;parsing 21 | README.md 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Properties/InternalsVisibleTo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("McMaster.Extensions.CommandLineUtils.Tests, PublicKey = 00240000048000009400000006020000002400005253413100040000010001001df0eba4297c8ffdf114a13714ad787744619dfb18e29191703f6f782d6a09e4a4cac35b8c768cbbd9ade8197bc0f66ec66fabc9071a206c8060af8b7a332236968d3ee44b90bd2f30d0edcb6150555c6f8d988e48234debaf2d427a08d7c06ba1343411142dc8ac996f7f7dbe0e93d13f17a7624db5400510e6144b0fd683b9")] 7 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Properties/NullabilityHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // Files here are for simplify annotations of nullable code and are not functional in .NET Standard 2.0 5 | #if NETSTANDARD2_0 || NET46_OR_GREATER 6 | namespace System.Diagnostics.CodeAnalysis 7 | { 8 | // https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.notnullwhenattribute? 9 | [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] 10 | internal sealed class NotNullWhenAttribute : Attribute 11 | { 12 | public NotNullWhenAttribute(bool returnValue) 13 | { 14 | } 15 | } 16 | 17 | // https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.allownullattribute 18 | [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property, Inherited=false)] 19 | internal sealed class AllowNullAttribute : Attribute { } 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/PublicAPI.Unshipped.txt: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | -------------------------------------------------------------------------------- /src/CommandLineUtils/ResponseFileHandling.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils 5 | { 6 | /// 7 | /// 8 | /// Specifies options for how to handle response files. The parser treats arguments beginning with '@' as a file path to a response file. 9 | /// 10 | /// 11 | /// A response file contains additional arguments that will be treated as if they were passed in on the command line. 12 | /// Response files can have comments that begin with the # symbol. 13 | /// You cannot use the backslash character (\) to concatenate lines. 14 | /// 15 | /// 16 | public enum ResponseFileHandling 17 | { 18 | /// 19 | /// Do not parse response files or treat arguments with '@' as a response file 20 | /// 21 | Disabled, 22 | 23 | /// 24 | /// 25 | /// Multiple arguments may appear on one line. Arguments are separate by spaces. 26 | /// 27 | /// 28 | /// Double and single quotes can be used to wrap arguments containing spaces. 29 | /// 30 | /// 31 | ParseArgsAsSpaceSeparated, 32 | 33 | /// 34 | /// 35 | /// Each line in the file is treated as an argument, regardless of whitespace on the line. 36 | /// 37 | /// 38 | /// Lines beginning with # are skipped. 39 | /// 40 | /// 41 | ParseArgsAsLineSeparated, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CommandLineUtils/UnrecognizedArgumentHandling.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils 5 | { 6 | /// 7 | /// Defines behaviors for for how unrecognized arguments should be handled. 8 | /// 9 | public enum UnrecognizedArgumentHandling 10 | { 11 | /// 12 | /// When an unrecognized argument is encountered, throw . 13 | /// 14 | Throw = 0, 15 | 16 | /// 17 | /// When an unrecognized argument is encountered, stop parsing arguments and put all remaining arguments, 18 | /// including the first unrecognized argument, in . 19 | /// 20 | StopParsingAndCollect, 21 | 22 | /// 23 | /// When an unrecognized argument is encountered, save it in a list that will be assigned 24 | /// to . 25 | /// 26 | CollectAndContinue, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Utilities/DotNetCliContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | using System; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// APIs related to .NET Core CLI. 12 | /// 13 | public static class DotNetCliContext 14 | { 15 | /// 16 | /// `dotnet --diagnostics` was specified. 17 | /// 18 | public static bool IsGlobalVerbose() 19 | { 20 | bool.TryParse(Environment.GetEnvironmentVariable("DOTNET_CLI_CONTEXT_VERBOSE"), out var globalVerbose); 21 | return globalVerbose; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/DelegateValidator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Validation 8 | { 9 | /// 10 | /// Implements a validator with an anonymous function 11 | /// 12 | public class DelegateValidator : ICommandValidator, IArgumentValidator, IOptionValidator 13 | { 14 | private readonly Func _validator; 15 | 16 | /// 17 | /// Initializes an instance of . 18 | /// 19 | /// 20 | public DelegateValidator(Func validator) 21 | { 22 | _validator = validator ?? throw new ArgumentNullException(nameof(validator)); 23 | } 24 | 25 | ValidationResult ICommandValidator.GetValidationResult(CommandLineApplication command, ValidationContext context) 26 | => _validator(context); 27 | 28 | ValidationResult IArgumentValidator.GetValidationResult(CommandArgument argument, ValidationContext context) 29 | => _validator(context); 30 | 31 | ValidationResult IOptionValidator.GetValidationResult(CommandOption option, ValidationContext context) 32 | => _validator(context); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IArgumentValidationBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators for . 8 | /// 9 | /// 10 | /// Custom validation extension methods that only apply to should hang off this type. 11 | /// 12 | public interface IArgumentValidationBuilder : IValidationBuilder 13 | { 14 | /// 15 | /// Use the given . 16 | /// 17 | /// The validator. 18 | void Use(IArgumentValidator validator); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IArgumentValidationBuilder{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators for . 8 | /// 9 | /// 10 | /// Custom validation extension methods that only apply to should hang off this type. 11 | /// 12 | public interface IArgumentValidationBuilder : IArgumentValidationBuilder, IValidationBuilder 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IArgumentValidator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Validation 7 | { 8 | /// 9 | /// Provides validation for a . 10 | /// 11 | public interface IArgumentValidator 12 | { 13 | /// 14 | /// Validates the values specified for . 15 | /// 16 | /// The argument. 17 | /// The validation context. 18 | /// The validation result. Returns if the values pass validation. 19 | ValidationResult? GetValidationResult(CommandArgument argument, ValidationContext context); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/ICommandValidator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Validation 7 | { 8 | /// 9 | /// Provides validation on a command 10 | /// 11 | public interface ICommandValidator 12 | { 13 | /// 14 | /// Validates a command 15 | /// 16 | /// The command. 17 | /// The validation context. 18 | /// The validation result. Returns if the values pass validation. 19 | ValidationResult? GetValidationResult(CommandLineApplication command, ValidationContext context); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IOptionValidationBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators for . 8 | /// 9 | /// 10 | /// Custom validation extension methods that only apply to should hang off this type. 11 | /// 12 | public interface IOptionValidationBuilder : IValidationBuilder 13 | { 14 | /// 15 | /// Use the given . 16 | /// 17 | /// The validator. 18 | void Use(IOptionValidator validator); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IOptionValidationBuilder{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators for . 8 | /// 9 | /// 10 | /// Custom validation extension methods that only apply to should hang off this type. 11 | /// 12 | public interface IOptionValidationBuilder : IOptionValidationBuilder, IValidationBuilder 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IOptionValidator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Validation 7 | { 8 | /// 9 | /// Provides validation for a . 10 | /// 11 | public interface IOptionValidator 12 | { 13 | /// 14 | /// Validates the values specified for . 15 | /// 16 | /// The option. 17 | /// The validation context. 18 | /// The validation result. Returns if the values pass validation. 19 | ValidationResult? GetValidationResult(CommandOption option, ValidationContext context); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IValidationBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators. 8 | /// 9 | /// 10 | /// Custom validation extension methods should hang off this type. 11 | /// 12 | public interface IValidationBuilder 13 | { 14 | /// 15 | /// Use the . 16 | /// 17 | /// The validator. 18 | void Use(IValidator validator); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IValidationBuilder{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Creates a collection of validators on or 8 | /// 9 | /// 10 | /// Custom validation extension methods should hang off this type. 11 | /// 12 | public interface IValidationBuilder : IValidationBuilder 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/IValidator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace McMaster.Extensions.CommandLineUtils.Validation 5 | { 6 | /// 7 | /// Provides validation for and . 8 | /// 9 | public interface IValidator : IOptionValidator, IArgumentValidator 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/CommandLineUtils/Validation/ValidationBuilder{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | 5 | namespace McMaster.Extensions.CommandLineUtils.Validation 6 | { 7 | /// 8 | /// Default implementation of and . 9 | /// 10 | public class ValidationBuilder : ValidationBuilder, IArgumentValidationBuilder, IOptionValidationBuilder 11 | { 12 | /// 13 | /// Creates a new instance of for a given . 14 | /// 15 | /// The argument. 16 | public ValidationBuilder(CommandArgument argument) : base(argument) 17 | { 18 | } 19 | 20 | /// 21 | /// Creates a new instance of for a given . 22 | /// 23 | /// The option. 24 | public ValidationBuilder(CommandOption option) : base(option) 25 | { 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/HostBuilderContextExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using McMaster.Extensions.CommandLineUtils.Abstractions; 5 | using McMaster.Extensions.Hosting.CommandLine.Internal; 6 | 7 | namespace Microsoft.Extensions.Hosting 8 | { 9 | /// 10 | /// Extensions methods for the 11 | /// 12 | public static class HostBuilderContextExtensions 13 | { 14 | /// 15 | /// Get the used to run the app 16 | /// 17 | /// This instance 18 | /// The used to run the app 19 | public static CommandLineContext GetCommandLineContext(this HostBuilderContext context) 20 | => (CommandLineContext)context.Properties[typeof(CommandLineState)]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/HostExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.ExceptionServices; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using McMaster.Extensions.CommandLineUtils; 9 | using McMaster.Extensions.Hosting.CommandLine.Internal; 10 | using Microsoft.Extensions.DependencyInjection; 11 | 12 | namespace Microsoft.Extensions.Hosting 13 | { 14 | /// 15 | /// Extension methods for support. 16 | /// 17 | public static class HostExtensions 18 | { 19 | /// 20 | /// Runs the app using the previously configured in 21 | /// . 22 | /// 23 | /// A program abstraction. 24 | /// Propagates notification that operations should be canceled. 25 | public static async Task RunCommandLineApplicationAsync(this IHost host, CancellationToken cancellationToken = default) 26 | { 27 | var exceptionHandler = host.Services.GetService(); 28 | var state = host.Services.GetRequiredService(); 29 | 30 | await host.RunAsync(cancellationToken); 31 | 32 | if (exceptionHandler?.StoredException != null) 33 | { 34 | ExceptionDispatchInfo.Capture(exceptionHandler.StoredException).Throw(); 35 | } 36 | 37 | return state.ExitCode; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/IUnhandledExceptionHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using McMaster.Extensions.CommandLineUtils; 6 | using McMaster.Extensions.Hosting.CommandLine.Internal; 7 | 8 | namespace McMaster.Extensions.Hosting.CommandLine 9 | { 10 | /// 11 | /// Used by to handle exceptions that are emitted from the 12 | /// e.g. during parsing or execution 13 | /// 14 | public interface IUnhandledExceptionHandler 15 | { 16 | /// 17 | /// Handle otherwise uncaught exception. You are free to log, rethrow, … the exception 18 | /// 19 | /// An otherwise uncaught exception 20 | void HandleException(Exception e); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/Internal/CommandLineState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using McMaster.Extensions.CommandLineUtils; 5 | using McMaster.Extensions.CommandLineUtils.Abstractions; 6 | 7 | namespace McMaster.Extensions.Hosting.CommandLine.Internal 8 | { 9 | /// 10 | /// A DI container for storing command line arguments. 11 | /// 12 | internal class CommandLineState : CommandLineContext 13 | { 14 | public CommandLineState(string[] args) 15 | { 16 | Arguments = args; 17 | } 18 | 19 | internal void SetConsole(IConsole console) 20 | { 21 | Console = console; 22 | } 23 | 24 | public int ExitCode { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/Internal/ICommandLineService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace McMaster.Extensions.Hosting.CommandLine.Internal 8 | { 9 | /// 10 | /// A service to be run as part of the . 11 | /// 12 | internal interface ICommandLineService 13 | { 14 | /// 15 | /// Runs the application asynchronously and returns the exit code. 16 | /// 17 | /// Used to indicate when stop should no longer be graceful. 18 | /// The exit code 19 | Task RunAsync(CancellationToken cancellationToken); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/Internal/StoreExceptionHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace McMaster.Extensions.Hosting.CommandLine.Internal 7 | { 8 | /// 9 | /// Implementation of that stores an unhandled exception so it can later be 10 | /// rethrown by . 11 | /// 12 | internal class StoreExceptionHandler : IUnhandledExceptionHandler 13 | { 14 | /// 15 | /// The captured exception, if any 16 | /// 17 | public Exception? StoredException { get; private set; } 18 | 19 | /// 20 | /// This will store the first unhandled exception and throw an if called a 21 | /// second time. 22 | /// 23 | /// The unhandled exception to store 24 | /// If called a second time an containing 25 | /// both exceptions is raised 26 | public void HandleException(Exception e) 27 | { 28 | if (StoredException != null) 29 | { 30 | throw new AggregateException("Second exception received!", StoredException, e); 31 | } 32 | 33 | StoredException = e; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | true 6 | true 7 | Provides command-line parsing API integration with the generic host API (Microsoft.Extensions.Hosting). 8 | commandline;parsing;hosting 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Hosting.CommandLine/PublicAPI.Unshipped.txt: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | -------------------------------------------------------------------------------- /src/StrongName.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natemcmaster/CommandLineUtils/210871add72e8ad22661194c6f630fc1ecee140f/src/StrongName.snk -------------------------------------------------------------------------------- /src/common.psm1: -------------------------------------------------------------------------------- 1 | function exec([string]$_cmd) { 2 | write-host -ForegroundColor DarkGray ">>> $_cmd $args" 3 | $ErrorActionPreference = 'Continue' 4 | & $_cmd @args 5 | $ErrorActionPreference = 'Stop' 6 | if ($LASTEXITCODE -ne 0) { 7 | write-error "Failed with exit code $LASTEXITCODE" 8 | exit 1 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/AppNameFromEntryAssemblyConventionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | using Xunit; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Tests 8 | { 9 | public class AppNameFromEntryAssemblyConventionTests 10 | { 11 | [Fact] 12 | public void ItSetsAppNameToEntryAssemblyIfNotSpecified() 13 | { 14 | if (Assembly.GetEntryAssembly() == null) 15 | { 16 | return; 17 | } 18 | 19 | var expected = Assembly.GetEntryAssembly().GetName().Name; 20 | var app = new CommandLineApplication(); 21 | app.Conventions.SetAppNameFromEntryAssembly(); 22 | Assert.Equal(expected, app.Name); 23 | } 24 | 25 | [Fact] 26 | public void ItDoesNotSpecifyCommandNameForSubcommands() 27 | { 28 | var app = new CommandLineApplication(); 29 | app.Conventions.SetAppNameFromEntryAssembly(); 30 | var subcmd = app.Command(null!, null!); 31 | Assert.Null(subcmd.Name); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/ArgumentEscaperTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | using Xunit; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils.Tests 9 | { 10 | public class ArgumentEscaperTests 11 | { 12 | [Theory] 13 | [InlineData(new[] { "one", "two", "three" }, "one two three")] 14 | [InlineData(new[] { "line1\nline2", "word1\tword2" }, "\"line1\nline2\" \"word1\tword2\"")] 15 | [InlineData(new[] { "with spaces" }, "\"with spaces\"")] 16 | [InlineData(new[] { @"with\backslash" }, @"with\backslash")] 17 | [InlineData(new[] { @"""quotedwith\backslash""" }, @"\""quotedwith\backslash\""")] 18 | [InlineData(new[] { @"C:\Users\" }, @"C:\Users\")] 19 | [InlineData(new[] { @"C:\Program Files\dotnet\" }, @"""C:\Program Files\dotnet\\""")] 20 | [InlineData(new[] { @"backslash\""preceedingquote" }, @"backslash\\\""preceedingquote")] 21 | [InlineData(new[] { @""" hello nate """ }, @"""\"" hello nate \""""")] 22 | [InlineData(new[] { "one", "", "three" }, "one \"\" three")] 23 | public void EscapesArguments(string[] args, string expected) 24 | { 25 | Assert.Equal(expected, ArgumentEscaper.EscapeAndConcatenate(args)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/CommandAttributeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Tests 7 | { 8 | public class CommandAttributeTests 9 | { 10 | [Command( 11 | ResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated, 12 | AllowArgumentSeparator = true, 13 | UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect)] 14 | private class ParsingOptions 15 | { } 16 | 17 | [Fact] 18 | public void HandlesParsingOptionsAttribute() 19 | { 20 | var app = new CommandLineApplication(); 21 | app.Conventions.UseCommandAttribute(); 22 | 23 | Assert.Equal(ResponseFileHandling.ParseArgsAsLineSeparated, app.ResponseFileHandling); 24 | Assert.Equal(UnrecognizedArgumentHandling.StopParsingAndCollect, app.UnrecognizedArgumentHandling); 25 | Assert.True(app.AllowArgumentSeparator); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/CommandNameFromTypeConventionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using McMaster.Extensions.CommandLineUtils.Conventions; 5 | using Xunit; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Tests 8 | { 9 | public class CommandNameFromTypeConventionTests 10 | { 11 | [Theory] 12 | [InlineData("Command", "command")] 13 | [InlineData("AddCommand", "add")] 14 | [InlineData("RemoveItem", "remove-item")] 15 | [InlineData("Rm_Item", "rm-item")] 16 | [InlineData("Rm_Item_Command", "rm-item")] 17 | public void ItInfersCommandName(string typeName, string commandName) 18 | => Assert.Equal(commandName, CommandNameFromTypeConvention.GetCommandName(typeName)); 19 | 20 | [Subcommand(typeof(AddCommand))] 21 | private class Program 22 | { } 23 | 24 | private class AddCommand 25 | { } 26 | 27 | [Fact] 28 | public void ItInfersSubcommandNameFromTypeName() 29 | { 30 | var app = new CommandLineApplication(); 31 | app.Conventions.UseDefaultConventions(); 32 | var sub = Assert.Single(app.Commands); 33 | Assert.Equal("add", sub.Name); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/DotNetExeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | // This file has been modified from the original form. See Notice.txt in the project root for more information. 5 | 6 | #if NETCOREAPP3_1_OR_GREATER 7 | using System.IO; 8 | using Xunit; 9 | 10 | namespace McMaster.Extensions.CommandLineUtils.Tests 11 | { 12 | public class DotNetExeTests 13 | { 14 | [Fact] 15 | public void FindsTheDotNetPath() 16 | { 17 | var dotnetPath = DotNetExe.FullPath; 18 | Assert.NotNull(dotnetPath); 19 | Assert.True(File.Exists(dotnetPath), "The file did not exist"); 20 | Assert.True(Path.IsPathRooted(dotnetPath), "The path should be rooted"); 21 | Assert.Equal("dotnet", Path.GetFileNameWithoutExtension(dotnetPath), ignoreCase: true); 22 | } 23 | } 24 | } 25 | #elif NET472 26 | #else 27 | #error Update target frameworks 28 | #endif 29 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/LegalFilePathAttributeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | using Xunit.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Tests 8 | { 9 | public class LegalFilePathAttributeTests 10 | { 11 | private readonly ITestOutputHelper _output; 12 | 13 | public LegalFilePathAttributeTests(ITestOutputHelper output) 14 | { 15 | _output = output; 16 | } 17 | 18 | private class App 19 | { 20 | [Argument(0), LegalFilePath] 21 | public string? FilePath { get; set; } 22 | private void OnExecute() { } 23 | } 24 | 25 | [Theory] 26 | [InlineData(@"C:\dir")] 27 | [InlineData(@"/dir")] 28 | [InlineData(@"../dir")] 29 | [InlineData(@"dir")] 30 | [InlineData(@"file.txt")] 31 | [InlineData(@".file")] 32 | [InlineData(@"/file.txt")] 33 | [InlineData(@"C:\file.txt")] 34 | [InlineData(@"..")] 35 | [InlineData(@".")] 36 | [InlineData(@"./")] 37 | [InlineData(@"../")] 38 | [InlineData(@"../..")] 39 | public void ValidatesLegalFilePaths(string filePath) 40 | { 41 | var console = new TestConsole(_output); 42 | Assert.Equal(0, CommandLineApplication.Execute(console, filePath)); 43 | } 44 | 45 | [Theory] 46 | [InlineData(null)] 47 | [InlineData("")] 48 | [InlineData("\0")] 49 | public void FailsInvalidLegalFilePaths(string filePath) 50 | { 51 | var console = new TestConsole(_output); 52 | Assert.NotEqual(0, CommandLineApplication.Execute(console, filePath)); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/McMaster.Extensions.CommandLineUtils.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net6.0 5 | 6 | annotations 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/ParentPropertyConventionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Tests 7 | { 8 | public class ParentPropertyConventionTests 9 | { 10 | [Subcommand(typeof(AddCommand))] 11 | private class Program 12 | { 13 | public object? Subcommand { get; set; } 14 | } 15 | 16 | private class AddCommand 17 | { 18 | public object? Parent { get; } 19 | } 20 | 21 | [Fact] 22 | public void BindsToParentProperty() 23 | { 24 | var app = new CommandLineApplication(); 25 | app.Conventions.UseDefaultConventions(); 26 | var result = app.Parse("add"); 27 | var add = Assert.IsType>(result.SelectedCommand); 28 | Assert.IsType(add.Model.Parent); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/StringExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Tests 7 | { 8 | public class StringExtensionsTests 9 | { 10 | [Theory] 11 | [InlineData(null, null)] 12 | [InlineData("", "")] 13 | [InlineData("_", "")] 14 | [InlineData("__", "")] 15 | [InlineData("___", "")] 16 | [InlineData("Option123", "option123")] 17 | [InlineData("dWORD", "d-word")] 18 | [InlineData("MSBuild", "msbuild")] 19 | [InlineData("NoEdit", "no-edit")] 20 | [InlineData("SetUpstreamBranch", "set-upstream-branch")] 21 | [InlineData("lowerCaseFirst", "lower-case-first")] 22 | [InlineData("_field", "field")] 23 | [InlineData("__field", "field")] 24 | [InlineData("___field", "field")] 25 | [InlineData("field_", "field")] 26 | [InlineData("field__", "field")] 27 | [InlineData("field___", "field")] 28 | [InlineData("m_field", "m-field")] 29 | [InlineData("m_Field", "m-field")] 30 | public void ToKebabCase(string input, string expected) 31 | { 32 | Assert.Equal(expected, input.ToKebabCase()); 33 | } 34 | 35 | [Theory] 36 | [InlineData(null, null)] 37 | [InlineData("", "")] 38 | [InlineData("NoEdit", "NO_EDIT")] 39 | [InlineData("word", "WORD")] 40 | [InlineData("_field", "FIELD")] 41 | [InlineData("MSBuildTask", "MSBUILD_TASK")] 42 | public void ToConstantCase(string input, string expected) 43 | { 44 | Assert.Equal(expected, input.ToConstantCase()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/SubcommandPropertyConventionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | 6 | namespace McMaster.Extensions.CommandLineUtils.Tests 7 | { 8 | public class SubcommandPropertyConventionTests 9 | { 10 | [Subcommand(typeof(AddCommand))] 11 | private class Program 12 | { 13 | public object? Subcommand { get; set; } 14 | } 15 | 16 | private class AddCommand 17 | { 18 | public object? Parent { get; } 19 | } 20 | 21 | [Fact] 22 | public void BindsToSubcommandProperty() 23 | { 24 | var app = new CommandLineApplication(); 25 | app.Conventions.UseDefaultConventions(); 26 | app.Parse("add"); 27 | Assert.IsType(app.Model.Subcommand); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/Utilities/CommandLineParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | using McMaster.Extensions.CommandLineUtils.Tests; 6 | using Xunit.Abstractions; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils 9 | { 10 | /// 11 | /// Utilities for parsing a command line application 12 | /// 13 | internal static class CommandLineParser 14 | { 15 | public static T ParseArgs(params string[] args) 16 | where T : class 17 | => ParseArgsImpl(NullConsole.Singleton, args); 18 | 19 | public static T ParseArgs(ITestOutputHelper output, params string[] args) 20 | where T : class => ParseArgsImpl(new TestConsole(output), args); 21 | 22 | private static T ParseArgsImpl(IConsole console, string[] args) where T : class 23 | { 24 | var app = new CommandLineApplication(console, Directory.GetCurrentDirectory()); 25 | app.Conventions.UseDefaultConventions(); 26 | app.Parse(args); 27 | return app.Model; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/Utilities/ConventionTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using McMaster.Extensions.CommandLineUtils.Conventions; 5 | using Xunit.Abstractions; 6 | 7 | namespace McMaster.Extensions.CommandLineUtils.Tests 8 | { 9 | public class ConventionTestBase 10 | { 11 | protected readonly ITestOutputHelper _output; 12 | 13 | protected ConventionTestBase(ITestOutputHelper output) 14 | { 15 | _output = output; 16 | } 17 | 18 | protected CommandLineApplication Create() 19 | where T : class 20 | where TConvention : IConvention, new() 21 | { 22 | var app = new CommandLineApplication(new TestConsole(_output)); 23 | app.Conventions.AddConvention(new TConvention()); 24 | return app; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/Utilities/TestConsole.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Reflection; 8 | using Xunit.Abstractions; 9 | 10 | namespace McMaster.Extensions.CommandLineUtils.Tests 11 | { 12 | public class TestConsole : IConsole 13 | { 14 | public TestConsole(ITestOutputHelper output) 15 | { 16 | Out = new XunitTextWriter(output); 17 | Error = new XunitTextWriter(output); 18 | } 19 | 20 | public TextWriter Out { get; set; } 21 | 22 | public TextWriter Error { get; set; } 23 | 24 | public TextReader In => throw new NotImplementedException(); 25 | 26 | public bool IsInputRedirected => throw new NotImplementedException(); 27 | 28 | public bool IsOutputRedirected => true; 29 | 30 | public bool IsErrorRedirected => true; 31 | 32 | public ConsoleColor ForegroundColor { get; set; } 33 | public ConsoleColor BackgroundColor { get; set; } 34 | 35 | public event ConsoleCancelEventHandler? CancelKeyPress; 36 | 37 | public void ResetColor() 38 | { 39 | } 40 | 41 | public void RaiseCancelKeyPress() 42 | { 43 | // See https://github.com/dotnet/corefx/blob/f2292af3a1794378339d6f5c8adcc0f2019a2cf9/src/System.Console/src/System/ConsoleCancelEventArgs.cs#L14 44 | var eventArgs = typeof(ConsoleCancelEventArgs) 45 | .GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance) 46 | .First() 47 | .Invoke(new object[] { ConsoleSpecialKey.ControlC }); 48 | CancelKeyPress?.Invoke(this, (ConsoleCancelEventArgs)eventArgs); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/Utilities/XunitTextWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | using System.Text; 6 | using Xunit.Abstractions; 7 | 8 | namespace McMaster.Extensions.CommandLineUtils.Tests 9 | { 10 | public class XunitTextWriter : TextWriter 11 | { 12 | private readonly ITestOutputHelper _output; 13 | private readonly StringBuilder _sb = new(); 14 | 15 | public XunitTextWriter(ITestOutputHelper output) 16 | { 17 | _output = output; 18 | } 19 | 20 | public override Encoding Encoding => Encoding.Unicode; 21 | 22 | public override void Write(char ch) 23 | { 24 | if (ch == '\n') 25 | { 26 | _output.WriteLine(_sb.ToString()); 27 | _sb.Clear(); 28 | } 29 | else 30 | { 31 | _sb.Append(ch); 32 | } 33 | } 34 | 35 | protected override void Dispose(bool disposing) 36 | { 37 | if (disposing) 38 | { 39 | if (_sb.Length > 0) 40 | { 41 | _output.WriteLine(_sb.ToString()); 42 | _sb.Clear(); 43 | } 44 | } 45 | 46 | base.Dispose(disposing); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/CommandLineUtils.Tests/xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "methodDisplay": "method" 3 | } -------------------------------------------------------------------------------- /test/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(DefaultItemExcludes);TestResults\** 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/Hosting.CommandLine.Tests/Utilities/TestConsole.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using McMaster.Extensions.CommandLineUtils; 7 | using Xunit.Abstractions; 8 | 9 | namespace McMaster.Extensions.Hosting.CommandLine.Tests.Utilities 10 | { 11 | public class TestConsole : IConsole 12 | { 13 | public TestConsole(ITestOutputHelper output) 14 | { 15 | Out = new XunitTextWriter(output); 16 | Error = new XunitTextWriter(output); 17 | } 18 | 19 | public TextWriter Out { get; set; } 20 | 21 | public TextWriter Error { get; set; } 22 | 23 | public TextReader In => throw new NotImplementedException(); 24 | 25 | public bool IsInputRedirected => throw new NotImplementedException(); 26 | 27 | public bool IsOutputRedirected => true; 28 | 29 | public bool IsErrorRedirected => true; 30 | 31 | public ConsoleColor ForegroundColor { get; set; } 32 | public ConsoleColor BackgroundColor { get; set; } 33 | 34 | public event ConsoleCancelEventHandler? CancelKeyPress 35 | { 36 | add { } 37 | remove { } 38 | } 39 | 40 | public void ResetColor() 41 | { 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/Hosting.CommandLine.Tests/Utilities/XunitTextWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Nate McMaster. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | using System.Text; 6 | using Xunit.Abstractions; 7 | 8 | namespace McMaster.Extensions.Hosting.CommandLine.Tests.Utilities 9 | { 10 | public class XunitTextWriter : TextWriter 11 | { 12 | private readonly ITestOutputHelper _output; 13 | private readonly StringBuilder _sb = new(); 14 | 15 | public XunitTextWriter(ITestOutputHelper output) 16 | { 17 | _output = output; 18 | } 19 | 20 | public override Encoding Encoding => Encoding.Unicode; 21 | 22 | public override void Write(char ch) 23 | { 24 | if (ch == '\n') 25 | { 26 | _output.WriteLine(_sb.ToString()); 27 | _sb.Clear(); 28 | } 29 | else 30 | { 31 | _sb.Append(ch); 32 | } 33 | } 34 | 35 | protected override void Dispose(bool disposing) 36 | { 37 | if (disposing) 38 | { 39 | if (_sb.Length > 0) 40 | { 41 | _output.WriteLine(_sb.ToString()); 42 | _sb.Clear(); 43 | } 44 | } 45 | 46 | base.Dispose(disposing); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/Hosting.CommandLine.Tests/xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "methodDisplay": "method" 3 | } --------------------------------------------------------------------------------