Giter Site home page Giter Site logo

dotnet / command-line-api Goto Github PK

View Code? Open in Web Editor NEW
3.3K 260.0 371.0 5.96 MB

Command line parsing, invocation, and rendering of terminal output.

Home Page: https://github.com/dotnet/command-line-api/wiki

License: MIT License

Batchfile 0.03% Shell 6.77% PowerShell 9.53% C# 82.86% CMake 0.81%
command-line parser parsing vt100 terminal posix completions dotnet-standard dotnet-core commandlineparser

command-line-api's Introduction

Build Status Join the chat at https://gitter.im/dotnet/command-line-api

This repository contains the code for the System.CommandLine libraries and the dotnet-suggest global tool.

Packages

Package Version Description
System.CommandLine Nuget Command line parser, model binding, invocation, shell completions
System.CommandLine.DragonFruit Nuget Build command-line apps by convention with a strongly-typed Main method
System.CommandLine.Hosting Nuget support for using System.CommandLine with Microsoft.Extensions.Hosting
dotnet-suggest Nuget A command-line tool to provide shell completions for apps built using System.CommandLine.

Daily Builds

Daily builds are available if you add this feed to your nuget.config: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json

Versions are listed at: https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-libraries/NuGet/System.CommandLine/versions

Documentation

The System.CommandLine documentation can now be found at Microsoft Learn.

Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information, see the .NET Foundation Code of Conduct

Contributing

See the Contributing guide for developer documentation.

License

This project is licensed under the MIT license.

.NET Foundation

.NET is a .NET Foundation project.

command-line-api's People

Contributors

adamsitnik avatar adamskt avatar apogeeoak avatar bobsilent avatar brettfo avatar christianrondeau avatar colombod avatar dotnet-maestro[bot] avatar fredrikhr avatar icontech avatar jeredm avatar jonsequitur avatar kathleendollard avatar keboo avatar kosat avatar markmichaelis avatar mmitche avatar natemcmaster avatar pieter-venter avatar sf-jbazuzi avatar sfoslund avatar stevebyerly avatar stevel-msft avatar tannergooding avatar tdashworth avatar tmds avatar tomservo3k avatar viktorhofer avatar vlada-shubina avatar wojciechnagorski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

command-line-api's Issues

Create a provider that uses a method signature to define the command line provider

e.g. Given a method DoStuff(Height argumentHeight = Height.High, param string[] arguments)
and enum Height { High, Medium, Low }
we would determine:

  • Command = DoStuff
  • Sub-commands = N/A (not supported)
  • Options = N/A (not supported)
  • Arguments = argumentHeight (with default to Height.High)
  • Unparsed/unmatched? tokens = arguments (optional)

E.g.:
void MainWish( string firstName, string lastName) {...} static void Main(args) { var result = CommandLine.Parse(MainWish, args); }

Questions:

  • Could you use overloading to provide multiple commands? Likely no, because of ambiguity and type coercion
  • Should we support a naming convention to identify command, options, arguments (i.e. DoStuff(string commandJump, string optionHowHigh, Height argumentHeight)
  • Do we support attributes on methods and parameters (adding support for things like aliases?

Handling suggestion sort order?

If the provider calls Define.Arguments().FromAmong("high","medium").FromAmong("low") should we sort the suggestion list alphabetically or in the order that configured?

Rename core classes dot be Definition and Instance based

Rename the following:

  • Option => OptionDefition
  • ArgumentRuleBuilder => ArgumentDefinitionBuilder
  • ArgrumentsRule => ArgumentDefinition
  • Symbol = > SymbolDefinition
  • ParsedOption => Option
  • ParsedCommand => Command
  • ParsedSymbol => Symbol

The entry point for the library was not obvious

At the hackathon many (most?) people struggled to find the appropriate entry point for the library.

Things people tried:

  • ArgumentParser
  • Parser

Feedback was that people wanted something similar to CommandLineApp CommandLineParser, etc.

Support argument assignment immediately following option name

  • Asignment of option values via ''
    i.e. 'getuser.exe -nInigo`
    Note, this is supported by POSIX

Question:

  • This would presumably be mutually exclusive when abbreviation/startswith is active?
  • Does this only work for single character names or can a full name be used?

Allow arguments for options using position rather than name

Given getuser.exe -firstName <userName> -age <age> is an invokation of getuser.exe inigo 42 supported? PowerShell allows this and extremely common.

If the name is not required when invoking the command then:

  • the argument is always the value of an option
  • commands don't have arguments
  • commands only contain sub-commands and options
  • arguments don't exist without a corresponding option

Ensure support fordotnet user-secrets set [arguments] [options]

Global completions and syntax definition registry

One high-level goal of the core library is to enable contextual completions for any program written using its core library.

This is currently enabled in dotnet using three pieces:

  • The parser configuration, written in C# against the predecessor library, Microsoft.DotNet.Cli.CommandLine,
  • Adding a shell-specific shim script (e.g. Powershell, zsh, bash), which calls dotnet complete to get completions, into one's shell profile, and
  • The dotnet complete command.

This set of capabilities should be provided with minimal effort by System.CommandLine. This could work as follows:

  • A parser configuration is serializable into a well-known format.
  • That well-known format is deserializable by System.CommandLine into a functioning parser.
  • Registration of the application's serialized, version-specific parse model is automated by a method call provided by System.CommandLine. On registration, the serialized parser configuration is written to a well-known location on disk.
  • A script is registered for the specified completion prefix (e.g. "dotnet" in one of the above-linked shim scripts) which directs the shell's completion requests to a dotnet global command or a more generalized implementation of dotnet complete, which then provides completions based on deserialization of the parser configuration.
  • In more dynamic cases where the completions can't be included in the serialized parser definition (e.g. dotnet add package โ‡ฅ), a forwarding command definition can be used to redirect the completion requests to the implementing command line application.
  • System.CommandLine should provide a very simple method (such as composability of arbitrary subcommands, some of which can be provided by the core library) to provide support for the equivalent of a dotnet complete command following the same protocol.

A couple if potential benefits of this approach:

  • Completions can be provided for commands for which the completion author does not own the code.
  • Non-.NET commands that adhere to the parser definition protocol can participate.

Decide on the general name of the "Providers" (formerly "Opinion")

During the design meetings we identified the various DSL providers (then called Opinions): C# Class, Fluent API, DocOpt, declarative file, etc.

We need to decide on the name general name for each of these providers. Some ideas include:
DslProvider, App Model, Programming Model, etc.

What does our lexer support?

What does our lexer support:

  • Named options where order doesn't matter.
    i.e. getuser.exe -first Inigo -last Montoya or getuser.exe -last Montoya -first Inigo
    DO:Done
  • Un-named command line arguments where the option name is determined by the argument position (when programming the option name is still required).
    i.e. getuser.exe Inigo Montoya
    DO: See #29.
  • Repeated use of the same option with the option name mulitple times
    i.e. getuser.exe -name Paul -name Mary
    DO:Done
  • Repeated use of the same option using a comma between the arguments
    i.e. getuser.exe -name Paul,Mary
    DO: See #37
  • Bundling of single character options
    i.e createuser.exe Inigo -force -administrator becomes createuser.exe -fa where f and a are aliases for force and administrator
    DO:Done
  • Abbreviations
    i.e. getuser.exe -fi Inigo -las Montoya
    DO: See #38 (lower priority)
  • Asignment of option values via '=', ' ', ':'
    i.e. 'getuser.exe -firstname = 'Inigo'
    DO: Done
  • Asignment of option values via ''
    i.e. 'getuser.exe -nInigo`
    DO: See #39

...

Add support for the equivalent of the dotnet parse command

dotnet parse is a helpful tool that gives developers working with the parser in the context of dotnet a way to evaluate a given command line, e.g.:

c:\my-project>dotnet parse "dotnet add package -v 2.0.0 System.CommandLine"
[ dotnet [ add [ package [ --version <2.0.0> ] <System.CommandLine> ] <c:\my-project\> ] ]

This functionality would be similarly helpful to any developers building tools using System.CommandLine.

One approach to supporting this might be to let System.CommandLine expose a class derived from Command, such as ParseCommand, that can be composed into a developer's ParserConfiguration.

Provide a means to specify a description in the root command.

Once specifying the description for the root command, it will be displayed in the description of what the executable does.

E.g., "Starts a new instance of the Windows command interpreter." would appear as:
`

cmd /?
Starts a new instance of the Windows command interpreter
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]
...
`

Consider improving ArgumentRule API design

The ArgumentRule returns null to indicate success and an error to indicate failure. It would be good to improve this API to have a clearer interface for validation.

Furthermore, the ArgumentRule takes a Func, it would be good to improve this API in general - likely with an interface.

Test failure: When_there_are_subcommands_and_options_then_a_subcommand_must_be_provided

Test Name:	System.CommandLine.Tests.ParsingValidationTests.When_there_are_subcommands_and_options_then_a_subcommand_must_be_provided
Test FullName:	System.CommandLine.Tests.ParsingValidationTests.When_there_are_subcommands_and_options_then_a_subcommand_must_be_provided
Test Source:	C:\dev\dotnet\System.CommandLine\src\System.CommandLine.Tests\ParsingValidationTests.cs : line 182
Test Outcome:	Failed
Test Duration:	0:00:00.095

Result StackTrace:	
at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions.Net45\Execution\XUnit2TestFramework.cs:line 32
   at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args) in C:\projects\fluentassertions-vf06b\Src\Core\Execution\AssertionScope.cs:line 197
   at FluentAssertions.Collections.SelfReferencingCollectionAssertions`2.ContainSingle(Expression`1 predicate, String because, Object[] becauseArgs) in C:\projects\fluentassertions-vf06b\Src\Core\Collections\SelfReferencingCollectionAssertions.cs:line 492
   at System.CommandLine.Tests.ParsingValidationTests.When_there_are_subcommands_and_options_then_a_subcommand_must_be_provided()
Result Message:	Expected collection to contain a single item matching ((e.Message == "Required command was not provided.") AndAlso (e.ParsedSymbol.Name == "inner")), but no such item was found.
Result StandardOutput:	
[ outer [ inner <arg> ] ]
the-message

This reproduces consistently in Debug, but not release. There appears to be some kind of race condition in the tests. The output "the-message" comes from another test, Default_validation_messages_can_be_replaced_in_order_to_add_localization_support.

cc @jonsequitur

Consider removing "Create" Option/Command/Argument pattern

Currently, we have sample code that uses the Create method to instantiate an Option or Command. Consider removing this pattern in favor of another - such as invoking the constructor.

One argument in favor of not using Create is that it isn't obvious from intellisense. C# programmers are used to seeing new. Without seeing an example, Create.Option(...) is not obvious.

Remove or rationalize indexers

Currently, the following classes have indexers:

  • OptionResult (returns Option)
  • CommandResult (returns Option)
  • SymbolSet<T> (returns T, which can be Symbol or SymbolDefinition in various cases)

Their presence and behavior is not always clear. Should we remove them?

Consider a Tuple DSL

Consider creating a DSL that takes and returns a tuple.

Ideas:
Result<(string firstName, string lastName)> result = Parser.Parse( (Option option1, Option option2), args) (string firstName, string lastName) = result.Value foreach(string error in result.Errors) { Console.WriteLine(result.Errors); }

Only return suggestions for options after prefix is specified

Given command: Dosomething.exe move --x 5 --y 42
The input dosomething move would return suggestions for --x and --y. However, (seemingly) many tools don't provide suggestions until after the prefix is specified (see posh-git and powershell).

Questions:
[ ] What should the default behavior be?
[ ] Should we support both scenarios (if yes create issue)?

The debug display is not obvious

When viewing the ParseResult in the debug views, the current display shows the parsed string. This is not enough for people trying to learn the library. This is especially true for Symbol SymbolDefinition` and their derived classes. The debug display should provide enough information to make the debug views useful for discovering what types are being displayed.

Does "Core" assume that arguments 'Always' have to be ordered?

Given getuser.exe <username> <age>, two or more arguments, where age can only be an integer and username cannot be an integer, do we provide any functionality try to coerce into username and age values regardless of argument order?

Note:

  • It is possible to sometimes programmatically determine the order.
  • If we can't determine the order we can report an error that arguments are ambiguous.
  • The programmer can always convert the arguments to a string array (or two string arguments) and then address order independently from us.

Add Parse overloads

One of the Parser.Parse method currently takes in an IReadOnlyCollection<string>. This was not intuitive to several people. Add an overload that accepts a string[]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.