Open Ducatel opened 4 years ago
The EnableDashDash
option has nothing to do with allowing -Url
to be treated as --Url
. What it enables is the standard handling of a bare --
arg (that is, an argument that's just two dashes and nothing else) as it's normally handled by the GNU getopt_long() function, where a bare --
argument means "everything after this point is a value, not an option, even if it starts with a hyphen".
As for treating a single -
like a double --
as an option prefix, that's something this library will not do, because it's designed to mimic the behavior of GNU getopt, which requires a single -
before single-charcter options, and a double --
before double-character options. And single-charcter options can be mixed, so that someprog -a -v -x
can also be written as someprog -avx
and that will have the exact same effect. This is a longstanding GNU getopt feature that is built into the behavior of CommandLineProcessor, and there's no way to change it. This is why -Url
doesn't work: it's being treated as the combination of -U
, -r
and -l
single-character options, none of which exist in your options class.
The only way to do what you're wanting to do is to pre-process your incoming args before handing them to the Parser, so that all the single-hyphen args that don't fit the getopt style are turned into double hyphens. I'd suggest something like this:
var processedArgs = args.Select(arg => arg.Replace("-Url", "--Url").Replace("-monoapp", "--monoapp").Replace("-Ctx", "--Ctx"));
Or better yet, use regular expressions and put a ^
in front of each of those patterns to ensure that it will only match at the start of each arg string. That way you won't accidentally turn a URL like "http://some.server/cool-monoapp-example" into "http://some.server/cool--monoapp-example" and get a 404 later on.
Then you'll be able to hand the processedArgs
array to Parser and it should work for you.
BTW, the Separator
property of Option doesn't do what you think it does. It's only for specifying a separator character on list-like arguments, e.g. if you want "--files=file1,file2,file3" to be automatically turned into a list you'd let your Files property be of type IEnumerableSeparator=','
in the Options attribute. CommandLineParser will automatically understand either equals or space as being the separator for long-style arguments, so --arg=value
and --arg value
will both work on the commandline.
Arf ok...
So the only way for me to use commandlineparser
is to preprocess the command line.
The thing is, I have something like 200 different options (and will continue to grow). Then Add regex for each seems to not be a maintainable solution :sweat_smile:
So do you know and alternative library which can help me ?
Ps: thanks for all of those explanation :wink:
@Ducatel
I'm trying to parse a command line (imposed, no way to change it)
What is the OS you are using this commandline options? Do you pass these args to a 3rd party tool/engine?
@rmunn We can plan to extend the library to support other standard commandline options beside GNU standard like:
I tried FluentCommandLineParser
and PowerArgs
and cannotable to parse the command line also.
@moh-hassan The main target are windows 10 x64 but can also have some Windows server. I'm acting as a middleware, I received some commands and I organize call to external software/API.
@Ducatel
I'm acting as a middleware, I received some commands and I organize call to external software/API.
As you are acting as a middleware, you have a control to get your args as Gnu standard and then converting these options to match the external software/API.
@moh-hassan
As you are acting as a middleware, you have a control to get your args as Gnu standard and then converting these options to match the external software/API.
Of course I can manage the conversion of options, this is my work :D But I have no control on all input option. I don't understand why you thinks it's possible for me ?
I will try to find a generic way to convert the command line
Edit:
I find a quite simple generic way seem to work well. Do you see any possible problem with this ?
args = args.Select(arg => Regex.IsMatch(arg, "^-\\w{2,}") ? "-" + arg : arg ).ToArray();
@rmunn We can plan to extend the library to support other standard commandline options beside GNU standard like:
- Using single dash only as Posix standard/ Powershell and Unity Engine.
- Using forward slash to support legacy windows standard.
+1. It would be nice to support other standards.
For windows, its always been a problem that windows used / as the argument discriminator when used in POSIX situations. How does the library differentiate between creating a new directory /Url or downloading for the /Url specified?
Additionally, when you start introducing single dash options for long names, you create ambiguities that are unable to be resolved.
For example, if I have three boolean options, U
for underline, r
for display in red color, and l
for justify the text left, these short options can be combined into -url
If you also have an option called "Url" which would grab a url and print it, using the other -Url
options, then you have ambiguity... what is the parser to do?
Supporting different standards is beyond the scope of this project. The CommandLineParser library is entirely designed to support the GNU getopt standard of argument parsing. If somebody decides to fork the project and continue to utilize the core parsing, property resolution and value placements, thats fine.
The GNU getopt standard is tried and true, has existed for over two decades, and it pretty reliable, even by current standards. I personally do not want to begin to support the myriad of ambiguous scenarios that arise from mixing and matching different standards.
...Just my 2cents...
I published a PR that brings the option to define the parsing behavior for command line options, whether to use single or double dashes: #767
Maybe you could consider this PR to raise the satisfaction for some of your library consumers.
I am also writing a parser and have exactly the same issue. I tried to process command line to change single dash to double dashes, but occasionally I find a new test case for which change is not correct :) also I was thinking of a way to disable flag merging to not have ambiguity like -long <=> -l -o -n -g.
@rmunn We can plan to extend the library to support other standard commandline options beside GNU standard like:
- Using single dash only as Posix standard/ Powershell and Unity Engine.
- Using forward slash to support legacy windows standard.
I would like to comment in support of this planning. In my case, I am trying to use CommandLine for a Unity project, where a single dash in front of parameter names is unfortunately what is used. For now, I seem to be fine with the regex based conversion that is mentioned here: https://github.com/commandlineparser/commandline/issues/685#issuecomment-676275503
Hi everyone,
I'm trying to parse a command line (imposed, no way to change it) which are like
As you can see, there is a lot of different case:
And I wasn't able to parse it because it seems that when there is just a dash option, it mustn't be a long name. ( I have a lot of
UnknownOptionError
which seem to come from that)So I have a very simple code to test
So I did something wrong ? There is a way to parse this command line ?
Thanks in advance for your help