├── .config └── tsaoptions.json ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .vsts-ci-official.yml ├── .vsts-ci.yml ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── Directory.Build.props ├── Directory.Build.rsp ├── Directory.Build.targets ├── Directory.Packages.props ├── LICENSE.md ├── NuGet.config ├── README.md ├── SECURITY.md ├── System.CommandLine.sln ├── System.CommandLine.v3.ncrunchsolution ├── build.cmd ├── build.sh ├── core.slnf ├── docs ├── DragonFruit-overview.md ├── Functional-goals.md ├── History.md ├── Technical-motivations.md ├── Your-first-app-with-System-CommandLine-DragonFruit.md ├── dotnet-suggest.md ├── model-binding.md └── readme.md ├── eng ├── Build.props ├── DotNetBuild.props ├── Publishing.props ├── Version.Details.xml ├── Versions.props └── common │ ├── BuildConfiguration │ └── build-configuration.json │ ├── CIBuild.cmd │ ├── PSScriptAnalyzerSettings.psd1 │ ├── README.md │ ├── SetupNugetSources.ps1 │ ├── SetupNugetSources.sh │ ├── build.cmd │ ├── build.ps1 │ ├── build.sh │ ├── cibuild.sh │ ├── core-templates │ ├── job │ │ ├── job.yml │ │ ├── onelocbuild.yml │ │ ├── publish-build-assets.yml │ │ ├── source-build.yml │ │ └── source-index-stage1.yml │ ├── jobs │ │ ├── codeql-build.yml │ │ ├── jobs.yml │ │ └── source-build.yml │ ├── post-build │ │ ├── common-variables.yml │ │ ├── post-build.yml │ │ └── setup-maestro-vars.yml │ ├── steps │ │ ├── component-governance.yml │ │ ├── enable-internal-runtimes.yml │ │ ├── enable-internal-sources.yml │ │ ├── generate-sbom.yml │ │ ├── get-delegation-sas.yml │ │ ├── get-federated-access-token.yml │ │ ├── publish-build-artifacts.yml │ │ ├── publish-logs.yml │ │ ├── publish-pipeline-artifacts.yml │ │ ├── retain-build.yml │ │ ├── send-to-helix.yml │ │ └── source-build.yml │ └── variables │ │ └── pool-providers.yml │ ├── cross │ ├── arm │ │ └── tizen │ │ │ └── tizen.patch │ ├── arm64 │ │ └── tizen │ │ │ └── tizen.patch │ ├── armel │ │ ├── armel.jessie.patch │ │ └── tizen │ │ │ └── tizen.patch │ ├── build-android-rootfs.sh │ ├── build-rootfs.sh │ ├── riscv64 │ │ └── tizen │ │ │ └── tizen.patch │ ├── tizen-build-rootfs.sh │ ├── tizen-fetch.sh │ ├── toolchain.cmake │ └── x86 │ │ └── tizen │ │ └── tizen.patch │ ├── darc-init.ps1 │ ├── darc-init.sh │ ├── dotnet-install.cmd │ ├── dotnet-install.ps1 │ ├── dotnet-install.sh │ ├── enable-cross-org-publishing.ps1 │ ├── generate-locproject.ps1 │ ├── generate-sbom-prep.ps1 │ ├── generate-sbom-prep.sh │ ├── helixpublish.proj │ ├── init-tools-native.cmd │ ├── init-tools-native.ps1 │ ├── init-tools-native.sh │ ├── internal-feed-operations.ps1 │ ├── internal-feed-operations.sh │ ├── internal │ ├── Directory.Build.props │ ├── NuGet.config │ └── Tools.csproj │ ├── loc │ └── P22DotNetHtmlLocalization.lss │ ├── msbuild.ps1 │ ├── msbuild.sh │ ├── native │ ├── CommonLibrary.psm1 │ ├── common-library.sh │ ├── init-compiler.sh │ ├── init-distro-rid.sh │ ├── init-os-and-arch.sh │ ├── install-cmake-test.sh │ ├── install-cmake.sh │ └── install-tool.ps1 │ ├── pipeline-logging-functions.ps1 │ ├── pipeline-logging-functions.sh │ ├── post-build │ ├── check-channel-consistency.ps1 │ ├── nuget-validation.ps1 │ ├── nuget-verification.ps1 │ ├── publish-using-darc.ps1 │ ├── redact-logs.ps1 │ ├── sourcelink-validation.ps1 │ └── symbols-validation.ps1 │ ├── retain-build.ps1 │ ├── sdk-task.ps1 │ ├── sdl │ ├── NuGet.config │ ├── configure-sdl-tool.ps1 │ ├── execute-all-sdl-tools.ps1 │ ├── extract-artifact-archives.ps1 │ ├── extract-artifact-packages.ps1 │ ├── init-sdl.ps1 │ ├── packages.config │ ├── run-sdl.ps1 │ ├── sdl.ps1 │ └── trim-assets-version.ps1 │ ├── template-guidance.md │ ├── templates-official │ ├── job │ │ ├── job.yml │ │ ├── onelocbuild.yml │ │ ├── publish-build-assets.yml │ │ ├── source-build.yml │ │ └── source-index-stage1.yml │ ├── jobs │ │ ├── codeql-build.yml │ │ ├── jobs.yml │ │ └── source-build.yml │ ├── post-build │ │ ├── common-variables.yml │ │ ├── post-build.yml │ │ └── setup-maestro-vars.yml │ ├── steps │ │ ├── component-governance.yml │ │ ├── enable-internal-runtimes.yml │ │ ├── enable-internal-sources.yml │ │ ├── generate-sbom.yml │ │ ├── get-delegation-sas.yml │ │ ├── get-federated-access-token.yml │ │ ├── publish-build-artifacts.yml │ │ ├── publish-logs.yml │ │ ├── publish-pipeline-artifacts.yml │ │ ├── retain-build.yml │ │ ├── send-to-helix.yml │ │ └── source-build.yml │ └── variables │ │ ├── pool-providers.yml │ │ └── sdl-variables.yml │ ├── templates │ ├── job │ │ ├── job.yml │ │ ├── onelocbuild.yml │ │ ├── publish-build-assets.yml │ │ ├── source-build.yml │ │ └── source-index-stage1.yml │ ├── jobs │ │ ├── codeql-build.yml │ │ ├── jobs.yml │ │ └── source-build.yml │ ├── post-build │ │ ├── common-variables.yml │ │ ├── post-build.yml │ │ └── setup-maestro-vars.yml │ ├── steps │ │ ├── component-governance.yml │ │ ├── enable-internal-runtimes.yml │ │ ├── enable-internal-sources.yml │ │ ├── generate-sbom.yml │ │ ├── get-delegation-sas.yml │ │ ├── get-federated-access-token.yml │ │ ├── publish-build-artifacts.yml │ │ ├── publish-logs.yml │ │ ├── publish-pipeline-artifacts.yml │ │ ├── retain-build.yml │ │ ├── send-to-helix.yml │ │ └── source-build.yml │ └── variables │ │ └── pool-providers.yml │ ├── tools.ps1 │ └── tools.sh ├── global.json ├── repack.ps1 ├── samples ├── DragonFruit │ ├── Directory.Build.props │ ├── Directory.Build.targets │ ├── DragonFruit.csproj │ └── Program.cs ├── HostingPlayground │ ├── Greeter.cs │ ├── GreeterOptions.cs │ ├── HostingPlayground.csproj │ ├── HostingPlaygroundLogEvents.cs │ ├── IGreeter.cs │ ├── Program.cs │ └── appsettings.json └── RenderingPlayground │ ├── Colorizer.cs │ ├── ColorsView.cs │ ├── Directory.Build.props │ ├── Directory.Build.targets │ ├── DirectoryTableView.cs │ ├── ProcessesView.cs │ ├── Program.cs │ ├── RenderingPlayground.csproj │ └── SampleName.cs ├── sourcebuild.slnf └── src ├── Common ├── ArgumentBuilder.cs └── OptionBuilder.cs ├── System.CommandLine.ApiCompatibility.Tests ├── ApiCompatibilityApprovalTests.System_CommandLine_Hosting_api_is_not_changed.approved.txt ├── ApiCompatibilityApprovalTests.System_CommandLine_NamingConventionBinder_api_is_not_changed.approved.txt ├── ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt ├── ApiCompatibilityApprovalTests.cs ├── ApiContract.cs ├── Directory.Build.props ├── LocalizationTests.cs └── System.CommandLine.ApiCompatibility.Tests.csproj ├── System.CommandLine.Benchmarks ├── Categories.cs ├── CommandLine │ ├── Perf_Parser_CustomScenarios.cs │ ├── Perf_Parser_Directives_Suggest.cs │ ├── Perf_Parser_NestedCommands.cs │ ├── Perf_Parser_Options_Bare.cs │ ├── Perf_Parser_Options_With_Arguments.cs │ ├── Perf_Parser_ParseResult.cs │ ├── Perf_Parser_Simple.cs │ ├── Perf_Parser_TypoCorrection.cs │ └── Perf_Suggestions.cs ├── DragonFruit │ ├── Perf_CommandLine_EntryPoint.cs │ ├── Perf_CommandLine_Help.cs │ └── Perf_XmlDocReader.cs ├── Helpers │ ├── BdnParam.cs │ ├── NullStreamWriter.cs │ └── Utils.cs ├── Input │ └── Sample1.Main.cs ├── Program.cs ├── RecommendedConfig.cs ├── System.CommandLine.Benchmarks.csproj ├── System.CommandLine.Benchmarks.net5.0.v3.ncrunchproject └── System.CommandLine.Benchmarks.v3.ncrunchproject ├── System.CommandLine.DragonFruit.Tests ├── CommandLineTests.cs ├── ConfigureFromMethodTests.cs ├── EntryPointCreatorTests.cs ├── StringExtensionTests.cs ├── System.CommandLine.DragonFruit.Tests.csproj ├── TestProgram.cs └── XmlDocReaderTests.cs ├── System.CommandLine.DragonFruit ├── CommandHelpMetadata.cs ├── CommandLine.cs ├── Directory.Build.props ├── EntryPointDiscoverer.cs ├── StringExtensions.cs ├── System.CommandLine.DragonFruit.csproj ├── XmlDocReader.cs └── targets │ ├── System.CommandLine.DragonFruit.props │ └── System.CommandLine.DragonFruit.targets ├── System.CommandLine.Generator.CommandHandler ├── CommandExtensions.cs └── System.CommandLine.Generator.CommandHandler.csproj ├── System.CommandLine.Generator.Tests ├── Directory.Build.props ├── GeneratedCommandHandlerTests.cs └── System.CommandLine.Generator.Tests.csproj ├── System.CommandLine.Generator ├── CommandHandlerSourceGenerator.cs ├── Directory.Build.props ├── Invocations │ ├── ConstructorModelBindingInvocation.cs │ ├── DelegateInvocation.cs │ └── ReturnPattern.cs ├── Parameters │ ├── ArgumentParameter.cs │ ├── BindingContextParameter.cs │ ├── ConsoleParameter.cs │ ├── OptionParameter.cs │ ├── Parameter.cs │ ├── ParseResultParameter.cs │ ├── PropertyParameter.cs │ └── RawParameter.cs ├── SyntaxReceiver.cs ├── System.CommandLine.Generator.csproj └── WellKnownTypes.cs ├── System.CommandLine.Hosting.Tests ├── HostingHandlerTest.cs ├── HostingTests.cs └── System.CommandLine.Hosting.Tests.csproj ├── System.CommandLine.Hosting ├── Directory.Build.props ├── HostingAction.cs ├── HostingExtensions.cs ├── InvocationLifetime.cs ├── InvocationLifetimeOptions.cs └── System.CommandLine.Hosting.csproj ├── System.CommandLine.NamingConventionBinder.Tests ├── BindingTestCase.cs ├── BindingTestSet.cs ├── HandlerDescriptorTests.cs ├── ModelBinderTests.cs ├── ModelBindingCommandHandlerTests.BindingByName.cs ├── ModelBindingCommandHandlerTests.cs ├── ModelDescriptorTests.cs ├── ParameterBindingTests.cs ├── ParameterDescriptorTests.cs ├── PropertyDescriptorTests.cs └── System.CommandLine.NamingConventionBinder.Tests.csproj ├── System.CommandLine.NamingConventionBinder ├── BindingContext.cs ├── BindingContextExtensions.cs ├── BindingHandler.cs ├── BoundValue.cs ├── CommandHandler.cs ├── CommandResultExtensions.cs ├── ConstructorDescriptor.cs ├── DelegateHandlerDescriptor.cs ├── DelegateValueSource.cs ├── Directory.Build.props ├── ExpressionExtensions.cs ├── HandlerDescriptor.cs ├── IMethodDescriptor.cs ├── IValueDescriptor.cs ├── IValueSource.cs ├── MethodInfoHandlerDescriptor.cs ├── MissingValueSource.cs ├── ModelBinder.cs ├── ModelBinderCollection.cs ├── ModelBinder{T}.cs ├── ModelBindingCommandHandler.cs ├── ModelDescriptor.cs ├── ParameterDescriptor.cs ├── ParseResultMatchingValueSource.cs ├── PropertyDescriptor.cs ├── ServiceProvider.cs ├── ServiceProviderValueSource.cs ├── SpecificSymbolValueSource.cs ├── System.CommandLine.NamingConventionBinder.csproj ├── TypeExtensions.cs └── ValueDescriptorDefaultValueSource.cs ├── System.CommandLine.Rendering.Tests ├── AnsiControlCodeTests.cs ├── AnsiTests.cs ├── ConsoleFormatInfoTests.cs ├── ConsoleRendererTests.cs ├── ContainerSpanTests.cs ├── ControlSpanTests.cs ├── Example_TOP.cs ├── OutputFormattingTests.cs ├── RegionTests.cs ├── RenderingTestCase.cs ├── SizeTests.cs ├── System.CommandLine.Rendering.Tests.csproj ├── SystemConsoleTerminalTests.cs ├── TableRenderingTests.cs ├── TerminalModeTests.cs ├── TerminalTests.cs ├── TestTerminalTests.cs ├── TextSpanFormatterTests.cs ├── TextSpanTests.cs ├── TextSpanVisitorTests.cs ├── TextStyleRenderingTests.cs ├── ViewRenderingTests.cs ├── ViewWrappingTests.cs ├── Views │ ├── ColumnDefinitionTests.cs │ ├── ContentViewTests.cs │ ├── ContentView{T}Tests.cs │ ├── GridViewTests.cs │ ├── LayoutViewTests.cs │ ├── RowDefinitionTests.cs │ ├── ScreenViewTests.cs │ └── StackLayoutViewTests.cs ├── WordWrappingTests.cs └── WrappingExtensionsTests.cs ├── System.CommandLine.Rendering ├── Ansi.cs ├── AnsiControlCode.cs ├── AnsiRenderingSpanVisitor.cs ├── BackgroundColorSpan.cs ├── ColorSpan.cs ├── ConsoleExtensions.cs ├── ConsoleFormatInfo.cs ├── ConsoleRenderer.cs ├── ContainerSpan.cs ├── ContentRenderingSpanVisitor.cs ├── ContentSpan.cs ├── ControlSpan.cs ├── CursorControlSpan.cs ├── Directory.Build.props ├── EntireTerminalRegion.cs ├── FileRenderingSpanVisitor.cs ├── ForegroundColorSpan.cs ├── IConsole.cs ├── IO │ ├── IStandardError.cs │ ├── IStandardIn.cs │ ├── IStandardOut.cs │ ├── IStandardStreamWriter.cs │ ├── StandardStreamWriter.cs │ ├── SystemConsole.cs │ └── TestConsole.cs ├── IRenderable.cs ├── ITerminal.cs ├── Interop.Windows.cs ├── NonAnsiRenderingSpanVisitor.cs ├── OutputMode.cs ├── RecordingWriter.cs ├── Region.cs ├── RgbColor.cs ├── ScrollingTerminalRegion.cs ├── Size.cs ├── SpanMeasuringVisitor.cs ├── StringExtensions.cs ├── StyleSpan.cs ├── System.CommandLine.Rendering.csproj ├── SystemConsoleTerminal.cs ├── Terminal.cs ├── TerminalBase.cs ├── TestTerminal.cs ├── TextSpan.cs ├── TextSpanFormatter.cs ├── TextSpanVisitor.cs ├── Views │ ├── ColumnDefinition.cs │ ├── ContentView.cs │ ├── ContentView{T}.cs │ ├── GridView.cs │ ├── ItemsView.cs │ ├── LayoutView.cs │ ├── Orientation.cs │ ├── RowDefinition.cs │ ├── ScreenView.cs │ ├── SizeMode.cs │ ├── StackLayoutView.cs │ ├── TableView.cs │ ├── TableViewColumn.cs │ └── View.cs ├── VirtualTerminal.cs ├── VirtualTerminalMode.cs └── WrappingExtensions.cs ├── System.CommandLine.Suggest.Tests ├── DotnetSuggestEndToEndTests.cs ├── EndToEndTestApp │ ├── EndToEndTestApp.csproj │ └── Program.cs ├── FileEnumeratorTests.cs ├── FileSuggestionProviderTests.cs ├── GlobalToolsSuggestionRegistrationTests.cs ├── SuggestionDispatcherTests.cs ├── SuggestionRegistrationTest.cs ├── SuggestionShellScriptHandlerTest.cs ├── TestSuggestionRegistration.cs ├── TestSuggestionRegistrationTests.cs └── dotnet-suggest.Tests.csproj ├── System.CommandLine.Suggest ├── CombineSuggestionRegistration.cs ├── Directory.Build.props ├── DotnetMuxer.cs ├── DotnetProfileDirectory.cs ├── FileEnumerator.cs ├── FileSuggestionRegistration.cs ├── GlobalToolsSuggestionRegistration.cs ├── ISuggestionRegistration.cs ├── ISuggestionStore.cs ├── PathExtensions.cs ├── Program.cs ├── RegistrationPair.cs ├── ShellType.cs ├── StringExtensions.cs ├── SuggestionDispatcher.cs ├── SuggestionShellScriptException.cs ├── SuggestionShellScriptHandler.cs ├── SuggestionStore.cs ├── build-and-install.ps1 ├── dotnet-suggest-shim.bash ├── dotnet-suggest-shim.ps1 ├── dotnet-suggest-shim.zsh └── dotnet-suggest.csproj ├── System.CommandLine.Tests ├── ArgumentTests.cs ├── Binding │ ├── TestModels.cs │ └── TypeConversionTests.cs ├── CommandLineConfigurationTests.cs ├── CommandTests.cs ├── CompilationTests.cs ├── CompletionContextTests.cs ├── CompletionTests.cs ├── CustomParsingTests.cs ├── DirectiveTests.cs ├── Directory.Build.props ├── EnvironmentVariableDirectiveTests.cs ├── GetValueByNameParserTests.cs ├── GlobalOptionTests.cs ├── Help │ ├── ApprovalTests.Config.cs │ ├── Approvals │ │ └── HelpBuilderTests.Help_layout_has_not_changed.approved.txt │ ├── CustomHelpAction.cs │ ├── HelpBuilderExtensions.cs │ ├── HelpBuilderTests.Approval.cs │ ├── HelpBuilderTests.Customization.cs │ └── HelpBuilderTests.cs ├── HelpOptionTests.cs ├── Invocation │ ├── CancelOnProcessTerminationTests.cs │ ├── InvocationTests.cs │ └── TypoCorrectionTests.cs ├── OptionTests.MultipleArgumentsPerToken.cs ├── OptionTests.cs ├── ParseDiagramTests.cs ├── ParseDirectiveTests.cs ├── ParseErrorReportingTests.cs ├── ParseResultTests.cs ├── ParserTests.DoubleDash.cs ├── ParserTests.MultipleArguments.cs ├── ParserTests.MultiplePositions.cs ├── ParserTests.RootCommandAndArg0.cs ├── ParserTests.SetupErrors.cs ├── ParserTests.cs ├── Parsing │ └── CommandLineStringSplitterTests.cs ├── ParsingValidationTests.cs ├── ResponseFileTests.cs ├── RootCommandTests.cs ├── SplitCommandLineTests.cs ├── SuggestDirectiveTests.cs ├── System.CommandLine.Tests.csproj ├── TestApps │ ├── NativeAOT │ │ ├── NativeAOT.csproj │ │ └── Program.cs │ └── Trimming │ │ ├── Program.cs │ │ └── Trimming.csproj ├── TestCliActions.cs ├── TokenReplacementTests.cs ├── UseExceptionHandlerTests.cs ├── Utility │ ├── AssertionExtensions.cs │ ├── LinuxOnlyTheory.cs │ ├── NonWindowsOnlyFactAttribute.cs │ ├── ParseResultExtensions.cs │ ├── Process.cs │ ├── ReleaseBuildOnlyFactAttribute.cs │ ├── ReleaseBuildOnlyTheoryAttribute.cs │ ├── RemoteExecution.cs │ ├── RemoteExecutor.cs │ └── WindowsOnlyFactAttribute.cs └── VersionOptionTests.cs ├── System.CommandLine ├── AliasSet.cs ├── Argument.cs ├── ArgumentArity.cs ├── ArgumentValidation.cs ├── Argument{T}.cs ├── Binding │ ├── ArgumentConversionResult.cs │ ├── ArgumentConversionResultType.cs │ ├── ArgumentConverter.DefaultValues.cs │ ├── ArgumentConverter.StringConverters.cs │ ├── ArgumentConverter.cs │ ├── TryConvertArgument.cs │ └── TypeExtensions.cs ├── ChildSymbolList{T}.cs ├── Command.cs ├── CommandLineConfiguration.cs ├── CommandLineConfigurationException.cs ├── CompletionSourceExtensions.cs ├── Completions │ ├── CompletionAction.cs │ ├── CompletionContext.cs │ ├── CompletionItem.cs │ ├── SuggestDirective.cs │ └── TextCompletionContext.cs ├── ConsoleHelpers.cs ├── Directive.cs ├── Directory.Build.props ├── EnumerableExtensions.cs ├── EnvironmentVariablesDirective.cs ├── Help │ ├── HelpAction.cs │ ├── HelpBuilder.Default.cs │ ├── HelpBuilder.cs │ ├── HelpBuilderExtensions.cs │ ├── HelpContext.cs │ ├── HelpOption.cs │ └── TwoColumnHelpRow.cs ├── Invocation │ ├── AnonymousAsynchronousCommandLineAction.cs │ ├── AnonymousSynchronousCommandLineAction.cs │ ├── AsynchronousCommandLineAction.cs │ ├── CommandLineAction.cs │ ├── InvocationPipeline.cs │ ├── ParseErrorAction.cs │ ├── ProcessTerminationHandler.cs │ └── SynchronousCommandLineAction.cs ├── LocalizationResources.cs ├── Option.cs ├── OptionValidation.cs ├── Option{T}.cs ├── ParseDiagramDirective.cs ├── ParseResult.cs ├── Parsing │ ├── ArgumentResult.cs │ ├── CommandLineParser.cs │ ├── CommandResult.cs │ ├── DirectiveResult.cs │ ├── OptionResult.cs │ ├── ParseDiagramAction.cs │ ├── ParseError.cs │ ├── ParseOperation.cs │ ├── StringExtensions.cs │ ├── SymbolResult.cs │ ├── SymbolResultExtensions.cs │ ├── SymbolResultTree.cs │ ├── Token.cs │ ├── TokenType.cs │ └── TryReplaceToken.cs ├── Properties │ ├── Resources.Designer.cs │ ├── Resources.resx │ └── xlf │ │ ├── Resources.cs.xlf │ │ ├── Resources.de.xlf │ │ ├── Resources.es.xlf │ │ ├── Resources.fr.xlf │ │ ├── Resources.it.xlf │ │ ├── Resources.ja.xlf │ │ ├── Resources.ko.xlf │ │ ├── Resources.pl.xlf │ │ ├── Resources.pt-BR.xlf │ │ ├── Resources.ru.xlf │ │ ├── Resources.tr.xlf │ │ ├── Resources.zh-Hans.xlf │ │ └── Resources.zh-Hant.xlf ├── RootCommand.cs ├── Symbol.cs ├── SymbolNode.cs ├── System.CommandLine.Config.cs ├── System.CommandLine.csproj ├── System.Diagnostics.CodeAnalysis │ ├── DynamicallyAccessedMemberTypes.cs │ ├── DynamicallyAccessedMembersAttribute.cs │ └── UnconditionalSuppressMessageAttribute.cs ├── System.Runtime.CompilerServices │ └── IsExternalInit.cs └── VersionOption.cs └── System.Diagnostics.CodeAnalysis.cs /.config/tsaoptions.json: -------------------------------------------------------------------------------- 1 | { 2 | "instanceUrl": "https://devdiv.visualstudio.com/", 3 | "template": "TFSDEVDIV", 4 | "projectName": "DEVDIV", 5 | "areaPath": "DevDiv\\NET Libraries", 6 | "iterationPath": "DevDiv", 7 | "notificationAliases": [ "system-commandline@microsoft.com" ], 8 | "repositoryName":"command-line-api", 9 | "codebaseName": "command-line-api", 10 | "serviceTreeId": "7a9b52f6-7805-416c-9390-343168c0cdb3" 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*.{c,c++,cc,cp,cpp,cu,cuh,cxx,h,hh,hpp,hxx,inc,inl,ino,ipp,mpp,proto,tpp}] 3 | indent_style=tab 4 | indent_size=tab 5 | tab_width=4 6 | 7 | [*.{asax,ascx,aspx,cs,cshtml,css,htm,html,js,jsx,master,razor,skin,ts,tsx,vb,xaml,xamlx,xoml}] 8 | indent_style=space 9 | indent_size=4 10 | tab_width=4 11 | 12 | [*.{appxmanifest,build,config,csproj,dbml,discomap,dtd,json,jsproj,lsproj,njsproj,nuspec,proj,props,resjson,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}] 13 | indent_style=space 14 | indent_size=2 15 | tab_width=2 16 | 17 | [*] 18 | 19 | # Microsoft .NET properties 20 | csharp_new_line_before_members_in_object_initializers=false 21 | csharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion 22 | csharp_style_var_elsewhere=true:hint 23 | csharp_style_var_for_built_in_types=true:hint 24 | csharp_style_var_when_type_is_apparent=true:hint 25 | dotnet_style_predefined_type_for_locals_parameters_members=true:hint 26 | dotnet_style_predefined_type_for_member_access=true:hint 27 | dotnet_style_qualification_for_event=false:warning 28 | dotnet_style_qualification_for_field=false:warning 29 | dotnet_style_qualification_for_method=false:warning 30 | dotnet_style_qualification_for_property=false:warning 31 | dotnet_style_require_accessibility_modifiers=for_non_interface_members:hint 32 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | Please read [.NET Guidelines](https://github.com/dotnet/runtime/blob/master/CONTRIBUTING.md) for more general information about coding styles, source structure, making pull requests, and more. 5 | 6 | ## Developer guide 7 | 8 | This project can be developed on any platform. To get started, follow instructions for your OS. 9 | 10 | ### Prerequisites 11 | 12 | This project depends on .NET 7. Before working on the project, check that the [.NET SDK](https://dotnet.microsoft.com/en-us/download) is installed. 13 | 14 | ### Visual Studio 15 | 16 | This project supports [Visual Studio 2022](https://visualstudio.com). Any version, including the free Community Edition, should be sufficient. 17 | 18 | This project also supports using 19 | [Visual Studio Code](https://code.visualstudio.com). Install the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit). 20 | 21 | ### Command line scripts 22 | 23 | This project can be built on the command line using the `build.cmd`/`build.sh` scripts. 24 | 25 | Run `.\build.cmd -help` or `./build.sh --help` to see more options. 26 | 27 | ### Compile 28 | 29 | Windows: 30 | 31 | > .\build.cmd 32 | 33 | macOS/Linux 34 | 35 | $ ./build.sh 36 | 37 | ### Running tests 38 | 39 | To build **and** run tests: 40 | 41 | Windows: 42 | 43 | > .\build.cmd -test 44 | 45 | macOS/Linux: 46 | 47 | $ ./build.sh --test 48 | 49 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | $(NoWarn);NU5125;CS0618 9 | MIT 10 | 13.0 11 | https://github.com/dotnet/command-line-api 12 | 13 | 14 | 15 | $(NetCurrent) 16 | net8.0 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Directory.Build.rsp: -------------------------------------------------------------------------------- 1 | # This file intentionally left blank to avoid accidental import during build. 2 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | $(DefaultExcludesInProjectFolder);TestResults\** 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © .NET Foundation and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | The .NET Core and ASP.NET Core support policy, including supported versions can be found at the [.NET Core Support Policy Page](https://dotnet.microsoft.com/platform/support/policy/dotnet-core). 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Security issues and bugs should be reported privately to the Microsoft Security Response Center (MSRC), either by emailing secure@microsoft.com or via the portal at https://msrc.microsoft.com. 10 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your 11 | original message. Further information, including the MSRC PGP key, can be found in the [MSRC Report an Issue FAQ](https://www.microsoft.com/en-us/msrc/faqs-report-an-issue). 12 | 13 | Reports via MSRC may qualify for the .NET Core Bug Bounty. Details of the .NET Core Bug Bounty including terms and conditions are at [https://aka.ms/corebounty](https://aka.ms/corebounty). 14 | 15 | Please do not open issues for anything you think might have a security implication. -------------------------------------------------------------------------------- /System.CommandLine.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | 5 | TargetFrameworks = net8.0 6 | TargetFramework = net8.0 7 | 8 | False 9 | True 10 | True 11 | 12 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -NoLogo -NoProfile -ExecutionPolicy ByPass %~dp0eng\common\build.ps1 -build -restore %* 3 | exit /b %ErrorLevel% 4 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where the 11 | # symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | 15 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 16 | "$scriptroot/eng/common/build.sh" --build --restore $@ 17 | -------------------------------------------------------------------------------- /core.slnf: -------------------------------------------------------------------------------- 1 | { 2 | "solution": { 3 | "path": "System.CommandLine.sln", 4 | "projects": [ 5 | "src\\System.CommandLine.ApiCompatibility.Tests\\System.CommandLine.ApiCompatibility.Tests.csproj", 6 | "src\\System.CommandLine.DragonFruit\\System.CommandLine.DragonFruit.csproj", 7 | "src\\System.CommandLine.NamingConventionBinder.Tests\\System.CommandLine.NamingConventionBinder.Tests.csproj", 8 | "src\\System.CommandLine.NamingConventionBinder\\System.CommandLine.NamingConventionBinder.csproj", 9 | "src\\System.CommandLine.Tests\\System.CommandLine.Tests.csproj", 10 | "src\\System.CommandLine\\System.CommandLine.csproj" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /docs/dotnet-suggest.md: -------------------------------------------------------------------------------- 1 | # dotnet-suggest 2 | 3 | Command line apps built using `System.CommandLine` have built-in support for tab completion. 4 | 5 | ![t-rex-suggestions](https://user-images.githubusercontent.com/547415/50387753-ef4c1280-06b8-11e9-90c8-89466d0bb406.gif) 6 | 7 | On the machine where you'd like to enable completion, you'll need to do two things. 8 | 9 | 1. Install the `dotnet-suggest` global tool: 10 | 11 | ```sh 12 | dotnet tool install -g dotnet-suggest 13 | ``` 14 | 15 | 2. Install the completion script. 16 | 17 | ### bash 18 | ```sh 19 | dotnet-suggest script bash >~/.dotnet-suggest-shim.bash 20 | echo '. ~/.dotnet-suggest-shim.bash' >>~/.bashrc 21 | ``` 22 | 23 | ### zsh 24 | ```sh 25 | dotnet-suggest script zsh >~/.dotnet-suggest-shim.zsh 26 | echo '. ~/.dotnet-suggest-shim.zsh' >>~/.zshrc 27 | ``` 28 | 29 | ### PowerShell 30 | 31 | Add the contents of [dotnet-suggest-shim.ps1](https://github.com/dotnet/command-line-api/blob/master/src/System.CommandLine.Suggest/dotnet-suggest-shim.ps1) to your PowerShell profile. You can find the expected path to your PowerShell profile by running the following in your console: 32 | 33 | ```console 34 | > echo $profile 35 | ``` 36 | 37 | (For other shells, please [look for](https://github.com/dotnet/command-line-api/issues?q=is%3Aissue+is%3Aopen+label%3A%22shell+suggestion%22) or open an [issue](https://github.com/dotnet/command-line-api/issues).) 38 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | The System.CommandLine documentation can now be found at [Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/standard/commandline/). 2 | -------------------------------------------------------------------------------- /eng/Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /eng/DotNetBuild.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | command-line-api 7 | true 8 | $(DotNetBuildFromVMR) 9 | false 10 | false 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /eng/Publishing.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /eng/Version.Details.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | https://github.com/dotnet/arcade 9 | 086a1771875b63404b4a710d27250fe384dc2810 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /eng/Versions.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 0.1.0 6 | true 7 | 8 | 9 | 10 | 11 | false 12 | 13 | 14 | 2.0.0 15 | beta5 16 | false 17 | 18 | 19 | 0.4.0 20 | alpha 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /eng/common/BuildConfiguration/build-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "RetryCountLimit": 1, 3 | "RetryByAnyError": false 4 | } 5 | -------------------------------------------------------------------------------- /eng/common/CIBuild.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" -------------------------------------------------------------------------------- /eng/common/PSScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | IncludeRules=@('PSAvoidUsingCmdletAliases', 3 | 'PSAvoidUsingWMICmdlet', 4 | 'PSAvoidUsingPositionalParameters', 5 | 'PSAvoidUsingInvokeExpression', 6 | 'PSUseDeclaredVarsMoreThanAssignments', 7 | 'PSUseCmdletCorrectly', 8 | 'PSStandardDSCFunctionsInResource', 9 | 'PSUseIdenticalMandatoryParametersForDSC', 10 | 'PSUseIdenticalParametersForDSC') 11 | } -------------------------------------------------------------------------------- /eng/common/README.md: -------------------------------------------------------------------------------- 1 | # Don't touch this folder 2 | 3 | uuuuuuuuuuuuuuuuuuuu 4 | u" uuuuuuuuuuuuuuuuuu "u 5 | u" u$$$$$$$$$$$$$$$$$$$$u "u 6 | u" u$$$$$$$$$$$$$$$$$$$$$$$$u "u 7 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 8 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 9 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 10 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 11 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 12 | $ $$$" ... "$... ...$" ... "$$$ ... "$$$ $ 13 | $ $$$u `"$$$$$$$ $$$ $$$$$ $$ $$$ $$$ $ 14 | $ $$$$$$uu "$$$$ $$$ $$$$$ $$ """ u$$$ $ 15 | $ $$$""$$$ $$$$ $$$u "$$$" u$$ $$$$$$$$ $ 16 | $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $ 17 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 18 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 19 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 20 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 21 | "u "$$$$$$$$$$$$$$$$$$$$$$$$" u" 22 | "u "$$$$$$$$$$$$$$$$$$$$" u" 23 | "u """""""""""""""""" u" 24 | """""""""""""""""""" 25 | 26 | !!! Changes made in this directory are subject to being overwritten by automation !!! 27 | 28 | The files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first. 29 | -------------------------------------------------------------------------------- /eng/common/build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0build.ps1""" %*" 3 | exit /b %ErrorLevel% 4 | -------------------------------------------------------------------------------- /eng/common/cibuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 15 | 16 | . "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ -------------------------------------------------------------------------------- /eng/common/core-templates/jobs/codeql-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md 3 | continueOnError: false 4 | # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job 5 | jobs: [] 6 | # Optional: if specified, restore and use this version of Guardian instead of the default. 7 | overrideGuardianVersion: '' 8 | is1ESPipeline: '' 9 | 10 | jobs: 11 | - template: /eng/common/core-templates/jobs/jobs.yml 12 | parameters: 13 | is1ESPipeline: ${{ parameters.is1ESPipeline }} 14 | enableMicrobuild: false 15 | enablePublishBuildArtifacts: false 16 | enablePublishTestResults: false 17 | enablePublishBuildAssets: false 18 | enablePublishUsingPipelines: false 19 | enableTelemetry: true 20 | 21 | variables: 22 | - group: Publish-Build-Assets 23 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 24 | # sync with the packages.config file. 25 | - name: DefaultGuardianVersion 26 | value: 0.109.0 27 | - name: GuardianPackagesConfigFile 28 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config 29 | - name: GuardianVersion 30 | value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} 31 | 32 | jobs: ${{ parameters.jobs }} 33 | 34 | -------------------------------------------------------------------------------- /eng/common/core-templates/post-build/common-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | - group: Publish-Build-Assets 3 | 4 | # Whether the build is internal or not 5 | - name: IsInternalBuild 6 | value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} 7 | 8 | # Default Maestro++ API Endpoint and API Version 9 | - name: MaestroApiEndPoint 10 | value: "https://maestro.dot.net" 11 | - name: MaestroApiVersion 12 | value: "2020-02-20" 13 | 14 | - name: SourceLinkCLIVersion 15 | value: 3.0.0 16 | - name: SymbolToolVersion 17 | value: 1.0.1 18 | - name: BinlogToolVersion 19 | value: 1.0.11 20 | 21 | - name: runCodesignValidationInjection 22 | value: false 23 | -------------------------------------------------------------------------------- /eng/common/core-templates/steps/component-governance.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | disableComponentGovernance: false 3 | componentGovernanceIgnoreDirectories: '' 4 | is1ESPipeline: false 5 | displayName: 'Component Detection' 6 | 7 | steps: 8 | - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: 9 | - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" 10 | displayName: Set skipComponentGovernanceDetection variable 11 | - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: 12 | - task: ComponentGovernanceComponentDetection@0 13 | continueOnError: true 14 | displayName: ${{ parameters.displayName }} 15 | inputs: 16 | ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} 17 | -------------------------------------------------------------------------------- /eng/common/core-templates/steps/enable-internal-runtimes.yml: -------------------------------------------------------------------------------- 1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64' 2 | # variable with the base64-encoded SAS token, by default 3 | 4 | parameters: 5 | - name: federatedServiceConnection 6 | type: string 7 | default: 'dotnetbuilds-internal-read' 8 | - name: outputVariableName 9 | type: string 10 | default: 'dotnetbuilds-internal-container-read-token-base64' 11 | - name: expiryInHours 12 | type: number 13 | default: 1 14 | - name: base64Encode 15 | type: boolean 16 | default: true 17 | - name: is1ESPipeline 18 | type: boolean 19 | default: false 20 | 21 | steps: 22 | - ${{ if ne(variables['System.TeamProject'], 'public') }}: 23 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml 24 | parameters: 25 | federatedServiceConnection: ${{ parameters.federatedServiceConnection }} 26 | outputVariableName: ${{ parameters.outputVariableName }} 27 | expiryInHours: ${{ parameters.expiryInHours }} 28 | base64Encode: ${{ parameters.base64Encode }} 29 | storageAccount: dotnetbuilds 30 | container: internal 31 | permissions: rl 32 | is1ESPipeline: ${{ parameters.is1ESPipeline }} -------------------------------------------------------------------------------- /eng/common/core-templates/steps/publish-build-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: is1ESPipeline 3 | type: boolean 4 | default: false 5 | - name: args 6 | type: object 7 | default: {} 8 | steps: 9 | - ${{ if ne(parameters.is1ESPipeline, true) }}: 10 | - template: /eng/common/templates/steps/publish-build-artifacts.yml 11 | parameters: 12 | is1ESPipeline: ${{ parameters.is1ESPipeline }} 13 | ${{ each parameter in parameters.args }}: 14 | ${{ parameter.key }}: ${{ parameter.value }} 15 | - ${{ else }}: 16 | - template: /eng/common/templates-official/steps/publish-build-artifacts.yml 17 | parameters: 18 | is1ESPipeline: ${{ parameters.is1ESPipeline }} 19 | ${{ each parameter in parameters.args }}: 20 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/core-templates/steps/publish-pipeline-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: is1ESPipeline 3 | type: boolean 4 | default: false 5 | 6 | - name: args 7 | type: object 8 | default: {} 9 | 10 | steps: 11 | - ${{ if ne(parameters.is1ESPipeline, true) }}: 12 | - template: /eng/common/templates/steps/publish-pipeline-artifacts.yml 13 | parameters: 14 | ${{ each parameter in parameters }}: 15 | ${{ parameter.key }}: ${{ parameter.value }} 16 | - ${{ else }}: 17 | - template: /eng/common/templates-official/steps/publish-pipeline-artifacts.yml 18 | parameters: 19 | ${{ each parameter in parameters }}: 20 | ${{ parameter.key }}: ${{ parameter.value }} 21 | -------------------------------------------------------------------------------- /eng/common/core-templates/steps/retain-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # Optional azure devops PAT with build execute permissions for the build's organization, 3 | # only needed if the build that should be retained ran on a different organization than 4 | # the pipeline where this template is executing from 5 | Token: '' 6 | # Optional BuildId to retain, defaults to the current running build 7 | BuildId: '' 8 | # Azure devops Organization URI for the build in the https://dev.azure.com/ format. 9 | # Defaults to the organization the current pipeline is running on 10 | AzdoOrgUri: '$(System.CollectionUri)' 11 | # Azure devops project for the build. Defaults to the project the current pipeline is running on 12 | AzdoProject: '$(System.TeamProject)' 13 | 14 | steps: 15 | - task: powershell@2 16 | inputs: 17 | targetType: 'filePath' 18 | filePath: eng/common/retain-build.ps1 19 | pwsh: true 20 | arguments: > 21 | -AzdoOrgUri: ${{parameters.AzdoOrgUri}} 22 | -AzdoProject ${{parameters.AzdoProject}} 23 | -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} 24 | -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} 25 | displayName: Enable permanent build retention 26 | env: 27 | SYSTEM_ACCESSTOKEN: $(System.AccessToken) 28 | BUILD_ID: $(Build.BuildId) -------------------------------------------------------------------------------- /eng/common/core-templates/variables/pool-providers.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | is1ESPipeline: false 3 | 4 | variables: 5 | - ${{ if eq(parameters.is1ESPipeline, 'true') }}: 6 | - template: /eng/common/templates-official/variables/pool-providers.yml 7 | - ${{ else }}: 8 | - template: /eng/common/templates/variables/pool-providers.yml -------------------------------------------------------------------------------- /eng/common/cross/arm/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf32-littlearm) 8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-armhf.so.3 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/cross/arm64/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf64-littleaarch64) 8 | -GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/cross/armel/armel.jessie.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h 2 | --- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700 3 | +++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700 4 | @@ -69,10 +69,10 @@ 5 | #endif 6 | #ifdef UATOMIC_HAS_ATOMIC_SHORT 7 | case 2: 8 | - return __sync_val_compare_and_swap_2(addr, old, _new); 9 | + return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new); 10 | #endif 11 | case 4: 12 | - return __sync_val_compare_and_swap_4(addr, old, _new); 13 | + return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new); 14 | #if (CAA_BITS_PER_LONG == 64) 15 | case 8: 16 | return __sync_val_compare_and_swap_8(addr, old, _new); 17 | @@ -109,7 +109,7 @@ 18 | return; 19 | #endif 20 | case 4: 21 | - __sync_and_and_fetch_4(addr, val); 22 | + __sync_and_and_fetch_4((uint32_t*) addr, val); 23 | return; 24 | #if (CAA_BITS_PER_LONG == 64) 25 | case 8: 26 | @@ -148,7 +148,7 @@ 27 | return; 28 | #endif 29 | case 4: 30 | - __sync_or_and_fetch_4(addr, val); 31 | + __sync_or_and_fetch_4((uint32_t*) addr, val); 32 | return; 33 | #if (CAA_BITS_PER_LONG == 64) 34 | case 8: 35 | @@ -187,7 +187,7 @@ 36 | return __sync_add_and_fetch_2(addr, val); 37 | #endif 38 | case 4: 39 | - return __sync_add_and_fetch_4(addr, val); 40 | + return __sync_add_and_fetch_4((uint32_t*) addr, val); 41 | #if (CAA_BITS_PER_LONG == 64) 42 | case 8: 43 | return __sync_add_and_fetch_8(addr, val); 44 | -------------------------------------------------------------------------------- /eng/common/cross/armel/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf32-littlearm) 8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/cross/riscv64/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf64-littleriscv) 8 | -GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-riscv64-lp64d.so.1 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-riscv64-lp64d.so.1 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/cross/x86/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf32-i386) 8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.2 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/dotnet-install.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*" -------------------------------------------------------------------------------- /eng/common/dotnet-install.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(PositionalBinding=$false)] 2 | Param( 3 | [string] $verbosity = 'minimal', 4 | [string] $architecture = '', 5 | [string] $version = 'Latest', 6 | [string] $runtime = 'dotnet', 7 | [string] $RuntimeSourceFeed = '', 8 | [string] $RuntimeSourceFeedKey = '' 9 | ) 10 | 11 | . $PSScriptRoot\tools.ps1 12 | 13 | $dotnetRoot = Join-Path $RepoRoot '.dotnet' 14 | 15 | $installdir = $dotnetRoot 16 | try { 17 | if ($architecture -and $architecture.Trim() -eq 'x86') { 18 | $installdir = Join-Path $installdir 'x86' 19 | } 20 | InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey 21 | } 22 | catch { 23 | Write-Host $_.ScriptStackTrace 24 | Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ 25 | ExitWithExitCode 1 26 | } 27 | 28 | ExitWithExitCode 0 29 | -------------------------------------------------------------------------------- /eng/common/enable-cross-org-publishing.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string] $token 3 | ) 4 | 5 | 6 | . $PSScriptRoot\pipeline-logging-functions.ps1 7 | 8 | # Write-PipelineSetVariable will no-op if a variable named $ci is not defined 9 | # Since this script is only ever called in AzDO builds, just universally set it 10 | $ci = $true 11 | 12 | Write-PipelineSetVariable -Name 'VSS_NUGET_ACCESSTOKEN' -Value $token -IsMultiJobVariable $false 13 | Write-PipelineSetVariable -Name 'VSS_NUGET_URI_PREFIXES' -Value 'https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/' -IsMultiJobVariable $false 14 | -------------------------------------------------------------------------------- /eng/common/generate-sbom-prep.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory=$true)][string] $ManifestDirPath # Manifest directory where sbom will be placed 3 | ) 4 | 5 | . $PSScriptRoot\pipeline-logging-functions.ps1 6 | 7 | # Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly 8 | # with their own overwriting ours. So we create it as a sub directory of the requested manifest path. 9 | $ArtifactName = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM" 10 | $SafeArtifactName = $ArtifactName -replace '["/:<>\\|?@*"() ]', '_' 11 | $SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName 12 | 13 | Write-Host "Artifact name before : $ArtifactName" 14 | Write-Host "Artifact name after : $SafeArtifactName" 15 | 16 | Write-Host "Creating dir $ManifestDirPath" 17 | 18 | # create directory for sbom manifest to be placed 19 | if (!(Test-Path -path $SbomGenerationDir)) 20 | { 21 | New-Item -ItemType Directory -path $SbomGenerationDir 22 | Write-Host "Successfully created directory $SbomGenerationDir" 23 | } 24 | else{ 25 | Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." 26 | } 27 | 28 | Write-Host "Updating artifact name" 29 | Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName" 30 | -------------------------------------------------------------------------------- /eng/common/helixpublish.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | msbuild 6 | 7 | 8 | 9 | 10 | %(Identity) 11 | 12 | 13 | 14 | 15 | 16 | $(WorkItemDirectory) 17 | $(WorkItemCommand) 18 | $(WorkItemTimeout) 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /eng/common/init-tools-native.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*" 3 | exit /b %ErrorLevel% -------------------------------------------------------------------------------- /eng/common/internal/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | false 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /eng/common/internal/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /eng/common/msbuild.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(PositionalBinding=$false)] 2 | Param( 3 | [string] $verbosity = 'minimal', 4 | [bool] $warnAsError = $true, 5 | [bool] $nodeReuse = $true, 6 | [switch] $ci, 7 | [switch] $prepareMachine, 8 | [switch] $excludePrereleaseVS, 9 | [string] $msbuildEngine = $null, 10 | [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs 11 | ) 12 | 13 | . $PSScriptRoot\tools.ps1 14 | 15 | try { 16 | if ($ci) { 17 | $nodeReuse = $false 18 | } 19 | 20 | MSBuild @extraArgs 21 | } 22 | catch { 23 | Write-Host $_.ScriptStackTrace 24 | Write-PipelineTelemetryError -Category 'Build' -Message $_ 25 | ExitWithExitCode 1 26 | } 27 | 28 | ExitWithExitCode 0 -------------------------------------------------------------------------------- /eng/common/msbuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $source until the file is no longer a symlink 6 | while [[ -h "$source" ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | # if $source was a relative symlink, we need to resolve it relative to the path where the 10 | # symlink file was located 11 | [[ $source != /* ]] && source="$scriptroot/$source" 12 | done 13 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 14 | 15 | verbosity='minimal' 16 | warn_as_error=true 17 | node_reuse=true 18 | prepare_machine=false 19 | extra_args='' 20 | 21 | while (($# > 0)); do 22 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" 23 | case $lowerI in 24 | --verbosity) 25 | verbosity=$2 26 | shift 2 27 | ;; 28 | --warnaserror) 29 | warn_as_error=$2 30 | shift 2 31 | ;; 32 | --nodereuse) 33 | node_reuse=$2 34 | shift 2 35 | ;; 36 | --ci) 37 | ci=true 38 | shift 1 39 | ;; 40 | --preparemachine) 41 | prepare_machine=true 42 | shift 1 43 | ;; 44 | *) 45 | extra_args="$extra_args $1" 46 | shift 1 47 | ;; 48 | esac 49 | done 50 | 51 | . "$scriptroot/tools.sh" 52 | 53 | if [[ "$ci" == true ]]; then 54 | node_reuse=false 55 | fi 56 | 57 | MSBuild $extra_args 58 | ExitWithExitCode 0 59 | -------------------------------------------------------------------------------- /eng/common/post-build/nuget-validation.ps1: -------------------------------------------------------------------------------- 1 | # This script validates NuGet package metadata information using this 2 | # tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage 3 | 4 | param( 5 | [Parameter(Mandatory=$true)][string] $PackagesPath # Path to where the packages to be validated are 6 | ) 7 | 8 | # `tools.ps1` checks $ci to perform some actions. Since the post-build 9 | # scripts don't necessarily execute in the same agent that run the 10 | # build.ps1/sh script this variable isn't automatically set. 11 | $ci = $true 12 | $disableConfigureToolsetImport = $true 13 | . $PSScriptRoot\..\tools.ps1 14 | 15 | try { 16 | & $PSScriptRoot\nuget-verification.ps1 ${PackagesPath}\*.nupkg 17 | } 18 | catch { 19 | Write-Host $_.ScriptStackTrace 20 | Write-PipelineTelemetryError -Category 'NuGetValidation' -Message $_ 21 | ExitWithExitCode 1 22 | } 23 | -------------------------------------------------------------------------------- /eng/common/retain-build.ps1: -------------------------------------------------------------------------------- 1 | 2 | Param( 3 | [Parameter(Mandatory=$true)][int] $buildId, 4 | [Parameter(Mandatory=$true)][string] $azdoOrgUri, 5 | [Parameter(Mandatory=$true)][string] $azdoProject, 6 | [Parameter(Mandatory=$true)][string] $token 7 | ) 8 | 9 | $ErrorActionPreference = 'Stop' 10 | Set-StrictMode -Version 2.0 11 | 12 | function Get-AzDOHeaders( 13 | [string] $token) 14 | { 15 | $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":${token}")) 16 | $headers = @{"Authorization"="Basic $base64AuthInfo"} 17 | return $headers 18 | } 19 | 20 | function Update-BuildRetention( 21 | [string] $azdoOrgUri, 22 | [string] $azdoProject, 23 | [int] $buildId, 24 | [string] $token) 25 | { 26 | $headers = Get-AzDOHeaders -token $token 27 | $requestBody = "{ 28 | `"keepForever`": `"true`" 29 | }" 30 | 31 | $requestUri = "${azdoOrgUri}/${azdoProject}/_apis/build/builds/${buildId}?api-version=6.0" 32 | write-Host "Attempting to retain build using the following URI: ${requestUri} ..." 33 | 34 | try { 35 | Invoke-RestMethod -Uri $requestUri -Method Patch -Body $requestBody -Header $headers -contentType "application/json" 36 | Write-Host "Updated retention settings for build ${buildId}." 37 | } 38 | catch { 39 | Write-Error "Failed to update retention settings for build: $_.Exception.Response.StatusDescription" 40 | exit 1 41 | } 42 | } 43 | 44 | Update-BuildRetention -azdoOrgUri $azdoOrgUri -azdoProject $azdoProject -buildId $buildId -token $token 45 | exit 0 46 | -------------------------------------------------------------------------------- /eng/common/sdl/NuGet.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /eng/common/sdl/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /eng/common/sdl/sdl.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Install-Gdn { 3 | param( 4 | [Parameter(Mandatory=$true)] 5 | [string]$Path, 6 | 7 | # If omitted, install the latest version of Guardian, otherwise install that specific version. 8 | [string]$Version 9 | ) 10 | 11 | $ErrorActionPreference = 'Stop' 12 | Set-StrictMode -Version 2.0 13 | $disableConfigureToolsetImport = $true 14 | $global:LASTEXITCODE = 0 15 | 16 | # `tools.ps1` checks $ci to perform some actions. Since the SDL 17 | # scripts don't necessarily execute in the same agent that run the 18 | # build.ps1/sh script this variable isn't automatically set. 19 | $ci = $true 20 | . $PSScriptRoot\..\tools.ps1 21 | 22 | $argumentList = @("install", "Microsoft.Guardian.Cli", "-Source https://securitytools.pkgs.visualstudio.com/_packaging/Guardian/nuget/v3/index.json", "-OutputDirectory $Path", "-NonInteractive", "-NoCache") 23 | 24 | if ($Version) { 25 | $argumentList += "-Version $Version" 26 | } 27 | 28 | Start-Process nuget -Verbose -ArgumentList $argumentList -NoNewWindow -Wait 29 | 30 | $gdnCliPath = Get-ChildItem -Filter guardian.cmd -Recurse -Path $Path 31 | 32 | if (!$gdnCliPath) 33 | { 34 | Write-PipelineTelemetryError -Category 'Sdl' -Message 'Failure installing Guardian' 35 | } 36 | 37 | return $gdnCliPath.FullName 38 | } -------------------------------------------------------------------------------- /eng/common/templates-official/job/onelocbuild.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/onelocbuild.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/job/publish-build-assets.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/publish-build-assets.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/job/source-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/source-build.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/job/source-index-stage1.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/source-index-stage1.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/jobs/codeql-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/codeql-build.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/jobs/jobs.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/jobs.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/jobs/source-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/source-build.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates-official/post-build/common-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | - template: /eng/common/core-templates/post-build/common-variables.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: true 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates-official/post-build/post-build.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - template: /eng/common/core-templates/post-build/post-build.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: true 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} 9 | -------------------------------------------------------------------------------- /eng/common/templates-official/post-build/setup-maestro-vars.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: true 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates-official/steps/component-governance.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/component-governance.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/enable-internal-runtimes.yml: -------------------------------------------------------------------------------- 1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64' 2 | # variable with the base64-encoded SAS token, by default 3 | steps: 4 | - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml 5 | parameters: 6 | is1ESPipeline: true 7 | 8 | ${{ each parameter in parameters }}: 9 | ${{ parameter.key }}: ${{ parameter.value }} 10 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/enable-internal-sources.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/enable-internal-sources.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates-official/steps/generate-sbom.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/generate-sbom.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/get-delegation-sas.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/get-federated-access-token.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/get-federated-access-token.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates-official/steps/publish-build-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: displayName 3 | type: string 4 | default: 'Publish to Build Artifact' 5 | 6 | - name: condition 7 | type: string 8 | default: succeeded() 9 | 10 | - name: artifactName 11 | type: string 12 | 13 | - name: pathToPublish 14 | type: string 15 | 16 | - name: continueOnError 17 | type: boolean 18 | default: false 19 | 20 | - name: publishLocation 21 | type: string 22 | default: 'Container' 23 | 24 | - name: is1ESPipeline 25 | type: boolean 26 | default: true 27 | 28 | steps: 29 | - ${{ if ne(parameters.is1ESPipeline, true) }}: 30 | - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error 31 | - task: 1ES.PublishBuildArtifacts@1 32 | displayName: ${{ parameters.displayName }} 33 | condition: ${{ parameters.condition }} 34 | ${{ if parameters.continueOnError }}: 35 | continueOnError: ${{ parameters.continueOnError }} 36 | inputs: 37 | PublishLocation: ${{ parameters.publishLocation }} 38 | PathtoPublish: ${{ parameters.pathToPublish }} 39 | ${{ if parameters.artifactName }}: 40 | ArtifactName: ${{ parameters.artifactName }} 41 | 42 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/publish-logs.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/publish-logs.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/publish-pipeline-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: is1ESPipeline 3 | type: boolean 4 | default: true 5 | 6 | - name: args 7 | type: object 8 | default: {} 9 | 10 | steps: 11 | - ${{ if ne(parameters.is1ESPipeline, true) }}: 12 | - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error 13 | - task: 1ES.PublishPipelineArtifact@1 14 | displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} 15 | ${{ if parameters.args.condition }}: 16 | condition: ${{ parameters.args.condition }} 17 | ${{ else }}: 18 | condition: succeeded() 19 | ${{ if parameters.args.continueOnError }}: 20 | continueOnError: ${{ parameters.args.continueOnError }} 21 | inputs: 22 | targetPath: ${{ parameters.args.targetPath }} 23 | ${{ if parameters.args.artifactName }}: 24 | artifactName: ${{ parameters.args.artifactName }} 25 | ${{ if parameters.args.properties }}: 26 | properties: ${{ parameters.args.properties }} 27 | ${{ if parameters.args.sbomEnabled }}: 28 | sbomEnabled: ${{ parameters.args.sbomEnabled }} 29 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/retain-build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/retain-build.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/send-to-helix.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/send-to-helix.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/source-build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/source-build.yml 3 | parameters: 4 | is1ESPipeline: true 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates-official/variables/sdl-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 3 | # sync with the packages.config file. 4 | - name: DefaultGuardianVersion 5 | value: 0.109.0 6 | - name: GuardianPackagesConfigFile 7 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config -------------------------------------------------------------------------------- /eng/common/templates/job/onelocbuild.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/onelocbuild.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/job/publish-build-assets.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/publish-build-assets.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/job/source-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/source-build.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/job/source-index-stage1.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/job/source-index-stage1.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/jobs/codeql-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/codeql-build.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/jobs/jobs.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/jobs.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/jobs/source-build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - template: /eng/common/core-templates/jobs/source-build.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/post-build/common-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | - template: /eng/common/core-templates/post-build/common-variables.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: false 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/post-build/post-build.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - template: /eng/common/core-templates/post-build/post-build.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: false 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/post-build/setup-maestro-vars.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml 3 | parameters: 4 | # Specifies whether to use 1ES 5 | is1ESPipeline: false 6 | 7 | ${{ each parameter in parameters }}: 8 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/steps/component-governance.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/component-governance.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/enable-internal-runtimes.yml: -------------------------------------------------------------------------------- 1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64' 2 | # variable with the base64-encoded SAS token, by default 3 | 4 | steps: 5 | - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml 6 | parameters: 7 | is1ESPipeline: false 8 | 9 | ${{ each parameter in parameters }}: 10 | ${{ parameter.key }}: ${{ parameter.value }} 11 | -------------------------------------------------------------------------------- /eng/common/templates/steps/enable-internal-sources.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/enable-internal-sources.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/steps/generate-sbom.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/generate-sbom.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/get-delegation-sas.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/get-federated-access-token.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/get-federated-access-token.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} -------------------------------------------------------------------------------- /eng/common/templates/steps/publish-build-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: is1ESPipeline 3 | type: boolean 4 | default: false 5 | 6 | - name: displayName 7 | type: string 8 | default: 'Publish to Build Artifact' 9 | 10 | - name: condition 11 | type: string 12 | default: succeeded() 13 | 14 | - name: artifactName 15 | type: string 16 | 17 | - name: pathToPublish 18 | type: string 19 | 20 | - name: continueOnError 21 | type: boolean 22 | default: false 23 | 24 | - name: publishLocation 25 | type: string 26 | default: 'Container' 27 | 28 | steps: 29 | - ${{ if eq(parameters.is1ESPipeline, true) }}: 30 | - 'eng/common/templates cannot be referenced from a 1ES managed template': error 31 | - task: PublishBuildArtifacts@1 32 | displayName: ${{ parameters.displayName }} 33 | condition: ${{ parameters.condition }} 34 | ${{ if parameters.continueOnError }}: 35 | continueOnError: ${{ parameters.continueOnError }} 36 | inputs: 37 | PublishLocation: ${{ parameters.publishLocation }} 38 | PathtoPublish: ${{ parameters.pathToPublish }} 39 | ${{ if parameters.artifactName }}: 40 | ArtifactName: ${{ parameters.artifactName }} -------------------------------------------------------------------------------- /eng/common/templates/steps/publish-logs.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/publish-logs.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/publish-pipeline-artifacts.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: is1ESPipeline 3 | type: boolean 4 | default: false 5 | 6 | - name: args 7 | type: object 8 | default: {} 9 | 10 | steps: 11 | - ${{ if eq(parameters.is1ESPipeline, true) }}: 12 | - 'eng/common/templates cannot be referenced from a 1ES managed template': error 13 | - task: PublishPipelineArtifact@1 14 | displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} 15 | ${{ if parameters.args.condition }}: 16 | condition: ${{ parameters.args.condition }} 17 | ${{ else }}: 18 | condition: succeeded() 19 | ${{ if parameters.args.continueOnError }}: 20 | continueOnError: ${{ parameters.args.continueOnError }} 21 | inputs: 22 | targetPath: ${{ parameters.args.targetPath }} 23 | ${{ if parameters.args.artifactName }}: 24 | artifactName: ${{ parameters.args.artifactName }} 25 | ${{ if parameters.args.publishLocation }}: 26 | publishLocation: ${{ parameters.args.publishLocation }} 27 | ${{ if parameters.args.fileSharePath }}: 28 | fileSharePath: ${{ parameters.args.fileSharePath }} 29 | ${{ if parameters.args.Parallel }}: 30 | parallel: ${{ parameters.args.Parallel }} 31 | ${{ if parameters.args.parallelCount }}: 32 | parallelCount: ${{ parameters.args.parallelCount }} 33 | ${{ if parameters.args.properties }}: 34 | properties: ${{ parameters.args.properties }} -------------------------------------------------------------------------------- /eng/common/templates/steps/retain-build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/retain-build.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/send-to-helix.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/send-to-helix.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/source-build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /eng/common/core-templates/steps/source-build.yml 3 | parameters: 4 | is1ESPipeline: false 5 | 6 | ${{ each parameter in parameters }}: 7 | ${{ parameter.key }}: ${{ parameter.value }} 8 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "tools": { 3 | "dotnet": "9.0.106", 4 | "runtimes": { 5 | "dotnet": [ 6 | "8.0.12" 7 | ] 8 | } 9 | }, 10 | "msbuild-sdks": { 11 | "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25271.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /repack.ps1: -------------------------------------------------------------------------------- 1 | 2 | # clean up the previously-cached NuGet packages 3 | Remove-Item -Recurse ~\.nuget\packages\System.CommandLine* -Force 4 | 5 | # build and pack dotnet-interactive 6 | dotnet clean 7 | dotnet pack /p:PackageVersion=2.0.0-dev 8 | 9 | # copy the dotnet-interactive packages to the temp directory 10 | Get-ChildItem -Recurse -Filter *.nupkg | Copy-Item -Destination c:\temp -Force 11 | 12 | -------------------------------------------------------------------------------- /samples/DragonFruit/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/DragonFruit/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/DragonFruit/DragonFruit.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | $(TargetFrameworkForNETSDK) 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /samples/DragonFruit/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace DragonFruit 7 | { 8 | class Program 9 | { 10 | /// 11 | /// DragonFruit simple example program 12 | /// 13 | /// Show verbose output 14 | /// Which flavor to use 15 | /// How many smoothies? 16 | static int Main( 17 | bool verbose, 18 | string flavor = "chocolate", 19 | int count = 1) 20 | { 21 | if (verbose) 22 | { 23 | Console.WriteLine("Running in verbose mode"); 24 | } 25 | Console.WriteLine($"Creating {count} banana {(count == 1 ? "smoothie" : "smoothies")} with {flavor}"); 26 | return 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/HostingPlayground/Greeter.cs: -------------------------------------------------------------------------------- 1 | namespace HostingPlayground 2 | { 3 | public class Greeter : IGreeter 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /samples/HostingPlayground/GreeterOptions.cs: -------------------------------------------------------------------------------- 1 | namespace HostingPlayground 2 | { 3 | public class GreeterOptions 4 | { 5 | public string Name { get; } 6 | 7 | public GreeterOptions(string name) 8 | { 9 | Name = name; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/HostingPlayground/HostingPlayground.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | $(TargetFrameworkForNETSDK) 6 | true 7 | $(NoWarn);CS1591 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /samples/HostingPlayground/HostingPlaygroundLogEvents.cs: -------------------------------------------------------------------------------- 1 | namespace HostingPlayground 2 | { 3 | public class HostingPlaygroundLogEvents 4 | { 5 | public const int GreetEvent = 1000; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /samples/HostingPlayground/IGreeter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HostingPlayground 4 | { 5 | interface IGreeter 6 | { 7 | void Greet(string name) => Console.WriteLine($"Hello, {name ?? "anonymous"}"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/HostingPlayground/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/Colorizer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Rendering; 5 | 6 | namespace RenderingPlayground 7 | { 8 | internal static class Colorizer 9 | { 10 | public static TextSpan Underline(this string value) => 11 | new ContainerSpan(StyleSpan.UnderlinedOn(), 12 | new ContentSpan(value), 13 | StyleSpan.UnderlinedOff()); 14 | 15 | 16 | public static TextSpan Rgb(this string value, byte r, byte g, byte b) => 17 | new ContainerSpan(ForegroundColorSpan.Rgb(r, g, b), 18 | new ContentSpan(value), 19 | ForegroundColorSpan.Reset()); 20 | 21 | public static TextSpan LightGreen(this string value) => 22 | new ContainerSpan(ForegroundColorSpan.LightGreen(), 23 | new ContentSpan(value), 24 | ForegroundColorSpan.Reset()); 25 | 26 | public static TextSpan White(this string value) => 27 | new ContainerSpan(ForegroundColorSpan.White(), 28 | new ContentSpan(value), 29 | ForegroundColorSpan.Reset()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/ColorsView.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Rendering; 2 | using System.CommandLine.Rendering.Views; 3 | 4 | namespace RenderingPlayground 5 | { 6 | internal class ColorsView : View 7 | { 8 | public ColorsView(string text) 9 | { 10 | Text = text; 11 | } 12 | 13 | private string Text { get; } 14 | 15 | public override Size Measure(ConsoleRenderer renderer, Size maxSize) => maxSize; 16 | 17 | public override void Render(ConsoleRenderer renderer, Region region) 18 | { 19 | byte r = 0; 20 | byte g = 0; 21 | byte b = 0; 22 | 23 | var i = 0; 24 | 25 | for (var x = 0; x < region.Width; x++) 26 | for (var y = 0; y < region.Height; y++) 27 | { 28 | if (i >= Text.Length - 1) 29 | { 30 | i = 0; 31 | } 32 | else 33 | { 34 | i++; 35 | } 36 | 37 | var subregion = new Region( 38 | region.Left + x, 39 | region.Top + y, 40 | 1, 41 | 1); 42 | 43 | unchecked 44 | { 45 | renderer.RenderToRegion( 46 | $"{ForegroundColorSpan.Rgb(r += 2, g += 3, b += 5)}{Text[i]}{ForegroundColorSpan.Reset()}", 47 | subregion); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/RenderingPlayground.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | $(TargetFrameworkForNETSDK) 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /samples/RenderingPlayground/SampleName.cs: -------------------------------------------------------------------------------- 1 | namespace RenderingPlayground 2 | { 3 | internal enum SampleName 4 | { 5 | Colors, 6 | Dir, 7 | Moby, 8 | Processes, 9 | TableView, 10 | Clock, 11 | GridLayout, 12 | Cursor, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sourcebuild.slnf: -------------------------------------------------------------------------------- 1 | { 2 | "solution": { 3 | "path": "System.CommandLine.sln", 4 | "projects": [ 5 | "src\\System.CommandLine\\System.CommandLine.csproj", 6 | "src\\System.CommandLine.DragonFruit\\System.CommandLine.DragonFruit.csproj", 7 | "src\\System.CommandLine.NamingConventionBinder\\System.CommandLine.NamingConventionBinder.csproj", 8 | "src\\System.CommandLine.Rendering\\System.CommandLine.Rendering.csproj" 9 | ] 10 | } 11 | } -------------------------------------------------------------------------------- /src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Hosting; 5 | using System.CommandLine.NamingConventionBinder; 6 | using ApprovalTests; 7 | using ApprovalTests.Reporters; 8 | using Xunit; 9 | 10 | namespace System.CommandLine.ApiCompatibility.Tests; 11 | 12 | public class ApiCompatibilityApprovalTests 13 | { 14 | [Fact] 15 | [UseReporter(typeof(DiffReporter))] 16 | public void System_CommandLine_api_is_not_changed() 17 | { 18 | var contract = ApiContract.GenerateContractForAssembly(typeof(ParseResult).Assembly); 19 | Approvals.Verify(contract); 20 | } 21 | 22 | [Fact] 23 | [UseReporter(typeof(DiffReporter))] 24 | public void System_CommandLine_Hosting_api_is_not_changed() 25 | { 26 | var contract = ApiContract.GenerateContractForAssembly(typeof(HostingExtensions).Assembly); 27 | Approvals.Verify(contract); 28 | } 29 | 30 | [Fact] 31 | [UseReporter(typeof(DiffReporter))] 32 | public void System_CommandLine_NamingConventionBinder_api_is_not_changed() 33 | { 34 | var contract = ApiContract.GenerateContractForAssembly(typeof(ModelBindingCommandHandler).Assembly); 35 | Approvals.Verify(contract); 36 | } 37 | } -------------------------------------------------------------------------------- /src/System.CommandLine.ApiCompatibility.Tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | IDE1006 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.ApiCompatibility.Tests/LocalizationTests.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Linq; 3 | using Xunit; 4 | 5 | namespace System.CommandLine.ApiCompatibility.Tests 6 | { 7 | public class LocalizationTests 8 | { 9 | private const string CommandName = "the-command"; 10 | 11 | [Theory] 12 | [InlineData("es", $"Falta el argumento requerido para el comando: '{CommandName}'.")] 13 | [InlineData("en-US", $"Required argument missing for command: '{CommandName}'.")] 14 | public void ErrorMessages_AreLocalized(string cultureName, string expectedMessage) 15 | { 16 | CultureInfo uiCultureBefore = CultureInfo.CurrentUICulture; 17 | 18 | try 19 | { 20 | CultureInfo.CurrentUICulture = new CultureInfo(cultureName); 21 | 22 | Command command = new(CommandName) 23 | { 24 | new Argument("arg") 25 | }; 26 | 27 | ParseResult parseResult = command.Parse(CommandName); 28 | 29 | Assert.Equal(expectedMessage, parseResult.Errors.Single().Message); 30 | } 31 | finally 32 | { 33 | CultureInfo.CurrentUICulture = uiCultureBefore; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/System.CommandLine.ApiCompatibility.Tests/System.CommandLine.ApiCompatibility.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK) 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/Categories.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Benchmarks 5 | { 6 | public static class Categories 7 | { 8 | public const string CommandLine = "CommandLine"; 9 | public const string DragonFruit = "DragonFruit"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/Helpers/BdnParam.cs: -------------------------------------------------------------------------------- 1 | namespace System.CommandLine.Benchmarks.Helpers 2 | { 3 | /// 4 | /// Wraps instance of type and 5 | /// returns a separately provided comment to the instance when DotnetBenchmark logs results. 6 | /// 7 | /// 8 | /// The purpose of this wrapper is to increase the readability of DotnetBenchmark outputs. 9 | /// 10 | public class BdnParam 11 | { 12 | public T Value { get; } 13 | private readonly string _comment; 14 | 15 | public BdnParam(T value, string comment) 16 | { 17 | Value = value; 18 | _comment = comment; 19 | } 20 | 21 | public override string ToString() 22 | { 23 | return _comment; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/Helpers/NullStreamWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.IO; 5 | 6 | namespace System.CommandLine.Benchmarks.Helpers 7 | { 8 | internal class NullStreamWriter : IStandardStreamWriter 9 | { 10 | public void Write(string value) 11 | { 12 | // do nothing 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using BenchmarkDotNet.Running; 5 | using System.Linq; 6 | using BenchmarkDotNet.Configs; 7 | using System.Collections.Immutable; 8 | using System.IO; 9 | 10 | namespace System.CommandLine.Benchmarks 11 | { 12 | class Program 13 | { 14 | static int Main(string[] args) 15 | { 16 | var result = BenchmarkSwitcher 17 | .FromAssembly(typeof(Program).Assembly) 18 | #if DEBUG 19 | .Run(args, new DebugInProcessConfig()); 20 | Console.ReadLine(); 21 | #else 22 | .Run(args, RecommendedConfig.Create( 23 | artifactsPath: new DirectoryInfo(Path.Combine( 24 | Path.GetDirectoryName(typeof(Program).Assembly.Location), "BenchmarkDotNet.Artifacts")), 25 | mandatoryCategories: ImmutableHashSet.Create(Categories.CommandLine, Categories.DragonFruit))); 26 | #endif 27 | // an empty summary means that initial filtering and validation did not allow to run 28 | if (!result.Any()) 29 | return 1; 30 | 31 | // if anything has failed, it's an error 32 | if (result.Any(summary => summary.HasCriticalValidationErrors || summary.Reports.Any(report => !report.BuildResult.IsBuildSuccess || !report.ExecuteResults.Any()))) 33 | return 1; 34 | 35 | return 0; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/System.CommandLine.Benchmarks.net5.0.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | 5 | -------------------------------------------------------------------------------- /src/System.CommandLine.Benchmarks/System.CommandLine.Benchmarks.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | 5 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit.Tests/EntryPointCreatorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.Reflection; 6 | using FluentAssertions; 7 | using Xunit; 8 | 9 | namespace System.CommandLine.DragonFruit.Tests 10 | { 11 | public class EntryPointCreatorTests 12 | { 13 | [Fact] 14 | public void ItThrowsIfEntryPointNotFound() 15 | { 16 | Action find = () => EntryPointDiscoverer.FindStaticEntryMethod(typeof(IEnumerable<>).Assembly); 17 | find.Should().Throw(); 18 | } 19 | 20 | private class Program 21 | { 22 | public static void Main(string arg1) { } 23 | public static void Main(string arg2, string arg3) { } 24 | } 25 | 26 | [Fact] 27 | public void ItThrowsIfMultipleEntryPointNotFound() 28 | { 29 | Action find = () => EntryPointDiscoverer.FindStaticEntryMethod(typeof(CommandLineTests).Assembly); 30 | find.Should().Throw(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit.Tests/StringExtensionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using FluentAssertions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.DragonFruit.Tests 8 | { 9 | public class StringExtensionTests 10 | { 11 | [Theory] 12 | [InlineData(null, null)] 13 | [InlineData("", "")] 14 | [InlineData("Option123", "option123")] 15 | [InlineData("dWORD", "d-word")] 16 | [InlineData("MSBuild", "msbuild")] 17 | [InlineData("NoEdit", "no-edit")] 18 | [InlineData("SetUpstreamBranch", "set-upstream-branch")] 19 | [InlineData("lowerCaseFirst", "lower-case-first")] 20 | [InlineData("_field", "field")] 21 | [InlineData("__field", "field")] 22 | [InlineData("___field", "field")] 23 | [InlineData("m_field", "m-field")] 24 | [InlineData("m_Field", "m-field")] 25 | public void ToKebabCase(string input, string expected) => input.ToKebabCase().Should().Be(expected); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit.Tests/System.CommandLine.DragonFruit.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK) 5 | AutoGeneratedProgram 6 | 7 | true 8 | 9 | 10 | 11 | $(NoWarn);1701;1702;1591 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit/CommandHelpMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.DragonFruit 7 | { 8 | public class CommandHelpMetadata 9 | { 10 | public string Description { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public Dictionary ParameterDescriptions { get; } = new Dictionary(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | true 4 | netstandard2.0 5 | This package includes the experimental DragonFruit app model for System.CommandLine, which allows you to create a command line application using only a Main method while getting support for complex type binding, error reporting, help, shell completions, and more. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/System.CommandLine.DragonFruit/targets/System.CommandLine.DragonFruit.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | 8 | true 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator.CommandHandler/CommandExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace System.CommandLine; 2 | 3 | /// 4 | /// Provides extension methods for . 5 | /// 6 | public static class CommandExtensions 7 | { 8 | private const string _messageForWhenGeneratorIsNotInUse = 9 | "This overload should not be called. You should reference the System.CommandLine.Generator package which will generate a more specific overload for your delegate."; 10 | 11 | /// 12 | /// Sets a command handler. 13 | /// 14 | /// Currently, this method only works with C# source generators. 15 | /// The command on which to set the handler. 16 | /// A delegate implementing the handler for the command. 17 | /// The symbols used to bind the handler's parameters. 18 | public static void SetHandler( 19 | this Command command, 20 | TDelegate @delegate, 21 | params Symbol[] symbols) 22 | { 23 | throw new InvalidOperationException(_messageForWhenGeneratorIsNotInUse); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator.CommandHandler/System.CommandLine.Generator.CommandHandler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator.Tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | IDE1006 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator.Tests/System.CommandLine.Generator.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK);$(NetFrameworkCurrent) 5 | true 6 | true 7 | true 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Invocations/ReturnPattern.cs: -------------------------------------------------------------------------------- 1 | namespace System.CommandLine.Generator.Invocations 2 | { 3 | internal enum ReturnPattern 4 | { 5 | None, 6 | InvocationContextExitCode, 7 | FunctionReturnValue, 8 | AwaitFunction, 9 | AwaitFunctionReturnValue 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/ArgumentParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | internal class ArgumentParameter : PropertyParameter, IEquatable 6 | { 7 | public ArgumentParameter(string localName, INamedTypeSymbol type, ITypeSymbol valueType) 8 | : base(localName, type, valueType) 9 | { 10 | } 11 | 12 | public override string GetValueFromContext() 13 | => $"context.GetValue({LocalName})"; 14 | 15 | public override int GetHashCode() 16 | => base.GetHashCode(); 17 | 18 | public override bool Equals(object? obj) 19 | => Equals(obj as ArgumentParameter); 20 | 21 | public bool Equals(ArgumentParameter? other) 22 | { 23 | if (other is null) return false; 24 | return base.Equals(other); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/BindingContextParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | internal class BindingContextParameter : Parameter, IEquatable 6 | { 7 | public BindingContextParameter(ITypeSymbol bindingContextType) 8 | : base(bindingContextType) 9 | { 10 | } 11 | 12 | public override string GetValueFromContext() 13 | => "context.GetBindingContext()"; 14 | 15 | public override int GetHashCode() 16 | => base.GetHashCode(); 17 | 18 | public override bool Equals(object? obj) 19 | => Equals(obj as BindingContextParameter); 20 | 21 | public bool Equals(BindingContextParameter? other) 22 | { 23 | if (other is null) return false; 24 | return base.Equals(other); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/ConsoleParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | internal class ConsoleParameter : Parameter, IEquatable 6 | { 7 | public ConsoleParameter(ITypeSymbol consoleType) 8 | : base(consoleType) 9 | { 10 | } 11 | 12 | public override string GetValueFromContext() 13 | => "context.Console"; 14 | 15 | public override int GetHashCode() 16 | => base.GetHashCode(); 17 | 18 | public override bool Equals(object? obj) 19 | => Equals(obj as ConsoleParameter); 20 | 21 | public bool Equals(ConsoleParameter? other) 22 | { 23 | if (other is null) return false; 24 | return base.Equals(other); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/OptionParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | 6 | internal class OptionParameter : PropertyParameter, IEquatable 7 | { 8 | public OptionParameter(string localName, INamedTypeSymbol type, ITypeSymbol valueType) 9 | : base(localName, type, valueType) 10 | { 11 | } 12 | 13 | public override string GetValueFromContext() 14 | => $"context.GetValue({LocalName})"; 15 | 16 | public override int GetHashCode() 17 | => base.GetHashCode(); 18 | 19 | public override bool Equals(object? obj) 20 | => Equals(obj as OptionParameter); 21 | 22 | public bool Equals(OptionParameter? other) 23 | { 24 | if (other is null) return false; 25 | return base.Equals(other); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/ParseResultParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | internal class ParseResultParameter : Parameter, IEquatable 6 | { 7 | public ParseResultParameter(ITypeSymbol parseResultType) 8 | : base(parseResultType) 9 | { 10 | } 11 | 12 | public override string GetValueFromContext() 13 | => "context"; 14 | 15 | public override int GetHashCode() 16 | => base.GetHashCode(); 17 | 18 | public override bool Equals(object? obj) 19 | => Equals(obj as ParseResultParameter); 20 | 21 | public bool Equals(ParseResultParameter? other) 22 | { 23 | if (other is null) return false; 24 | return base.Equals(other); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/Parameters/RawParameter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace System.CommandLine.Generator.Parameters 4 | { 5 | internal class RawParameter : PropertyParameter, IEquatable 6 | { 7 | public RawParameter(string localName, ITypeSymbol valueType) 8 | : base(localName, valueType, valueType) 9 | { 10 | } 11 | 12 | public override string GetValueFromContext() 13 | => LocalName; 14 | 15 | public override int GetHashCode() 16 | => base.GetHashCode(); 17 | 18 | public override bool Equals(object? obj) 19 | => Equals(obj as RawParameter); 20 | 21 | public bool Equals(RawParameter? other) 22 | { 23 | if (other is null) return false; 24 | return base.Equals(other); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Generator/System.CommandLine.Generator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | enable 6 | true 7 | false 8 | $(NoWarn);NU5128 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Hosting.Tests/System.CommandLine.Hosting.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK);$(NetFrameworkCurrent) 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/System.CommandLine.Hosting/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.Hosting/InvocationLifetimeOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | 3 | namespace System.CommandLine.Hosting 4 | { 5 | public class InvocationLifetimeOptions : ConsoleLifetimeOptions 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | netstandard2.0;netstandard2.1;$(TargetFrameworkForNETSDK) 6 | This package provides support for using System.CommandLine with Microsoft.Extensions.Hosting. 7 | 8 | 9 | 10 | portable 11 | 12 | 13 | 14 | true 15 | true 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder.Tests/BindingTestSet.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.NamingConventionBinder.Tests; 7 | 8 | public class BindingTestSet : Dictionary<(Type type, string variationName), BindingTestCase> 9 | { 10 | public void Add(BindingTestCase testCase) 11 | { 12 | Add((testCase.ParameterType, testCase.VariationName), testCase); 13 | } 14 | 15 | public BindingTestCase this[Type type] => base[(type, null)]; 16 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder.Tests/ParameterDescriptorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Tests.Binding; 5 | using System.Linq; 6 | using FluentAssertions; 7 | using Xunit; 8 | 9 | namespace System.CommandLine.NamingConventionBinder.Tests; 10 | 11 | public class ParameterDescriptorTests 12 | { 13 | [Theory] 14 | [InlineData(typeof(string), null)] 15 | [InlineData(typeof(int), 0)] 16 | [InlineData(typeof(int?), null)] 17 | public void GetDefaultValue_returns_the_default_for_the_type(Type type, object defaultValue) 18 | { 19 | type = typeof(ClassWithCtorParameter<>).MakeGenericType(type); 20 | 21 | var modelDescriptor = ModelDescriptor.FromType(type); 22 | 23 | modelDescriptor 24 | .ConstructorDescriptors 25 | .Single() 26 | .ParameterDescriptors 27 | .Single() 28 | .GetDefaultValue() 29 | .Should() 30 | .Be(defaultValue); 31 | } 32 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder.Tests/PropertyDescriptorTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Tests.Binding; 5 | using System.Linq; 6 | using FluentAssertions; 7 | using Xunit; 8 | 9 | namespace System.CommandLine.NamingConventionBinder.Tests; 10 | 11 | public class PropertyDescriptorTests 12 | { 13 | [Theory] 14 | [InlineData(typeof(string), null)] 15 | [InlineData(typeof(int), 0)] 16 | [InlineData(typeof(int?), null)] 17 | public void GetDefaultValue_returns_the_default_for_the_type(Type type, object defaultValue) 18 | { 19 | type = typeof(ClassWithSetter<>).MakeGenericType(type); 20 | 21 | var modelDescriptor = ModelDescriptor.FromType(type); 22 | 23 | modelDescriptor 24 | .PropertyDescriptors 25 | .Single() 26 | .GetDefaultValue() 27 | .Should() 28 | .Be(defaultValue); 29 | } 30 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder.Tests/System.CommandLine.NamingConventionBinder.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK);$(NetFrameworkCurrent) 5 | 10 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/BindingHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Binding; 5 | using System.CommandLine.Invocation; 6 | 7 | namespace System.CommandLine.NamingConventionBinder 8 | { 9 | /// 10 | /// Represents a handler that provides binding functionality for command-line actions. 11 | /// 12 | /// This abstract class serves as a base for implementing custom binding logic in command-line 13 | /// applications. It provides a mechanism to retrieve or initialize a for the current 14 | /// invocation. 15 | public abstract class BindingHandler : AsynchronousCommandLineAction 16 | { 17 | private BindingContext? _bindingContext; 18 | 19 | /// 20 | /// The binding context for the current invocation. 21 | /// 22 | public virtual BindingContext GetBindingContext(ParseResult parseResult) 23 | => _bindingContext ??= new BindingContext(parseResult); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/BoundValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | /// 7 | /// A value created by binding command line input. 8 | /// 9 | public readonly struct BoundValue 10 | { 11 | internal BoundValue( 12 | object? value, 13 | IValueDescriptor valueDescriptor, 14 | IValueSource valueSource) 15 | { 16 | Value = value; 17 | ValueDescriptor = valueDescriptor; 18 | ValueSource = valueSource; 19 | } 20 | 21 | /// 22 | /// The descriptor for the bound value. 23 | /// 24 | public IValueDescriptor ValueDescriptor { get; } 25 | 26 | /// 27 | /// The source from which the value was bound. 28 | /// 29 | public IValueSource ValueSource { get; } 30 | 31 | /// 32 | /// The value bound from the specified source. 33 | /// 34 | public object? Value { get; } 35 | 36 | /// 37 | public override string ToString() => $"{ValueDescriptor}: {Value}"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/ConstructorDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | 8 | namespace System.CommandLine.NamingConventionBinder; 9 | 10 | /// 11 | /// Provides information for binding command line input to a constructor. 12 | /// 13 | public class ConstructorDescriptor : IMethodDescriptor 14 | { 15 | private List? _parameterDescriptors; 16 | 17 | private readonly ConstructorInfo _constructorInfo; 18 | 19 | internal ConstructorDescriptor( 20 | ConstructorInfo constructorInfo, 21 | ModelDescriptor parent) 22 | { 23 | Parent = parent; 24 | _constructorInfo = constructorInfo; 25 | } 26 | 27 | /// 28 | public ModelDescriptor Parent { get; } 29 | 30 | /// 31 | public IReadOnlyList ParameterDescriptors => 32 | _parameterDescriptors ??= 33 | _constructorInfo.GetParameters().Select(p => new ParameterDescriptor(p, this)).ToList(); 34 | 35 | internal object Invoke(IReadOnlyCollection parameters) 36 | { 37 | return _constructorInfo.Invoke(parameters.ToArray()); 38 | } 39 | 40 | /// 41 | public override string ToString() => 42 | $"{Parent} ({string.Join(", ", ParameterDescriptors)})"; 43 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/DelegateHandlerDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace System.CommandLine.NamingConventionBinder; 8 | 9 | internal class DelegateHandlerDescriptor : HandlerDescriptor 10 | { 11 | private readonly Delegate _handlerDelegate; 12 | 13 | public DelegateHandlerDescriptor(Delegate handlerDelegate) 14 | { 15 | _handlerDelegate = handlerDelegate; 16 | } 17 | 18 | public override BindingHandler GetCommandHandler() 19 | { 20 | return new ModelBindingCommandHandler( 21 | _handlerDelegate, 22 | this); 23 | } 24 | 25 | public override ModelDescriptor? Parent => null; 26 | 27 | private protected override IEnumerable InitializeParameterDescriptors() 28 | { 29 | return _handlerDelegate.Method 30 | .GetParameters() 31 | .Select(p => new ParameterDescriptor(p, this)); 32 | } 33 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/DelegateValueSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Binding; 5 | 6 | namespace System.CommandLine.NamingConventionBinder; 7 | 8 | internal class DelegateValueSource : IValueSource 9 | { 10 | private readonly Func _getValue; 11 | 12 | public DelegateValueSource(Func getValue) 13 | { 14 | _getValue = getValue; 15 | } 16 | 17 | public bool TryGetValue(IValueDescriptor valueDescriptor, BindingContext? bindingContext, out object? boundValue) 18 | { 19 | boundValue = _getValue(bindingContext); 20 | 21 | return true; 22 | } 23 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/IMethodDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.NamingConventionBinder; 7 | 8 | /// 9 | /// Provides information for binding command line input to a method. 10 | /// 11 | public interface IMethodDescriptor 12 | { 13 | /// 14 | /// The model descriptor that this constructor belongs to. 15 | /// 16 | ModelDescriptor? Parent { get; } 17 | 18 | /// 19 | /// Descriptors for the parameters of the constructor. 20 | /// 21 | IReadOnlyList ParameterDescriptors { get; } 22 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/IValueDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | /// 7 | /// Describes and provides access to a bindable named value. 8 | /// 9 | public interface IValueDescriptor 10 | { 11 | /// 12 | /// The name of the value. 13 | /// 14 | string ValueName { get; } 15 | 16 | /// 17 | /// The type of the value. 18 | /// 19 | Type ValueType { get; } 20 | 21 | /// 22 | /// Gets a value determining whether there is a default value. 23 | /// 24 | bool HasDefaultValue { get; } 25 | 26 | /// 27 | /// Gets the default value, if any. 28 | /// 29 | object? GetDefaultValue(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/IValueSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | /// 7 | /// Binds a value from a based on a . 8 | /// 9 | public interface IValueSource 10 | { 11 | /// 12 | /// Gets a value from a binding context. A return value indicates whether a value matching the specified value descriptor was present. 13 | /// 14 | /// The descriptor for the value to be bound. 15 | /// The binding context from which to bind the value. 16 | /// The bound value. 17 | /// if a matching value was found; otherwise, . 18 | bool TryGetValue( 19 | IValueDescriptor valueDescriptor, 20 | BindingContext bindingContext, 21 | out object? boundValue); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/MissingValueSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Binding; 5 | 6 | namespace System.CommandLine.NamingConventionBinder; 7 | 8 | internal class MissingValueSource : IValueSource 9 | { 10 | public bool TryGetValue(IValueDescriptor valueDescriptor, BindingContext? bindingContext, out object? boundValue) 11 | { 12 | boundValue = null; 13 | return false; 14 | } 15 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/ModelBinderCollection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.CommandLine.Binding; 6 | 7 | namespace System.CommandLine.NamingConventionBinder; 8 | 9 | internal class ModelBinderCollection 10 | { 11 | private readonly Dictionary _modelBindersByValueDescriptor = new(); 12 | 13 | public void Add(ModelBinder binder) 14 | { 15 | _modelBindersByValueDescriptor.Add(binder.ValueDescriptor.ValueType, binder); 16 | } 17 | 18 | public ModelBinder GetModelBinder(IValueDescriptor valueDescriptor) 19 | { 20 | if (!_modelBindersByValueDescriptor.TryGetValue(valueDescriptor.ValueType, out var binder)) 21 | { 22 | binder = new ModelBinder(valueDescriptor); 23 | _modelBindersByValueDescriptor.Add(valueDescriptor.ValueType, binder); 24 | } 25 | 26 | return binder; 27 | } 28 | } -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/ServiceProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.CommandLine.Binding; 6 | 7 | namespace System.CommandLine.Invocation 8 | { 9 | internal sealed class ServiceProvider : IServiceProvider 10 | { 11 | private readonly Dictionary> _services; 12 | 13 | internal ServiceProvider(BindingContext bindingContext) 14 | { 15 | _services = new Dictionary> 16 | { 17 | [typeof(ParseResult)] = _ => bindingContext.ParseResult, 18 | [typeof(BindingContext)] = _ => bindingContext 19 | }; 20 | } 21 | 22 | public void AddService(Func factory) => _services[typeof(T)] = p => factory(p)!; 23 | 24 | public void AddService(Type serviceType, Func factory) => _services[serviceType] = factory; 25 | 26 | public IReadOnlyCollection AvailableServiceTypes => _services.Keys; 27 | 28 | public object? GetService(Type serviceType) 29 | { 30 | if (_services.TryGetValue(serviceType, out var factory)) 31 | { 32 | return factory(this); 33 | } 34 | 35 | return null; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/ServiceProviderValueSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | internal class ServiceProviderValueSource : IValueSource 7 | { 8 | public bool TryGetValue( 9 | IValueDescriptor valueDescriptor, 10 | BindingContext? bindingContext, 11 | out object? boundValue) 12 | { 13 | boundValue = bindingContext?.ServiceProvider.GetService(valueDescriptor.ValueType); 14 | return true; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/System.CommandLine.NamingConventionBinder.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | System.CommandLine.NamingConventionBinder 6 | $(TargetFrameworkForNETSDK);netstandard2.0 7 | 10 8 | enable 9 | This package provides command handler support for System.CommandLine performs parameter and model binding by matching option and argument names to parameter and property names. 10 | true 11 | 12 | 13 | 14 | portable 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/System.CommandLine.NamingConventionBinder/ValueDescriptorDefaultValueSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | internal class ValueDescriptorDefaultValueSource : IValueSource 7 | { 8 | public static readonly IValueSource Instance = new ValueDescriptorDefaultValueSource(); 9 | 10 | private ValueDescriptorDefaultValueSource() 11 | { 12 | } 13 | 14 | public bool TryGetValue( 15 | IValueDescriptor valueDescriptor, 16 | BindingContext bindingContext, 17 | out object? boundValue) 18 | { 19 | boundValue = valueDescriptor.GetDefaultValue(); 20 | return true; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/ContainerSpanTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using FluentAssertions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Rendering.Tests 8 | { 9 | public class ContainerSpanTests 10 | { 11 | [Fact] 12 | public void Container_span_supports_add_method() 13 | { 14 | var span = new ContainerSpan(new ContentSpan("content")); 15 | span.Add(new ContentSpan(" with child")); 16 | 17 | span.ContentLength.Should().Be("content with child".Length); 18 | } 19 | 20 | [Fact] 21 | public void Container_span_supports_add_string_method() 22 | { 23 | var span = new ContainerSpan(new ContentSpan("content")); 24 | span.Add(" with string"); 25 | 26 | span.ContentLength.Should().Be("content with string".Length); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/RenderingTestCase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Tests 5 | { 6 | public class RenderingTestCase 7 | { 8 | private static readonly TextSpanFormatter _formatter = new(); 9 | 10 | public RenderingTestCase( 11 | string name, 12 | FormattableString rendering, 13 | Region inRegion, 14 | params TextRendered[] expectOutput) 15 | { 16 | if (rendering == null) 17 | { 18 | throw new ArgumentNullException(nameof(rendering)); 19 | } 20 | 21 | if (string.IsNullOrWhiteSpace(name)) 22 | { 23 | throw new ArgumentException("Value cannot be null or whitespace.", nameof(name)); 24 | } 25 | 26 | Name = name; 27 | InputSpan = _formatter.ParseToSpan(rendering); 28 | Region = inRegion ?? throw new ArgumentNullException(nameof(inRegion)); 29 | ExpectedOutput = expectOutput ?? throw new ArgumentNullException(nameof(expectOutput)); 30 | } 31 | 32 | public string Name { get; } 33 | 34 | public TextSpan InputSpan { get; } 35 | 36 | public Region Region { get; } 37 | 38 | public TextRendered[] ExpectedOutput { get; } 39 | 40 | public override string ToString() => $"{Name} (in {Region})"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/SizeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using FluentAssertions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Rendering.Tests 8 | { 9 | public class SizeTests 10 | { 11 | [Fact] 12 | public void Width_cannot_be_negative() 13 | { 14 | Action createSize = () => new Size(-1, 0); 15 | createSize.Should().Throw().Where(exception => exception.ParamName == "width"); 16 | } 17 | 18 | [Fact] 19 | public void Height_cannot_be_negative() 20 | { 21 | Action createSize = () => new Size(0, -1); 22 | createSize.Should().Throw().Where(exception => exception.ParamName == "height"); 23 | } 24 | 25 | [Fact] 26 | public void Width_and_height_can_be_set_on_size() 27 | { 28 | var size = new Size(20, 15); 29 | size.Width.Should().Be(20); 30 | size.Height.Should().Be(15); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/System.CommandLine.Rendering.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK) 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/SystemConsoleTerminalTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.IO; 5 | 6 | namespace System.CommandLine.Rendering.Tests 7 | { 8 | public class SystemConsoleTerminalTests : TerminalTests 9 | { 10 | protected override ITerminal GetTerminal() 11 | { 12 | return new SystemConsoleTerminal(new SystemConsole()); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering.Tests/ViewWrappingTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using FluentAssertions; 5 | using System.Linq; 6 | using Xunit; 7 | using System.CommandLine.Rendering.Views; 8 | 9 | namespace System.CommandLine.Rendering.Tests 10 | { 11 | public class ViewWrappingTests 12 | { 13 | private readonly TestTerminal _terminal; 14 | private readonly ConsoleRenderer consoleRenderer; 15 | 16 | public ViewWrappingTests() 17 | { 18 | _terminal = new TestTerminal 19 | { 20 | Width = 150 21 | }; 22 | 23 | consoleRenderer = new ConsoleRenderer(_terminal); 24 | } 25 | 26 | [Fact] 27 | public void Text_wraps_within_the_specified_region() 28 | { 29 | var text = "1 1 1 2 2"; 30 | 31 | var view = new ContentView(text); 32 | 33 | view.Render(consoleRenderer, 34 | new Region(0, 0, 5, 2)); 35 | 36 | _terminal.RenderOperations() 37 | .Select(l => l.Text) 38 | .Should() 39 | .BeEquivalentTo( 40 | new[] { 41 | "1 1 1", 42 | "2 2 " 43 | }, 44 | options => options.WithStrictOrdering()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/ColorSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | public abstract class ColorSpan : ControlSpan 7 | { 8 | protected ColorSpan(string name, AnsiControlCode ansiControlCode) 9 | : base(name, ansiControlCode) 10 | { 11 | } 12 | 13 | protected ColorSpan(RgbColor rgbColor, AnsiControlCode ansiControlCode) 14 | : base( 15 | GetName(rgbColor) ?? throw new ArgumentNullException(nameof(rgbColor)), 16 | ansiControlCode) 17 | { 18 | RgbColor = rgbColor; 19 | } 20 | 21 | public RgbColor RgbColor { get; } 22 | 23 | protected static string GetName(RgbColor rgbColor) 24 | { 25 | return rgbColor?.ToString(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/ContentSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | public class ContentSpan : TextSpan 7 | { 8 | public ContentSpan(string content) 9 | { 10 | Content = content ?? ""; 11 | } 12 | 13 | public string Content { get; } 14 | 15 | public override int ContentLength => Content.Length; 16 | 17 | public override string ToString() => Content; 18 | 19 | protected bool Equals(ContentSpan other) => string.Equals(Content, other.Content); 20 | 21 | public override bool Equals(object obj) 22 | { 23 | if (ReferenceEquals(null, obj)) 24 | { 25 | return false; 26 | } 27 | 28 | if (ReferenceEquals(this, obj)) 29 | { 30 | return true; 31 | } 32 | 33 | return obj.GetType() == GetType() && 34 | Equals((ContentSpan)obj); 35 | } 36 | 37 | public override int GetHashCode() => Content?.GetHashCode() ?? 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/CursorControlSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace System.CommandLine.Rendering 7 | { 8 | [DebuggerDisplay("{" + nameof(Name) + "}")] 9 | public class CursorControlSpan : ControlSpan 10 | { 11 | public CursorControlSpan(string name, AnsiControlCode ansiControlCode) : 12 | base(name, ansiControlCode) 13 | { 14 | } 15 | 16 | public override int ContentLength => 0; 17 | 18 | public static CursorControlSpan Hide() => new(nameof(Hide), Ansi.Cursor.Hide); 19 | 20 | public static CursorControlSpan Show() => new(nameof(Show), Ansi.Cursor.Show); 21 | } 22 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/EntireTerminalRegion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | internal class EntireTerminalRegion : Region 7 | { 8 | public EntireTerminalRegion() : base(0, 0, isOverwrittenOnRender: false) 9 | { 10 | } 11 | 12 | public override int Height => Console.WindowHeight; 13 | 14 | public override int Width => Console.WindowWidth; 15 | 16 | public override int Top => Console.CursorTop; 17 | 18 | public override int Left => Console.CursorLeft; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/FileRenderingSpanVisitor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.IO; 5 | 6 | namespace System.CommandLine.Rendering 7 | { 8 | internal class FileRenderingSpanVisitor : ContentRenderingSpanVisitor 9 | { 10 | public FileRenderingSpanVisitor( 11 | IStandardStreamWriter writer, 12 | Region region) : base(writer, region) 13 | { 14 | } 15 | 16 | protected override void SetCursorPosition(int? left = null, int? top = null) 17 | { 18 | if (top > 0 && left == 0) 19 | { 20 | Writer.WriteLine(); 21 | } 22 | } 23 | 24 | protected override void TryClearRemainingWidth() 25 | { 26 | ClearRemainingWidth(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IConsole.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.IO; 5 | 6 | namespace System.CommandLine 7 | { 8 | /// 9 | /// Represents the standard console input, output, and error streams. 10 | /// 11 | public interface IConsole : 12 | IStandardOut, 13 | IStandardError, 14 | IStandardIn 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IO/IStandardError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.IO 5 | { 6 | /// 7 | /// Represents a console's standard error stream. 8 | /// 9 | public interface IStandardError 10 | { 11 | /// 12 | /// The stream writer for standard error. 13 | /// 14 | IStandardStreamWriter Error { get; } 15 | 16 | /// 17 | /// Indicates whether the standard error stream has been redirected. 18 | /// 19 | bool IsErrorRedirected { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IO/IStandardIn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.IO 5 | { 6 | /// 7 | /// Represents a console's standard input stream. 8 | /// 9 | public interface IStandardIn 10 | { 11 | /// 12 | /// Gets a value indicating whether input is redirected. 13 | /// 14 | bool IsInputRedirected { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IO/IStandardOut.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.IO 5 | { 6 | /// 7 | /// Represents a console's standard output stream. 8 | /// 9 | public interface IStandardOut 10 | { 11 | /// 12 | /// The stream writer for standard output. 13 | /// 14 | IStandardStreamWriter Out { get; } 15 | 16 | /// 17 | /// Indicates whether the standard output stream has been redirected. 18 | /// 19 | bool IsOutputRedirected { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IO/IStandardStreamWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.IO 5 | { 6 | /// 7 | /// Represents a standard stream that can be written to. 8 | /// 9 | public interface IStandardStreamWriter 10 | { 11 | /// 12 | /// Writes the specified string to the stream. 13 | /// 14 | /// The value to write. 15 | void Write(string? value); 16 | } 17 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/IRenderable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | internal interface IRenderable 7 | { 8 | OutputMode OutputMode { get; } 9 | 10 | Region GetRegion(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/ITerminal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | public interface ITerminal : IConsole 7 | { 8 | ConsoleColor BackgroundColor { get; set; } 9 | 10 | ConsoleColor ForegroundColor { get; set; } 11 | 12 | void ResetColor(); 13 | 14 | void Clear(); 15 | 16 | int CursorLeft { get; set; } 17 | 18 | int CursorTop { get; set; } 19 | 20 | void SetCursorPosition(int left, int top); 21 | 22 | void HideCursor(); 23 | 24 | void ShowCursor(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Interop.Windows.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace System.CommandLine.Rendering 7 | { 8 | internal static class Interop 9 | { 10 | public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; 11 | 12 | public const uint ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200; 13 | 14 | public const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008; 15 | 16 | public const int STD_OUTPUT_HANDLE = -11; 17 | 18 | public const int STD_INPUT_HANDLE = -10; 19 | 20 | [DllImport("kernel32.dll")] 21 | public static extern bool GetConsoleMode(IntPtr handle, out uint mode); 22 | 23 | [DllImport("kernel32.dll")] 24 | public static extern uint GetLastError(); 25 | 26 | [DllImport("kernel32.dll")] 27 | public static extern bool SetConsoleMode(IntPtr handle, uint mode); 28 | 29 | [DllImport("kernel32.dll", SetLastError = true)] 30 | public static extern IntPtr GetStdHandle(int handle); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/OutputMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | public enum OutputMode 7 | { 8 | Auto, 9 | NonAnsi, 10 | Ansi, 11 | PlainText 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/RecordingWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.IO; 5 | using System.IO; 6 | using System.Text; 7 | 8 | namespace System.CommandLine.Rendering 9 | { 10 | internal class RecordingWriter : TextWriter, IStandardStreamWriter 11 | { 12 | private readonly StringBuilder _stringBuilder = new(); 13 | 14 | public event Action CharWritten; 15 | 16 | public override void Write(char value) 17 | { 18 | _stringBuilder.Append(value); 19 | CharWritten?.Invoke(value); 20 | } 21 | 22 | public override Encoding Encoding { get; } = Encoding.Unicode; 23 | 24 | public override string ToString() => _stringBuilder.ToString(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/RgbColor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | public class RgbColor 7 | { 8 | public RgbColor(byte r, byte g, byte b) 9 | { 10 | Red = r; 11 | Green = g; 12 | Blue = b; 13 | } 14 | 15 | public byte Red { get; } 16 | public byte Green { get; } 17 | public byte Blue { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/ScrollingTerminalRegion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | internal class ScrollingTerminalRegion : Region 7 | { 8 | public ScrollingTerminalRegion() : base(0, 0, isOverwrittenOnRender: false) 9 | { 10 | } 11 | 12 | public override int Height => int.MaxValue; 13 | 14 | public override int Width => Console.IsOutputRedirected 15 | ? 100 16 | : base.Width; 17 | 18 | public override int Top => Console.IsOutputRedirected 19 | ? 0 20 | : base.Top; 21 | 22 | public override int Left => Console.IsOutputRedirected 23 | ? 0 24 | : Console.CursorLeft; 25 | } 26 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Size.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace System.CommandLine.Rendering 7 | { 8 | [DebuggerDisplay("{Width}x{Height}")] 9 | public class Size 10 | { 11 | public const int MaxValue = -1; 12 | 13 | public Size(int width, int height) 14 | { 15 | if (width < 0) 16 | { 17 | throw new ArgumentOutOfRangeException(nameof(width)); 18 | } 19 | 20 | if (height < 0) 21 | { 22 | throw new ArgumentOutOfRangeException(nameof(height)); 23 | } 24 | 25 | Width = width; 26 | Height = height; 27 | } 28 | 29 | public int Width { get; } 30 | 31 | public int Height { get; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering 5 | { 6 | internal static class StringExtensions 7 | { 8 | public static bool EndsWithWhitespace(this string value) => 9 | value.Length > 0 10 | && char.IsWhiteSpace(value[value.Length - 1]); 11 | 12 | public static bool StartsWithWhitespace(this string value) => 13 | value.Length > 0 14 | && char.IsWhiteSpace(value[0]); 15 | 16 | public static bool IsNewLine(this string value) => value == "\n" || value == "\r\n"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/System.CommandLine.Rendering.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | netstandard2.0 6 | This package provides support for structured command line output rendering. Write code once that renders correctly in multiple output modes, including System.Console, virtual terminal (using ANSI escape sequences), and plain text. 7 | 8 | $(NoWarn);CS8632 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/TextSpan.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.IO; 5 | 6 | namespace System.CommandLine.Rendering 7 | { 8 | public abstract class TextSpan 9 | { 10 | public static TextSpan Empty() => new ContentSpan(""); 11 | 12 | private TextSpan _root; 13 | 14 | public abstract int ContentLength { get; } 15 | 16 | public TextSpan Root => _root ?? (_root = this); 17 | 18 | public ContainerSpan Parent { get; private set; } 19 | 20 | public int Start { get; private set; } 21 | 22 | public int End => Start + ContentLength; 23 | 24 | internal virtual void RecalculatePositions(ContainerSpan parent, int start) 25 | { 26 | Parent = parent; 27 | _root = parent.Root; 28 | Start = start; 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return ToString(OutputMode.PlainText); 34 | } 35 | 36 | public virtual string ToString(OutputMode outputMode) 37 | { 38 | var writer = new StringWriter(); 39 | 40 | WriteTo(writer, outputMode); 41 | 42 | return writer.ToString(); 43 | } 44 | 45 | public virtual void WriteTo(TextWriter writer, OutputMode outputMode) 46 | { 47 | writer.Write(ToString()); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/ColumnDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public class ColumnDefinition 7 | { 8 | public SizeMode SizeMode { get; } 9 | 10 | public double Value { get; } 11 | 12 | private ColumnDefinition(SizeMode sizeMode, double value) 13 | { 14 | SizeMode = sizeMode; 15 | Value = value; 16 | } 17 | 18 | public static ColumnDefinition Fixed(int size) 19 | { 20 | if (size < 0.0) 21 | { 22 | throw new ArgumentException("Fixed size cannot be negative", nameof(size)); 23 | } 24 | return new ColumnDefinition(SizeMode.Fixed, size); 25 | } 26 | 27 | public static ColumnDefinition Star(double weight) 28 | { 29 | if (weight < 0.0) 30 | { 31 | throw new ArgumentException("Weight cannot be negative", nameof(weight)); 32 | } 33 | return new ColumnDefinition(SizeMode.Star, weight); 34 | } 35 | 36 | public static ColumnDefinition SizeToContent() => new(SizeMode.SizeToContent, 0); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/ContentView{T}.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public class ContentView : ContentView 7 | { 8 | public ContentView(T value) 9 | { 10 | Value = value; 11 | } 12 | 13 | public T Value { get; } 14 | 15 | public override Size Measure(ConsoleRenderer renderer, Size maxSize) 16 | { 17 | EnsureSpanCreated(renderer); 18 | return base.Measure(renderer, maxSize); 19 | } 20 | 21 | public override void Render(ConsoleRenderer renderer, Region region) 22 | { 23 | EnsureSpanCreated(renderer); 24 | base.Render(renderer, region); 25 | } 26 | 27 | private void EnsureSpanCreated(ConsoleRenderer renderer) 28 | { 29 | if (Span == null) 30 | { 31 | Span = renderer.Formatter.Format(Value); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/ItemsView.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.Rendering.Views 7 | { 8 | public abstract class ItemsView : View 9 | { 10 | private IReadOnlyList _items; 11 | //TODO: IEnumerable? INCC? IObservable? 12 | public virtual IReadOnlyList Items 13 | { 14 | get => _items; 15 | set 16 | { 17 | if (!EqualityComparer>.Default.Equals(_items, value)) 18 | { 19 | _items = value; 20 | OnUpdated(); 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/Orientation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public enum Orientation 7 | { 8 | Vertical, 9 | Horizontal 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/RowDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public class RowDefinition 7 | { 8 | public double Value { get; } 9 | public SizeMode SizeMode { get; } 10 | 11 | private RowDefinition(SizeMode sizeMode, double value) 12 | { 13 | SizeMode = sizeMode; 14 | Value = value; 15 | } 16 | public static RowDefinition Fixed(int size) 17 | { 18 | if (size < 0.0) 19 | { 20 | throw new ArgumentException("Fixed size cannot be negative", nameof(size)); 21 | } 22 | return new RowDefinition(SizeMode.Fixed, size); 23 | } 24 | 25 | public static RowDefinition Star(double weight) 26 | { 27 | if (weight < 0.0) 28 | { 29 | throw new ArgumentException("Weight cannot be negative", nameof(weight)); 30 | } 31 | return new RowDefinition(SizeMode.Star, weight); 32 | } 33 | 34 | public static RowDefinition SizeToContent() => new(SizeMode.SizeToContent, 0); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/SizeMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public enum SizeMode 7 | { 8 | Fixed, 9 | Star, 10 | SizeToContent 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/TableViewColumn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public interface ITableViewColumn 7 | { 8 | ColumnDefinition ColumnDefinition { get; } 9 | 10 | View Header { get; } 11 | 12 | View GetCell(T item, TextSpanFormatter formatter); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/System.CommandLine.Rendering/Views/View.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Rendering.Views 5 | { 6 | public abstract class View 7 | { 8 | public event EventHandler Updated; 9 | 10 | public abstract void Render(ConsoleRenderer renderer, Region region = null); 11 | 12 | public abstract Size Measure(ConsoleRenderer renderer, Size maxSize); 13 | 14 | protected void OnUpdated() => Updated?.Invoke(this, EventArgs.Empty); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/EndToEndTestApp/EndToEndTestApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Exe 9 | $(TargetFrameworkForNETSDK) 10 | win-x64;linux-x64;osx-x64;osx-arm64 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/EndToEndTestApp/Program.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using System.CommandLine.Help; 3 | using System.CommandLine.Parsing; 4 | using System.Threading.Tasks; 5 | using System.Threading; 6 | 7 | namespace EndToEndTestApp 8 | { 9 | public class Program 10 | { 11 | static async Task Main(string[] args) 12 | { 13 | Option appleOption = new ("--apple" ); 14 | Option bananaOption = new ("--banana"); 15 | Option cherryOption = new ("--cherry"); 16 | Option durianOption = new ("--durian"); 17 | 18 | RootCommand rootCommand = new () 19 | { 20 | appleOption, 21 | bananaOption, 22 | cherryOption, 23 | durianOption, 24 | }; 25 | 26 | rootCommand.SetAction((ParseResult ctx, CancellationToken cancellationToken) => 27 | { 28 | string apple = ctx.GetValue(appleOption); 29 | string banana = ctx.GetValue(bananaOption); 30 | string cherry = ctx.GetValue(cherryOption); 31 | string durian = ctx.GetValue(durianOption); 32 | 33 | return Task.CompletedTask; 34 | }); 35 | 36 | CommandLineConfiguration commandLine = new (rootCommand); 37 | 38 | await commandLine.InvokeAsync(args); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/FileSuggestionProviderTests.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace System.CommandLine.Suggest.Tests 4 | { 5 | public class FileSuggestionProviderTests : SuggestionRegistrationTest, IDisposable 6 | { 7 | protected override ISuggestionRegistration GetSuggestionRegistration() => new FileSuggestionRegistration(_filePath); 8 | 9 | private readonly string _filePath; 10 | 11 | public FileSuggestionProviderTests() 12 | { 13 | _filePath = Path.GetFullPath(Path.GetRandomFileName()); 14 | } 15 | 16 | public void Dispose() 17 | { 18 | if (File.Exists(_filePath)) 19 | { 20 | File.Delete(_filePath); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/TestSuggestionRegistration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | namespace System.CommandLine.Suggest.Tests 9 | { 10 | internal class TestSuggestionRegistration : ISuggestionRegistration 11 | { 12 | private readonly List _suggestionRegistrations = new(); 13 | 14 | public TestSuggestionRegistration(params Registration[] suggestionRegistrations) 15 | { 16 | foreach (Registration suggestionRegistration in suggestionRegistrations) 17 | { 18 | AddSuggestionRegistration(suggestionRegistration); 19 | } 20 | } 21 | 22 | public Registration FindRegistration(FileInfo soughtExecutable) 23 | => _suggestionRegistrations.FirstOrDefault(x => x.ExecutablePath.StartsWith(soughtExecutable.FullName, StringComparison.OrdinalIgnoreCase)); 24 | 25 | public IEnumerable FindAllRegistrations() 26 | => _suggestionRegistrations; 27 | 28 | public void AddSuggestionRegistration(Registration registration) 29 | { 30 | _suggestionRegistrations.Add(registration); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/TestSuggestionRegistrationTests.cs: -------------------------------------------------------------------------------- 1 | namespace System.CommandLine.Suggest.Tests 2 | { 3 | public class TestSuggestionRegistrationTests : SuggestionRegistrationTest 4 | { 5 | protected override ISuggestionRegistration GetSuggestionRegistration() => new TestSuggestionRegistration(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest.Tests/dotnet-suggest.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(TargetFrameworkForNETSDK) 5 | $(DefaultExcludesInProjectFolder);EndToEndTestApp\** 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/DotnetProfileDirectory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace System.CommandLine.Suggest 8 | { 9 | public static class DotnetProfileDirectory 10 | { 11 | private const string DotnetHomeVariableName = "DOTNET_CLI_HOME"; 12 | private const string DotnetProfileDirectoryName = ".dotnet"; 13 | 14 | private static string PlatformHomeVariableName => 15 | RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "USERPROFILE" : "HOME"; 16 | 17 | public static bool TryGet(out string dotnetProfileDirectory) 18 | { 19 | dotnetProfileDirectory = null; 20 | var home = Environment.GetEnvironmentVariable(DotnetHomeVariableName); 21 | if (string.IsNullOrEmpty(home)) 22 | { 23 | home = Environment.GetEnvironmentVariable(PlatformHomeVariableName); 24 | if (string.IsNullOrEmpty(home)) 25 | { 26 | return false; 27 | } 28 | } 29 | 30 | dotnetProfileDirectory = Path.Combine(home, DotnetProfileDirectoryName); 31 | return true; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/FileEnumerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | namespace System.CommandLine.Suggest 9 | { 10 | public static class FileEnumerator 11 | { 12 | public static IEnumerable EnumerateFilesWithoutExtension(DirectoryInfo path) 13 | { 14 | if (path == null || !path.Exists) 15 | { 16 | return Array.Empty(); 17 | } 18 | 19 | return path.EnumerateFiles() 20 | .Select(p => Path.GetFileNameWithoutExtension(p.FullName)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/ISuggestionRegistration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace System.CommandLine.Suggest 5 | { 6 | public interface ISuggestionRegistration 7 | { 8 | void AddSuggestionRegistration(Registration registration); 9 | Registration FindRegistration(FileInfo soughtExecutable); 10 | IEnumerable FindAllRegistrations(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/ISuggestionStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | 5 | namespace System.CommandLine.Suggest 6 | { 7 | public interface ISuggestionStore 8 | { 9 | string GetCompletions(string exeFileName, string suggestionTargetArguments, TimeSpan timeout); 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/PathExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Suggest 5 | { 6 | internal static class PathExtensions 7 | { 8 | public static string RemoveExeExtension(this string path) 9 | { 10 | if (path.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) 11 | { 12 | path = path.Remove(path.LastIndexOf(".exe", StringComparison.OrdinalIgnoreCase)); 13 | } 14 | 15 | return path; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/RegistrationPair.cs: -------------------------------------------------------------------------------- 1 | namespace System.CommandLine.Suggest 2 | { 3 | public class Registration 4 | { 5 | public Registration(string executablePath) 6 | { 7 | ExecutablePath = executablePath ?? throw new ArgumentNullException(nameof(executablePath)); 8 | } 9 | 10 | public string ExecutablePath { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/ShellType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Suggest 5 | { 6 | public enum ShellType 7 | { 8 | Bash, 9 | PowerShell, 10 | Zsh 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Suggest 5 | { 6 | internal static class StringExtensions 7 | { 8 | public static string Escape(this string commandLine) => commandLine.Replace("\"", "\\\""); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/SuggestionShellScriptException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Suggest 5 | { 6 | public class SuggestionShellScriptException : Exception 7 | { 8 | public SuggestionShellScriptException() 9 | { 10 | } 11 | 12 | public SuggestionShellScriptException(string message) : base(message) 13 | { 14 | } 15 | 16 | public SuggestionShellScriptException(string message, Exception innerException) : base(message, innerException) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/build-and-install.ps1: -------------------------------------------------------------------------------- 1 | function Get-ScriptDirectory { 2 | Split-Path -parent $PSCommandPath 3 | } 4 | 5 | dotnet pack /p:Version=0.0.0-dev 6 | dotnet tool uninstall -g dotnet-suggest 7 | dotnet tool install -g --version 0.0.0-dev --add-source "$(Get-ScriptDirectory)/bin/Debug" dotnet-suggest 8 | 9 | # enable debug logging 10 | $env:DOTNET_SUGGEST_LOGGING=1 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/dotnet-suggest-shim.bash: -------------------------------------------------------------------------------- 1 | _dotnet_bash_complete() 2 | { 3 | local fullpath=$(type -p "${COMP_WORDS[0]}") 4 | local completions=$(dotnet-suggest get --executable "${fullpath}" --position "${COMP_POINT}" -- "${COMP_LINE}") 5 | 6 | # filter suggestions by word to complete. 7 | local word="${COMP_WORDS[COMP_CWORD]}" 8 | local IFS=$'\n' 9 | local suggestions=($(compgen -W "$completions" -- "$word")) 10 | 11 | # format suggestions as shell input. 12 | for i in "${!suggestions[@]}"; do 13 | suggestions[i]="$(printf '%q' "${suggestions[$i]}")" 14 | done 15 | 16 | COMPREPLY=("${suggestions[@]}") 17 | } 18 | 19 | _dotnet_bash_register_complete() 20 | { 21 | if command -v dotnet-suggest &>/dev/null; then 22 | local IFS=$'\n' 23 | complete -F _dotnet_bash_complete $(dotnet-suggest list) 24 | fi 25 | } 26 | 27 | _dotnet_bash_register_complete 28 | export DOTNET_SUGGEST_SCRIPT_VERSION="1.0.3" 29 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/dotnet-suggest-shim.ps1: -------------------------------------------------------------------------------- 1 | # dotnet suggest shell start 2 | if (Get-Command "dotnet-suggest" -errorAction SilentlyContinue) 3 | { 4 | $availableToComplete = (dotnet-suggest list) | Out-String 5 | $availableToCompleteArray = $availableToComplete.Split([Environment]::NewLine, [System.StringSplitOptions]::RemoveEmptyEntries) 6 | 7 | Register-ArgumentCompleter -Native -CommandName $availableToCompleteArray -ScriptBlock { 8 | param($wordToComplete, $commandAst, $cursorPosition) 9 | $fullpath = (Get-Command $commandAst.CommandElements[0]).Source 10 | 11 | $arguments = $commandAst.Extent.ToString().Replace('"', '\"') 12 | dotnet-suggest get -e $fullpath --position $cursorPosition -- "$arguments" | ForEach-Object { 13 | [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) 14 | } 15 | } 16 | } 17 | else 18 | { 19 | "Unable to provide System.CommandLine tab completion support unless the [dotnet-suggest] tool is first installed." 20 | "See the following for tool installation: https://www.nuget.org/packages/dotnet-suggest" 21 | } 22 | 23 | $env:DOTNET_SUGGEST_SCRIPT_VERSION = "1.0.2" 24 | # dotnet suggest script end 25 | -------------------------------------------------------------------------------- /src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh: -------------------------------------------------------------------------------- 1 | _dotnet_zsh_complete() 2 | { 3 | # debug lines, uncomment to get state variables passed to this function 4 | # echo "\n\n\nstate:\t'$state'" 5 | # echo "line:\t'$line'" 6 | # echo "words:\t$words" 7 | 8 | # Get full path to script because dotnet-suggest needs it 9 | # NOTE: this requires a command registered with dotnet-suggest be 10 | # on the PATH 11 | full_path=`which ${words[1]}` # zsh arrays are 1-indexed 12 | # Get the full line 13 | # $words array when quoted like this gets expanded out into the full line 14 | full_line="$words" 15 | 16 | # Get the completion results, will be newline-delimited 17 | completions=$(dotnet-suggest get --executable "$full_path" -- "$full_line") 18 | # explode the completions by linefeed instead of by spaces into the descriptions for the 19 | # _values helper function. 20 | 21 | exploded=(${(f)completions}) 22 | # for later - once we have descriptions from dotnet suggest, we can stitch them 23 | # together like so: 24 | # described=() 25 | # for i in {1..$#exploded}; do 26 | # argument="${exploded[$i]}" 27 | # description="hello description $i" 28 | # entry=($argument"["$description"]") 29 | # described+=("$entry") 30 | # done 31 | _values 'suggestions' $exploded 32 | } 33 | 34 | # apply this function to each command the dotnet-suggest knows about 35 | compdef _dotnet_zsh_complete $(dotnet-suggest list) 36 | 37 | export DOTNET_SUGGEST_SCRIPT_VERSION="1.0.0" 38 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | IDE1006 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Help/ApprovalTests.Config.cs: -------------------------------------------------------------------------------- 1 | using ApprovalTests.Reporters; 2 | using ApprovalTests.Reporters.TestFrameworks; 3 | 4 | // Use globally defined Reporter for ApprovalTests. Please see 5 | // https://github.com/approvals/ApprovalTests.Net/blob/master/docs/ApprovalTests/Reporters.md 6 | 7 | [assembly: UseReporter(typeof(FrameworkAssertReporter))] 8 | 9 | [assembly: ApprovalTests.Namers.UseApprovalSubdirectory("Approvals")] 10 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Help/CustomHelpAction.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Invocation; 2 | 3 | namespace System.CommandLine.Help 4 | { 5 | /// 6 | /// Provides command line help. 7 | /// 8 | public sealed class CustomHelpAction : SynchronousCommandLineAction 9 | { 10 | private HelpBuilder? _builder; 11 | 12 | /// 13 | /// Specifies an to be used to format help output when help is requested. 14 | /// 15 | internal HelpBuilder Builder 16 | { 17 | get => _builder ??= new HelpBuilder(Console.IsOutputRedirected ? int.MaxValue : Console.WindowWidth); 18 | set => _builder = value ?? throw new ArgumentNullException(nameof(value)); 19 | } 20 | 21 | /// 22 | public override int Invoke(ParseResult parseResult) 23 | { 24 | var output = parseResult.Configuration.Output; 25 | 26 | var helpContext = new HelpContext(Builder, 27 | parseResult.CommandResult.Command, 28 | output); 29 | 30 | Builder.Write(helpContext); 31 | 32 | return 0; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Help/HelpBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Help; 5 | using System.IO; 6 | 7 | namespace System.CommandLine.Tests.Help 8 | { 9 | public static class HelpBuilderExtensions 10 | { 11 | internal static void Write( 12 | this HelpBuilder builder, 13 | Command command, 14 | TextWriter writer) => 15 | builder.Write(new HelpContext(builder, command, writer)); 16 | } 17 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/RootCommandTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using FluentAssertions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Tests 8 | { 9 | public class RootCommandTests 10 | { 11 | [Fact] 12 | public void Root_command_name_defaults_to_executable_name() 13 | { 14 | var rootCommand = new RootCommand(); 15 | 16 | rootCommand.Name.Should().Be(RootCommand.ExecutableName); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/TestApps/NativeAOT/NativeAOT.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | $(TargetFrameworkForNETSDK) 6 | 7 | false 8 | true 9 | Guard 10 | 11 | 12 | 13 | ..\..\..\System.CommandLine\bin\Release\$(TargetFrameworkForNETSDK)\System.CommandLine.dll 14 | 15 | 16 | 17 | 18 | $(SystemCommandLineDllPath) 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/TestApps/NativeAOT/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.CommandLine; 3 | using System.CommandLine.Parsing; 4 | 5 | public class Program 6 | { 7 | private static int Main(string[] args) 8 | { 9 | Option boolOption = new ("--bool", "-b") { Description = "Bool option" }; 10 | Option stringOption = new ("--string", "-s") { Description = "String option" }; 11 | 12 | RootCommand command = new () 13 | { 14 | boolOption, 15 | stringOption 16 | }; 17 | 18 | command.SetAction(Run); 19 | 20 | return new CommandLineConfiguration(command).Invoke(args); 21 | 22 | void Run(ParseResult parseResult) 23 | { 24 | Console.WriteLine($"Bool option: {parseResult.GetValue(boolOption)}"); 25 | Console.WriteLine($"String option: {parseResult.GetValue(stringOption)}"); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/TestApps/Trimming/Program.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using System.CommandLine.Invocation; 3 | 4 | Argument fileArgument = new ("file"); 5 | fileArgument.AcceptLegalFileNamesOnly(); 6 | 7 | RootCommand command = new () 8 | { 9 | fileArgument 10 | }; 11 | 12 | command.SetAction(parseResult => 13 | { 14 | Console.Write($"The file you chose was: {parseResult.GetValue(fileArgument)}"); 15 | }); 16 | 17 | command.Parse(args).Invoke(); 18 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/TestApps/Trimming/Trimming.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | $(TargetFrameworkForNETSDK) 6 | enable 7 | enable 8 | true 9 | false 10 | 11 | 12 | 13 | ..\..\..\System.CommandLine\bin\Release\$(TargetFrameworkForNETSDK)\System.CommandLine.dll 14 | 15 | 16 | 17 | 18 | $(SystemCommandLineDllPath) 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/TestCliActions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Invocation; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace System.CommandLine.Tests; 9 | 10 | public class SynchronousTestAction : SynchronousCommandLineAction 11 | { 12 | private readonly Action _invoke; 13 | 14 | public SynchronousTestAction(Action invoke, bool terminating = true) 15 | { 16 | _invoke = invoke; 17 | Terminating = terminating; 18 | } 19 | 20 | public override int Invoke(ParseResult parseResult) 21 | { 22 | _invoke(parseResult); 23 | return 0; 24 | } 25 | } 26 | 27 | public class AsynchronousTestAction : AsynchronousCommandLineAction 28 | { 29 | private readonly Action _invoke; 30 | 31 | public AsynchronousTestAction(Action invoke, bool terminating = true) 32 | { 33 | _invoke = invoke; 34 | Terminating = terminating; 35 | } 36 | 37 | public override Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken = default) 38 | { 39 | _invoke(parseResult); 40 | return Task.FromResult(0); 41 | } 42 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/LinuxOnlyTheory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Tests.Utility 8 | { 9 | public class LinuxOnlyTheory : TheoryAttribute 10 | { 11 | public LinuxOnlyTheory() 12 | { 13 | if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) 14 | { 15 | Skip = "This test requires Linux to run"; 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/NonWindowsOnlyFactAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.DotNet.PlatformAbstractions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Tests.Utility 8 | { 9 | public class NonWindowsOnlyFactAttribute : FactAttribute 10 | { 11 | public NonWindowsOnlyFactAttribute() 12 | { 13 | if (RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows) 14 | { 15 | Skip = "This test requires non-Windows to run"; 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/ParseResultExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Invocation; 2 | using System.IO; 3 | 4 | namespace System.CommandLine.Tests 5 | { 6 | internal static class ParseResultExtensions 7 | { 8 | internal static string Diagram(this ParseResult parseResult) 9 | { 10 | TextWriter outputBefore = parseResult.Configuration.Output; 11 | 12 | try 13 | { 14 | parseResult.Configuration.Output = new StringWriter(); 15 | ((SynchronousCommandLineAction)new DiagramDirective().Action!).Invoke(parseResult); 16 | return parseResult.Configuration.Output.ToString() 17 | .TrimEnd(); // the directive adds a new line, tests that used to rely on Diagram extension method don't expect it 18 | } 19 | finally 20 | { 21 | // some of the tests check the Output after getting the Diagram 22 | parseResult.Configuration.Output = outputBefore; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/ReleaseBuildOnlyFactAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Xunit; 5 | 6 | namespace System.CommandLine.Tests.Utility 7 | { 8 | public class ReleaseBuildOnlyFactAttribute : FactAttribute 9 | { 10 | public ReleaseBuildOnlyFactAttribute() 11 | { 12 | #if DEBUG 13 | Skip = "This test runs only on Release builds."; 14 | #endif 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/ReleaseBuildOnlyTheoryAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Xunit; 5 | 6 | namespace System.CommandLine.Tests.Utility; 7 | 8 | public class ReleaseBuildOnlyTheoryAttribute : TheoryAttribute 9 | { 10 | public ReleaseBuildOnlyTheoryAttribute() 11 | { 12 | #if DEBUG 13 | Skip = "This test runs only on Release builds."; 14 | #endif 15 | } 16 | } -------------------------------------------------------------------------------- /src/System.CommandLine.Tests/Utility/WindowsOnlyFactAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.DotNet.PlatformAbstractions; 5 | using Xunit; 6 | 7 | namespace System.CommandLine.Tests.Utility 8 | { 9 | public class WindowsOnlyFactAttribute : FactAttribute 10 | { 11 | public WindowsOnlyFactAttribute() 12 | { 13 | if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Windows) 14 | { 15 | Skip = "This test requires Windows to run"; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/System.CommandLine/Binding/ArgumentConversionResultType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Binding 5 | { 6 | internal enum ArgumentConversionResultType 7 | { 8 | NoArgument, // NoArgumentConversionResult 9 | Successful, // SuccessfulArgumentConversionResult 10 | Failed, // FailedArgumentConversionResult 11 | FailedArity, // FailedArgumentConversionArityResult 12 | FailedType, // FailedArgumentTypeConversionResult 13 | FailedTooManyArguments, // TooManyArgumentsConversionResult 14 | FailedMissingArgument, // MissingArgumentConversionResult 15 | } 16 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Binding/TryConvertArgument.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.CommandLine.Parsing; 5 | 6 | namespace System.CommandLine.Binding 7 | { 8 | internal delegate bool TryConvertArgument( 9 | ArgumentResult argumentResult, 10 | out object? value); 11 | } -------------------------------------------------------------------------------- /src/System.CommandLine/CommandLineConfigurationException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine; 5 | 6 | /// 7 | /// Indicates that a command line configuration is invalid. 8 | /// 9 | public class CommandLineConfigurationException : Exception 10 | { 11 | /// 12 | public CommandLineConfigurationException(string message) : base(message) 13 | { 14 | } 15 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Completions/SuggestDirective.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Invocation; 2 | 3 | namespace System.CommandLine.Completions; 4 | 5 | /// 6 | /// Enables the use of the [suggest] directive which when specified in command line input short circuits normal command handling and writes a newline-delimited list of suggestions suitable for use by most shells to provide command line completions. 7 | /// 8 | /// The dotnet-suggest tool requires the suggest directive to be enabled for an application to provide completions. 9 | public sealed class SuggestDirective : Directive 10 | { 11 | private CommandLineAction? _action; 12 | 13 | /// 14 | public SuggestDirective() : base("suggest") 15 | { 16 | } 17 | 18 | /// 19 | public override CommandLineAction? Action 20 | { 21 | get => _action ??= new CompletionAction(this); 22 | set => _action = value ?? throw new ArgumentNullException(nameof(value)); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/System.CommandLine/ConsoleHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace System.CommandLine 7 | { 8 | internal static class ConsoleHelpers 9 | { 10 | private static readonly bool ColorsAreSupported = GetColorsAreSupported(); 11 | 12 | private static bool GetColorsAreSupported() 13 | #if NET7_0_OR_GREATER 14 | => !(OperatingSystem.IsBrowser() || OperatingSystem.IsAndroid() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS()) 15 | #else 16 | => !(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) 17 | || RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) 18 | || RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) 19 | || RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS"))) 20 | #endif 21 | && !Console.IsOutputRedirected; 22 | 23 | internal static void SetTerminalForegroundRed() 24 | { 25 | if (ColorsAreSupported) 26 | { 27 | Console.ForegroundColor = ConsoleColor.Red; 28 | } 29 | } 30 | 31 | internal static void ResetTerminalForegroundColor() 32 | { 33 | if (ColorsAreSupported) 34 | { 35 | Console.ResetColor(); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/System.CommandLine/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | 7 | namespace System.CommandLine 8 | { 9 | /// 10 | /// Provides a set of methods for querying objects that implement . 11 | /// 12 | internal static class EnumerableExtensions 13 | { 14 | internal static IEnumerable FlattenBreadthFirst( 15 | this IEnumerable source, 16 | Func> children) 17 | { 18 | var queue = new Queue(); 19 | 20 | foreach (var item in source) 21 | { 22 | queue.Enqueue(item); 23 | } 24 | 25 | while (queue.Count > 0) 26 | { 27 | var current = queue.Dequeue(); 28 | 29 | foreach (var option in children(current)) 30 | { 31 | queue.Enqueue(option); 32 | } 33 | 34 | yield return current; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Help/HelpAction.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Invocation; 2 | 3 | namespace System.CommandLine.Help 4 | { 5 | /// 6 | /// Provides command line help. 7 | /// 8 | public sealed class HelpAction : SynchronousCommandLineAction 9 | { 10 | private HelpBuilder? _builder; 11 | 12 | /// 13 | /// Specifies an to be used to format help output when help is requested. 14 | /// 15 | internal HelpBuilder Builder 16 | { 17 | get => _builder ??= new HelpBuilder(Console.IsOutputRedirected ? int.MaxValue : Console.WindowWidth); 18 | set => _builder = value ?? throw new ArgumentNullException(nameof(value)); 19 | } 20 | 21 | /// 22 | public override int Invoke(ParseResult parseResult) 23 | { 24 | var output = parseResult.Configuration.Output; 25 | 26 | var helpContext = new HelpContext(Builder, 27 | parseResult.CommandResult.Command, 28 | output); 29 | 30 | Builder.Write(helpContext); 31 | 32 | return 0; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Invocation/AnonymousAsynchronousCommandLineAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace System.CommandLine.Invocation; 8 | 9 | internal sealed class AnonymousAsynchronousCommandLineAction : AsynchronousCommandLineAction 10 | { 11 | private readonly Func> _asyncAction; 12 | 13 | internal AnonymousAsynchronousCommandLineAction(Func> action) 14 | => _asyncAction = action; 15 | 16 | /// 17 | public override Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken = default) => 18 | _asyncAction(parseResult, cancellationToken); 19 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Invocation/AnonymousSynchronousCommandLineAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Invocation; 5 | 6 | internal sealed class AnonymousSynchronousCommandLineAction : SynchronousCommandLineAction 7 | { 8 | private readonly Func _syncAction; 9 | 10 | internal AnonymousSynchronousCommandLineAction(Func action) 11 | => _syncAction = action; 12 | 13 | /// 14 | public override int Invoke(ParseResult parseResult) => 15 | _syncAction(parseResult); 16 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Invocation/AsynchronousCommandLineAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace System.CommandLine.Invocation; 8 | 9 | /// Defines an asynchronous behavior associated with a command line symbol. 10 | public abstract class AsynchronousCommandLineAction : CommandLineAction 11 | { 12 | /// 13 | /// Performs an action when the associated symbol is invoked on the command line. 14 | /// 15 | /// Provides the parse results. 16 | /// The token to monitor for cancellation requests. 17 | /// A value that can be used as the exit code for the process. 18 | public abstract Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken = default); 19 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Invocation/CommandLineAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Invocation; 5 | 6 | /// 7 | /// Defines a behavior associated with a command line symbol. 8 | /// 9 | public abstract class CommandLineAction 10 | { 11 | private protected CommandLineAction() 12 | { 13 | } 14 | 15 | /// 16 | /// Indicates that the action terminates a command line invocation, and later actions are skipped. 17 | /// 18 | public bool Terminating { get; protected init; } = true; 19 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Invocation/SynchronousCommandLineAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Invocation; 5 | 6 | /// 7 | /// Defines a synchronous behavior associated with a command line symbol. 8 | /// 9 | public abstract class SynchronousCommandLineAction : CommandLineAction 10 | { 11 | /// 12 | /// Performs an action when the associated symbol is invoked on the command line. 13 | /// 14 | /// Provides the parse results. 15 | /// A value that can be used as the exit code for the process. 16 | public abstract int Invoke(ParseResult parseResult); 17 | } -------------------------------------------------------------------------------- /src/System.CommandLine/ParseDiagramDirective.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Invocation; 2 | using System.CommandLine.Parsing; 3 | 4 | namespace System.CommandLine 5 | { 6 | /// 7 | /// Enables the use of the [diagram] directive, which when specified on the command line will short 8 | /// circuit normal command handling and display a diagram explaining the parse result for the command line input. 9 | /// 10 | public sealed class DiagramDirective : Directive 11 | { 12 | private CommandLineAction? _action; 13 | 14 | /// 15 | /// Writes a diagram of the parse result to the output. 16 | /// 17 | public DiagramDirective() : base("diagram") 18 | { 19 | } 20 | 21 | /// 22 | public override CommandLineAction? Action 23 | { 24 | get => _action ??= new ParseDiagramAction(ParseErrorReturnValue); 25 | set => _action = value ?? throw new ArgumentNullException(nameof(value)); 26 | } 27 | 28 | /// 29 | /// Gets or sets the return value, which can be used as an exit code, when parsing encounters an error. 30 | /// 31 | public int ParseErrorReturnValue { get; set; } = 1; 32 | } 33 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Parsing/DirectiveResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace System.CommandLine.Parsing 4 | { 5 | /// 6 | /// A result produced when parsing an . 7 | /// 8 | public sealed class DirectiveResult : SymbolResult 9 | { 10 | private List? _values; 11 | 12 | internal DirectiveResult(Directive directive, Token token, SymbolResultTree symbolResultTree) 13 | : base(symbolResultTree, null) // directives don't belong to any command 14 | { 15 | Directive = directive; 16 | Token = token; 17 | } 18 | 19 | /// 20 | /// Parsed values of [name:value] directive(s). 21 | /// 22 | /// Can be empty for [name] directives. 23 | public IReadOnlyList Values => _values is null ? Array.Empty() : _values; 24 | 25 | /// 26 | /// The directive to which the result applies. 27 | /// 28 | public Directive Directive { get; } 29 | 30 | /// 31 | /// The token that was parsed to specify the directive. 32 | /// 33 | public Token Token { get; } 34 | 35 | internal void AddValue(string value) => (_values ??= new()).Add(value); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/System.CommandLine/Parsing/ParseError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Parsing 5 | { 6 | /// 7 | /// Describes an error that occurs while parsing command line input. 8 | /// 9 | public sealed class ParseError 10 | { 11 | internal ParseError( 12 | string message, 13 | SymbolResult? symbolResult = null) 14 | { 15 | if (string.IsNullOrWhiteSpace(message)) 16 | { 17 | throw new ArgumentException("Value cannot be null or whitespace.", nameof(message)); 18 | } 19 | 20 | Message = message; 21 | SymbolResult = symbolResult; 22 | } 23 | 24 | /// 25 | /// A message to explain the error to a user. 26 | /// 27 | public string Message { get; } 28 | 29 | /// 30 | /// The symbol result detailing the symbol that failed to parse and the tokens involved. 31 | /// 32 | public SymbolResult? SymbolResult { get; } 33 | 34 | /// 35 | public override string ToString() => Message; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/System.CommandLine/Parsing/SymbolResultExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.Parsing 7 | { 8 | internal static class SymbolResultExtensions 9 | { 10 | internal static IEnumerable AllSymbolResults(this CommandResult commandResult) 11 | { 12 | yield return commandResult; 13 | 14 | foreach (var item in commandResult 15 | .Children 16 | .FlattenBreadthFirst(o => o.SymbolResultTree.GetChildren(o))) 17 | { 18 | yield return item; 19 | } 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /src/System.CommandLine/Parsing/TokenType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine.Parsing 5 | { 6 | /// 7 | /// Identifies the type of a . 8 | /// 9 | public enum TokenType 10 | { 11 | /// 12 | /// An argument token. 13 | /// 14 | /// 15 | Argument, 16 | 17 | /// 18 | /// A command token. 19 | /// 20 | /// 21 | Command, 22 | 23 | /// 24 | /// An option token. 25 | /// 26 | /// 27 | Option, 28 | 29 | /// 30 | /// A double dash (--) token, which changes the meaning of subsequent tokens. 31 | /// 32 | DoubleDash, 33 | 34 | /// 35 | /// A directive token. 36 | /// 37 | /// 38 | Directive 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/System.CommandLine/Parsing/TryReplaceToken.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace System.CommandLine.Parsing; 7 | 8 | /// 9 | /// Replaces a token with one or more other tokens prior to parsing. 10 | /// 11 | public delegate bool TryReplaceToken( 12 | string tokenToReplace, 13 | out IReadOnlyList? replacementTokens, 14 | out string? errorMessage); -------------------------------------------------------------------------------- /src/System.CommandLine/SymbolNode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.CommandLine 5 | { 6 | internal sealed class SymbolNode 7 | { 8 | internal SymbolNode(Symbol symbol, Command? parent = null) 9 | { 10 | Symbol = symbol; 11 | Parent = parent; 12 | } 13 | 14 | internal Symbol Symbol { get; } 15 | 16 | internal Command? Parent { get; } 17 | 18 | internal SymbolNode? Next { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/System.CommandLine/System.CommandLine.Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/System.CommandLine/System.Runtime.CompilerServices/IsExternalInit.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace System.Runtime.CompilerServices; 5 | 6 | internal static class IsExternalInit 7 | { 8 | } --------------------------------------------------------------------------------