GithubHelp home page GithubHelp logo

Comments (11)

sgillbee avatar sgillbee commented on July 21, 2024 7

How about allowing certain arguments to be definable as positional to allow mapping of positional arguments to strongly-typed arguments.

For example:

p.Setup(arg => arg.InputFile)
  .As('i', "input")
  .OrAsPositional();

p.Setup(arg => arg.OutputFile)
  .As('o', "output")
  .OrAsPositional();

This would parse "app.exe -i filename.txt -o outfile.txt" and also "app.exe filename.exe outfile.txt" and also "app.exe outfile.txt -i filename.txt. You could mix named and positional arguments in any order. Basically, the parser would split the command line into parsable segments. It would first assign all the named argumented. Then it would take all the positional arguments in order and map the to the list of unassigned arguments in the order they were defined in the code.

Examples:
app.exe -i filename.txt -o outfile.txt
This would parse into two named blocked and no positional blocks: "-i filename.txt" and "-o outfile.txt".
settings.InputFile == "filename.txt"
settings.OutputFile == "outfile.txt"
Nothing new here. Move along.

app.exe filename.txt outfile.txt
This would parse into two positional blocks: "filename.txt" and "outfile.txt". The would be assigned in order to properties tagged as OrAsPositional in the order they were defined (InputFile and then OutputFile)
settings.InputFile == "filename.txt"
settings.OutputFile == "outfile.txt"
Fairly straightforward since there is no mix of param types

app.exe outfile.txt -i filename.txt
This would parse into one positional block ("outfile.txt") and one named block ("-i filename.txt"). First the named block would be assigned so that:
settings.InputFile == "filename.txt"
Then the positional block would be assigned based on the order that properties have been assigned. First defined is InputFile, but it's already assigned. So next up is OutputFile. That's unassigned to assign "outfile.txt" to OutputFile.
settings.OutputFile == "outfile.txt"
Now you can mix and match positional and named arguments.

from fluent-command-line-parser.

siywilliams avatar siywilliams commented on July 21, 2024

Interesting, I've not used free arguments before.

May I ask what purpose do they serve, and how would you expect to consume them through the api? What if the same free argument was specified twice?

from fluent-command-line-parser.

pragmatrix avatar pragmatrix commented on July 21, 2024

Often a command has some primary function that is associated with one or more file-names or a host name, for example. In such cases it makes sense to pass them without an option. Prominent examples are echo, cat, or ssh.

I would prefer to retrieve the free arguments via callbacks in the DSL instead of going through a list of free arguments in the result interface, simply because free arguments may need to take part in the error checking. Right now free arguments are ignored and commands could run without being sure that all the user input was handled properly.

What should happen when the same free argument is passed twice to a command is up to the command's semantic. So either the DSL supports some additional parameterization or - if a callback is used - it just calls it for each in the order supplied.

I guess it could also happen that a free argument is just a shortcut that provides a value for one of the options, so there could also be a method that marks an option as the one that receives the free arguments by default.

from fluent-command-line-parser.

siywilliams avatar siywilliams commented on July 21, 2024

I'm going to spend some time soon working towards other features to include so I will see about how free arguments could fit into it. If you have any other suggestions I will be interested to hear them.

from fluent-command-line-parser.

pragmatrix avatar pragmatrix commented on July 21, 2024

One related thing I can remember is that some Linux commands support this -- marker. From the bash man page:

A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --.

This seems to be very useful for commands that wish to forward options and arguments to other commands. The API could look something like:

.PassThroughAfter("--")
  .Callback(remainingOptionOrArg => stuffIWantToForward.Add(remainingOptionOrArg))

from fluent-command-line-parser.

siywilliams avatar siywilliams commented on July 21, 2024

Work almost complete towards support for -- which disables further option parsing and treats all remaining arguments as additional for the current option.

Using your initial example:

MyConsoleApp.exe --opt1 opt1value Filename.txt Filename2.txt

CaptionAdditionalArguments(Action<IEnumerable<string>>) is used to now capture the free arguments Filename.txt and Filename2.txt

The setup looks like this

string value;
var freeArgs = new List<string>();

parser.Setup<string>("opt1")
      .Callback(str => value = str)
      .CaptureAdditionalArguments(freeArgs.AddRange);

// after parsing
// value is "opt1value"
// freeArgs contains "Filename.txt", "Filename2.txt"

It can also be used to safely handle negative integer and doubles

MyConsoleApp.exe --numbers -- -123 123 -789 789

can be safely parsed to a list of integers using

var numbers = new List<int>();

parser.Setup<int>("numbers")
      .Callback(numbers.AddRange);

// after parsing numbers contains
// -123
// 123
// -789
// 789

from fluent-command-line-parser.

pragmatrix avatar pragmatrix commented on July 21, 2024

Great work! But I'm not sure if your interpretation of the -- semantics is correct.

I don't think that arguments after -- should be linked to any option that comes before. From my experience, -- is used to capture a trailing set of free arguments, which may include unescaped options. These strings may then passed to subsequent shells / command line processors.

In bash for example, you can clearly separate the arguments that are given to the shell and the script it executes: bash --login -- test.sh --option_for_test_sh. Here, everything before the -- goes to bash, everything after the -- goes to test.sh.

from fluent-command-line-parser.

do0om avatar do0om commented on July 21, 2024

I agree with pragmatrix. It's like in git commit command (https://www.kernel.org/pub/software/scm/git/docs/git-commit.html) , the free arguments at the end represent a list of files, which are not linked to any of the previous options.
In my latest pull request, I didn't link arguments after "--" to any option.
I think this is why 6 tests are failing, our expectations are different.

from fluent-command-line-parser.

mbrenn avatar mbrenn commented on July 21, 2024

I also agree. Being able to parse something like

  • "a.exe input output -o options"

is a mandatory requirement for such a library, which is not satisfied here.

from fluent-command-line-parser.

graniv avatar graniv commented on July 21, 2024

UP

I also agree with @pragmatrix and @do0om. Could you add a semantics like this ?

In bash for example, you can clearly separate the arguments that are given to the shell and the script it executes: bash --login -- test.sh --option_for_test_sh. Here, everything before the -- goes to bash, everything after the -- goes to test.sh.

from fluent-command-line-parser.

ruslanfedoseenko avatar ruslanfedoseenko commented on July 21, 2024

You may look how other do that case. For example boost::program_options call this type of parameters Positional Options. Here is a small description. Hope it can help you to understed what they are.

from fluent-command-line-parser.

Related Issues (20)

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.