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

Add mode for optional option-argument from embedded value only (POSIX style) #1901

Closed
shadowspawn opened this issue Jul 4, 2023 · 5 comments

Comments

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jul 4, 2023

Short version: support POSIX style parsing mode which only reads optional value with embedded forms --optional=VALUE and -oVALUE.

Say: program.optionOptionalValuesEmbedded()

(Shorter meaningful name suggestions welcome!)


Long version

Commander supports an option which may be used as a boolean option but may optionally take an option-argument (declared with square brackets like -o, --opt [value]). This can lead to parsing ambiguities due to the space-separated VALUE being confused with non-option arguments.

These are all the optional variations:

foo --optional
foo -o
foo --optional VALUE
foo -o VALUE
foo --optional=VALUE
foo -oVALUE

POSIX takes a stricter approach, which avoids the parsing ambiguity. The option-argument has to be embedded with the option.

If the SYNOPSIS shows an optional option-argument (as with [ -f[option_argument]] in the example), a conforming application shall place any option-argument for that option directly adjacent to the option in the same argument string, without intervening characters. If the utility receives an argument containing only the option, it shall behave as specified in its description for an omitted option-argument; it shall not treat the next argument (if any) as the option-argument for that option.

So the POSIX approach only allows:

foo --optional
foo -o
foo --optional=VALUE
foo -oVALUE

Reference:

@aweebit
Copy link
Contributor

aweebit commented Jul 4, 2023

I haven't contributed to open source before and am not really acquainted with testing, but this look like something I could work on. I will try once I am finished with my current project.

I think a better name would be optionalOptionArgumentsEmbedded(), to use the wording from POSIX. strictOptionalOptionArguments() is also a good option (no pun intended), since it better reflects what the method actually implies. After all, embedded option-arguments can still be used when the method is not applied.

An important question is also how we want to inform users about the correct syntax. All solutions I can think of are a bit awkward. One is to format all of them like this: -o[argument], --option[=argument]. Another is to add a way to separate options with optional option-arguments from other options in the options list, so that a comment on their correct use could be added above, for example by running program.separateOptionsWithOptionalArguments(msg), which would produce an output like this one:

Usage: foo [options]

Options:
  -h, --help            display help for command
Following options' arguments are optional. The syntax is [-o[argument] | --option[=argument]]
  -1, --one [argument]  first option
  -2, --two [argument]  second option

@shadowspawn
Copy link
Collaborator Author

shadowspawn commented Jul 4, 2023

I like strictOptionalOptionArguments. Favourite so far.

Yes, the help syntax is interesting. Maybe -o, --option[=argument] which is compact but will lead to more questions about -o=value. The displayed syntax also overlaps with how options are defined in code, but work how how we want it to look to end-user first.

I'll do another look around at how this gets displayed. There must be plenty of applications using getsopts_long of which some use optional option arguments...

@shadowspawn shadowspawn changed the title Mode for optional option-argument from embedded value only (POSIX style) Add mode for optional option-argument from embedded value only (POSIX style) Jul 5, 2023
@shadowspawn
Copy link
Collaborator Author

shadowspawn commented Jul 5, 2023

I found these examples of utilities with "strict optional option arguments":

man make
       -j [jobs], --jobs[=jobs]

git checkout --help
       -t, --track[=(direct|inherit)]

man grep
     -C[num], --context[=num]

deno
  -r, --reload[=<CACHE_BLOCKLIST>...]

Details: The documentation for make is inaccurate, since it requires -jJOBS (no space). The Deno short format is -r=VALUE.

@aweebit
Copy link
Contributor

aweebit commented Jul 5, 2023

The grep way seems to be the most reasonable. What concerns me a little is the discrepancy between the formats that would arise from the fact that the option-argument is currently only displayed once for normal options. By contrast, grep repeats the option-argument: -f FILE, --file=FILE.

@shadowspawn
Copy link
Collaborator Author

This issue has not had any activity in over six months. It isn't likely to get acted on due to this report.

This is a favourite of mine since the POSIX embedded-only approach is a standard and avoids a bunch of ambiguous parsing situations, but only one person has responded. Closing this and see if there is future interest!

Feel free to open a new issue if it comes up again, with new information and renewed interest.

Thank you for your contributions.

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

No branches or pull requests

2 participants