Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DashDash (--) doesn't work properly with multi-value options #605

Open
robnasby opened this issue Mar 23, 2020 · 4 comments
Open

DashDash (--) doesn't work properly with multi-value options #605

robnasby opened this issue Mar 23, 2020 · 4 comments

Comments

@robnasby
Copy link

robnasby commented Mar 23, 2020

When using the "DashDash" feature, the results are unexpected when using a multi-valued option.

Single-valued option (base case)

Program.cs

    class Program
    {
        #region Main

        static int Main(string[] args)
        {
            return new Parser(with => with.EnableDashDash = true)
                    .ParseArguments<CommandLineOptions>(args)
                    .MapResult(options => RunWrappedExecutable(options),
                               _ => -2);
        }

        #endregion
    }

CommandLineOptions.cs

    class CommandLineOptions
    {
        #region Properties

        [Option('o', "option")]
        public string Option { get; set; }

        [Value(0)]
        public IEnumerable<string> Values { get; set; }

        #endregion
    }

Running the program as follows:

foo.exe -o "option" -- value1 value2 value3

produces the (expected) results:

options.Option = "option"
options.Values = [ "value1", "value2", "value3" ]

Multi-valued option (broken case)

CommandLineOptions.cs

    class CommandLineOptions
    {
        #region Properties

        [Option('o', "option")]
        public IEnumerable<string> Option { get; set; }

        [Value(0)]
        public IEnumerable<string> Values { get; set; }

        #endregion
    }

Running the program as follows:

foo.exe -o "option" -- value1 value2 value3

produces the (unexpected) results:

options.Option = [ "option", "value1", "value2", "value3" ]
options.Values = [ ]

Conclusion

My expectation is that any arguments after the -- would be processed as values, rather than options. Can you confirm my expectations match yours? If so, I'm happy to try to resolve this issue and submit a PR. Thanks!

@robnasby
Copy link
Author

robnasby commented Mar 25, 2020

After digging into the source, the issue is a loss of context during tokenization. Arguments after the double dash are of type Value, but they are combined with the tokens generated from arguments before the double dash. During parsing, when the multi-value Name token is encountered, it grabs all subsequent Value tokens, since it has no way to distinguish between those before the double dash and those after.

One way to resolve this is to introduce a new token type ValueForced, which can never be attributed to an option property. This should force them to go to value properties (and trigger an error if there are no value properties available).

@moh-hassan
Copy link
Collaborator

moh-hassan commented Apr 13, 2020

My expectation is that any arguments after the -- would be processed as values, rather than options.

Yes, you are correct.
The only effect of double dash '--' is terminating all options and any following arguments are treated as non-option arguments, even if they begin with a hyphen and can't be used for partitioning values.

so parsing

-o option1  -- value1 --value2 value3

will be
-o: option token
option1 value1 --value2 value3 : value token and will be assigned to 'Option' Enumerator.

Value token has a property ExplicitlyAssigned which is true when parser split the option of IEnumerable<string> otherwise it's false.

Edit:
In the scenario 'Multi-valued option' I find #607 merged with both #594 and #610 solved it nicely.

@icedoor
Copy link

icedoor commented Dec 7, 2020

Hi! I am trying to understand when this is going to be fixed. There is a lot of issues related to it but I understand this as the root issue.
I am currently having this exact issue. I have tried version 2.8.0 and the new 2.9.0-preview1.
Is there some kind of workaround to actually make -- split multi-options and values?'
(I do have EnableDashDash = true)

The expected behavior of -o first second -- some -cool "--values 1 2 3" would be:

-o : [ "first", "second" ]
values: [ "some", "-cool", "--values 1 2 3" ]

Where o is an IEnumerable.

Thanks

@Kimi-Arthur
Copy link

Hi there,

What's the status of this issue? It looks to me that it's recognized as a bug to be fixed? It really bothers me as there is virtually no way to combine IEnumerable Option with Value. I have to split a single string argument instead of IEnumerable, which looks ugly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants