c-blake / cligen

Nim library to infer/generate command-line-interfaces / option / argument parsing; Docs at
https://c-blake.github.io/cligen/
ISC License
508 stars 24 forks source link

Feature request: default command for multicommands when no parameters set #135

Closed kraptor closed 4 years ago

kraptor commented 4 years ago

I solved this (for the root multi command) like this:

if commandLineParameters().len == 0:
   run()
else:
  dispatchMulti(["multi"], [run], [version], [debug])

Would be nice to support something like:

dispatchMulti(["multi", default=run], [run], [version], [debug])

That way, sub-multicommands might support this feature, too.

Use case: I'm building a mixed command-line/GUI application, I want the application to launch the default command when double-cliked by users (GUI mode), but I want too to support all cli shenanigans for advanced users.

c-blake commented 4 years ago

The problem I see with this is that all the options and non-option CLI args for the default subcommand would become part of the no-subcommand syntax. That would collide with another request feature (via e-mail not github of @kaushalmodi) of having "global" options pre-any-subcommands (bound to Nim variables perhaps set non-CL-wise via perhaps environment variables or an outside cligen config file). For your specific use case there are probably no other options/args and you already have a workaround. But I'll let Kaushal chime in before closing this issue as "conflicts with something more standard". (To the extent there is much "standard" multi-command syntax out there..which isn't very much.)

c-blake commented 4 years ago

It would also collide with the ability to have "arbitrary words" be non-option CL parameters since if someone did a shell * and it matched a file that happened to also be a subcommand name and came before any other non-option parameter there would be a syntactic ambiguity. It's possible that the way Windows resolves * could fix this, but not with Unix. So, I think it's unfortunately somewhere between too hard (requiring various User quotings undermining the brevity that was desired in the first place) and impossible to make this idea "safe".

However, on the plus side, cligen has for a long time already accepted for that subcommand any prefix unique among subcommands. So, chances are that you could probably arrange for the one you expect to be used "most often" to require only 1 character without even a - prefix.

The idea of a "subcommand alias" system a la Mercurial has occurred to me, but I have not implemented it. If that alias facility existed you could always alias the default to be something like the number "1" or "0" or "," or something easy to type that would almost never collide (perhaps by convention) with anything else. Then mymulticmd , could always invoke the CLI-author's intended default (assuming the author has a convention of making ',' (or maybe '.' or '/') alias some intended default. Having a token (virtually any token) separate early options and late parameters resolves the problems I mention in the first paragraph here.

This subcommand alias idea is a separate feature request, though, IMO, and it would indeed "leave the choice open" to CLI authors. So, some particular CLI author might pick period and another comma and another slash and without community agreement CLI users would..be out of luck. I think that's the best we can do, though. Even if I could do your initial idea I am 100% sure that someone would request being able to adjust the behavior anyway. So, we'd already need one-CLI-author-mindset to have a suite of multi-author tools that worked the same way. (We already need that for many other reasons/knobs/levers anyway.)

So, I'm going to close this issue, but if you want to open a subcommand alias one before I get around to implementing it then feel free.

c-blake commented 4 years ago

So, I added an example of how to do this "alias" business with existing mechanisms in test/FullyAutoMulti.nim. So, it's entirely conceivable that in "default mode" one would want slightly different disptchGen options and just doubling up the entry point already gives that capability. You might want to substitute the entire help table/message with something like "alias for punt subcommand`" which that example shows how to do, and you can put it either as the first or last or wherever slot if you want that at the top/bottom/wherever.

So, some more formal alias system seems like it would add very little value. As with so many things in cligen, an FAQ/HOWTO/better documentation could definitely ease the burden for new users than my 3 dozen test/ programs.

Anyway, I think I am going to release this fix in the next day or two and then give a two week period with RELEASE_NOTES having warned people about 1.0/more resistance to breaking changes. So, if you have something else, try to think of it now. (Many things are only ambiguously "breaking" or not hard to add backward compatibly, though.)

kraptor commented 4 years ago

Thanks for this! You are awesome, keep the good work.

c-blake commented 4 years ago

You're welcome. Sorry that a reduction from foo . to foo was not in the cards. (or ',' or whatever you choose as your local convention).