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

Feature request: Allow converting camelcase/snake-case proc arguments to standard Unix-style long options #28

Closed
kaushalmodi opened this issue May 17, 2018 · 7 comments

Comments

@kaushalmodi
Copy link
Contributor

Hello,

I am trying to use cligen to generate standard Unix-style long options like --foo-bar instead of --fooBar.

As cligen infers the long form switch names from the proc arguments, I cannot set the argument identifiers to something like git-skip or wait-skip (as I would like to get the long form options as --git-skip and --wait-skip). Instead I need to do GitSkip (ignore the capital G.. I did that just as a quick way to get -G as the short form switch).

Would it be possible to have a cligen configuration that auto-converts all camel/snake case proc args to kebab-case for the long-form switches?

Here is what the help of my little script looks like:

Usage:
  nbuild [required&optional-params]
NBuild: General purpose build script
  Options(opt-arg sep :|=|spc):
  -h, --help                                  print this help message
  -p=, --pkg=        string  REQUIRED         set pkg
  -r=, --rev=        string  "origin/master"  set rev
  -G, --GitSkip      bool    false            set GitSkip
  -W, --WaitSkip     bool    false            set WaitSkip
  -I, --InstallSkip  bool    false            set InstallSkip
  -k, --keep         bool    false            set keep
  -d, --debug        bool    false            set debug

Here is the full code.

@c-blake
Copy link
Owner

c-blake commented May 17, 2018

This is already handled and mentioned in my README.md (search for "--dry-run").

It isn't spelled out to the command user in the help message (that label is just whatever the proc parameter is). However, there are quite a few aspects of command syntax which are not detailed and the user has to "just know". Besides flexible spelling of long option keys there is also, e.g. "--" as an end of options indicator as in nbuild --Wait-sKip -- * working if filenames begin with a "-", the whole "+=" syntax and so on. A help message can/should only do so much.

If you want to describe more syntax than my default to command users then you can just pass

usage="my more verbose help template instead of "${prelude}$command $args\n$doc  Options(opt-arg sep :|=|spc):\n$options$sep"

as well as a new prelude. I refer you to the documentation for the dispatch or dispatchGen macros.

The only possible new feature along these lines would be to have a switch to change the way the long option keys are rendered in the help table, but I don't know if that's really worthwhile - there are an unbounded number of --spel-ing---s, after all.

@c-blake c-blake closed this as completed May 17, 2018
@kaushalmodi
Copy link
Contributor Author

🤦

Thank you, I now remember reading about this style-insensitive nature of the switches.

The only possible new feature along these lines would be to have a switch to change the way the long option keys are rendered in the help table

Would have liked to have the help show only the Unix-style switches instead of the camelCase as they are more common, at least in my experience.

Regarding:

there are an unbounded number of --spel-ing---s, after all

I doubt if that's very common.. one would expect someSwitch to convert to --some-switch only.

But I appreciate you taking time to write back, with that much detail. I will study the source code.

@c-blake
Copy link
Owner

c-blake commented May 17, 2018

It wouldn't be so hard to map just a lower-to-upper case transition to a "-lower" in the help table, but that is also just one of many choices. It seems better to me to just remind/explain the flexibility (a choice which is admittedly quite rare).

@c-blake
Copy link
Owner

c-blake commented Apr 30, 2019

By the way, I just added a helpCase feature to address this issue at the request of a second user. Right now it only translates from snake to kebab-case ('_' -> '-'), but it's a hook like mergeParams that a CLI author can redefine between import cligen and dispatch.

@kaushalmodi
Copy link
Contributor Author

but it's a hook like mergeParams that a CLI author can redefine between import cligen and dispatch.

I tried adding a helpCase proc between import cligen and dispatch but it didn't work. First it complained that the ClHelpContext type wasn't defined. Once I redefined that type locally, I get this:

gen_test.nim(72, 8) Hint: 'helpCase' is declared but not used [XDeclaredButNotUsed]

Can you give an example of overriding helpCase?

Thanks.

@c-blake
Copy link
Owner

c-blake commented May 21, 2019

My comment above might be a part lie/expression of hope more than reality. The distributed helpCase is defined in cligen/argcvt. So, the uses within argcvt.nim like enum values will always use that local definition. The generated parsers should use the helpCase between import cligen & dispatch, I think, but maybe they don't? You're right that I should add a test/ case for that.

Anyway, I'm sure that the user override aspect of this feature is at least incomplete. That relates to helpCase being needed both in the argcvt submodule and in the main module file since there are (at least) 3 separate namespaces - long options, enum values, and subcommand names. I've been meaning to figure out something better. I am very open to suggestions.

In the meanwhile, I am also happy to accept any PR updating the default snake -> kebab transformation, if you have one. I almost did a camelCase -> kebab one in there, but didn't get around to it as it's more involved logic than just underscore to dash.

@c-blake
Copy link
Owner

c-blake commented May 23, 2019

Even if you (or @pb-cdunn) have a set of rules for doing camel->kebab, I could try to code them up.

The most naive rule of just lower->upper case transition ==> dash,lowercase would seem to break in cases with adjacent capitals like printDNA. I doubt we want print-d-n-a as output. Some other examples/discussion is at #97.

We could also just have helpCase become a new table constructor { "printDNA": "print-DNA" } that could override whatever rules helpCase implements but maybe only for the long-option namespace. Or we could maybe try to make the spelling of the key part of the existing help decide which is what was tried in #100. subcommand names already have an override in cmdName, and enums also already have an override in that Nim lets you set the string $ yields:

type Action = enum
    printDNA = "print-DNA", RNAwrite = "RNA-write"

(I haven't quite tested the enum thing on the help printing/output side, but it definitely works on the parsing/input side.)

Even so, it would be best to have the default automatic procedure work so well that people almost never have to think about the 3 distinct override paths. This camel->kebab (or camel->snake which we can trivially kebabify) also smells like the kind of problem others have probably run into over the decades. So, there may be some guidance/wisdom in terms of rules out on the Internet at large, at least for English.

c-blake added a commit that referenced this issue May 23, 2019
also relates to #28).  Also make
short={"whAteVer-SpelIng":..} work.  Move containsParam, formalParamExpand, and
formalParams back to cligen.nim since optionNormalize'ing makes them no longer
general purpose.  Tweak a few test programs to check work & update ref output.
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

2 participants