c-blake / cligen

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

Problems with test/MultiMultiMulti.nim #113

Closed pb-cdunn closed 5 years ago

pb-cdunn commented 5 years ago

First,

foo.nim(35, 3) Error: undeclared identifier: 'clCfg'
mmm.nim(48, 33) Error: undeclared identifier: 'docFromModuleOf'

I might be wrong about the other problem, so I'll wait for that to be fixed first. I have installed cligen-0.9.36 and I use nim-0.20.99.

c-blake commented 5 years ago

Hmm. I cannot make this happen on nim-0.19.2, 0.19.4, 0.19.6, 0.20.0 or the tip of devel. So, I suspect this is some Nim regression. Where do you get this nim-0.20.99? Do you know what git hash version that corresponds to?

c-blake commented 5 years ago

Oh, wait...The tip of devel is reporting 0.20.99 for me. Maybe that's what you mean? My git hash is 44d80dd86373b9ba41051428948eae30ed97acd3, but I can update to the current tip and try again.

pb-cdunn commented 5 years ago
p% nim -v
Nim Compiler Version 0.20.99 [Linux: amd64]
Compiled at 2019-06-07
Copyright (c) 2006-2019 by Andreas Rumpf

git hash: 2c03c9f42e882eaff4f8e8fa358b9c66ecdd803a
active boot switches: -d:release
pb-cdunn commented 5 years ago

I have simply copied MultMultMult.nim to mmm.nim and run nim c mmm.nim

c-blake commented 5 years ago

(I assume you mean MultMultMult.nim without the is...)

c-blake commented 5 years ago

That program does use docFromModuleOf which does refer to the module name which Nim does construct from the file name. So, you may have to edit that part to doc = docFromModuleOf(mmm.demo).

c-blake commented 5 years ago

Or you could just delete it if you don't want that doc to default to the module docs. Sometimes rather than creating a whole new test program I just double-up testing by using features in existing ones.

c-blake commented 5 years ago

It could also be that the error messages Nim spits out are unhelpful to the mistaken programmer. I've definitely had troubles like that myself.

pb-cdunn commented 5 years ago

I updated to nim-0.2.02, in case that was the issue. But it sounds like you found. Interesting. Didn't know about docFromModuleOf(). Now,

% ./mmm -h
module doc

Usage:
  mmm {SUBCMD}  [sub-command options & parameters]
where {SUBCMD} is one of:
  help   print comprehensive or per-cmd help
  apple  apple SUB-SUB commands
  whoa   Another entry point; here we echoResult
  nelly  Yet another entry point; here we block autoEcho

mmm {-h|--help} or with no args at all prints this message.
mmm --help-syntax gives general cligen syntax help.
Run "mmm {help SUBCMD|SUBCMD --help}" to see help for just SUBCMD.
Run "mmm help" to get *comprehensive* help.

% ./mmm apple -h
apple [optional-params] [cmdLine: seq...]
apple SUB-SUB commands
Options(opt-arg sep :|=|spc):
  -h, --help         print this cligen-erated help
  --help-syntax      advanced: prepend,plurals,..

% ./mmm help apple
apple [optional-params] [cmdLine: seq...]
apple SUB-SUB commands
Options(opt-arg sep :|=|spc):
  -h, --help         print this cligen-erated help
  --help-syntax      advanced: prepend,plurals,..
pb-cdunn commented 5 years ago

So that doesn't work. But at least this does:

% ./mmm apple demo -h
demo [optional-params] [files: string...]
demo entry point with varied, meaningless parameters.
Options(opt-arg sep :|=|spc):
  -h, --help                    print this cligen-erated help
  --help-syntax                 advanced: prepend,plurals,..
  -a=, --alpha=  int     1      set alpha
  -b=, --beta=   float   2.0    set beta
  -v, --verb     bool    false  on=chatty, off=quiet
  -i=, --item=   string  ""     set item

The usage note is wrong. (It should say ./mmm apple demo [optional-parm] ...) But the real problem is that the second level help does not point to the third.

pb-cdunn commented 5 years ago

If this is too hard to work out, that's ok. We can use a flat hierarchy of sub-commands, or multiple executables. But I just wanted to know your thoughts on this.

pb-cdunn commented 5 years ago
% ./mmm help
This is a multiple-dispatch command.  Top-level --help/--help-syntax
is also available.  Usage is like:
    mmm {SUBCMD} [subcommand-opts & args]
where subcommand syntaxes are as follows:

  apple [optional-params] [cmdLine: seq...]
    apple SUB-SUB commands
  Options(opt-arg sep :|=|spc):
      -h, --help         print this cligen-erated help
      --help-syntax      advanced: prepend,plurals,..

  whoa [optional-params] [names: string...]
    Another entry point; here we echoResult
  Options(opt-arg sep :|=|spc):
      -h, --help                   print this cligen-erated help
      --help-syntax                advanced: prepend,plurals,..
      -z=, --zeta=   int    1      set zeta
      -e=, --eta=    float  2.0    set eta
      -v, --verb     bool   false  set verb

  nelly [optional-params] [names: string...]
    Yet another entry point; here we block autoEcho
  Options(opt-arg sep :|=|spc):
      -h, --help                  print this cligen-erated help
      --help-syntax               advanced: prepend,plurals,..
      --hooves=      int   4      set hooves
      -r=, --races=  int   9      set races
      -v, --verb     bool  false  set verb

That's pretty cool, but not expected.

c-blake commented 5 years ago

I have never used more than one-level myself. As a user find a flat hierarchy much simpler to deal with, but people were asking for it. So, I did something. The dispatch all seems to work, but maybe the help system is a little shaky. I tried to walk a line between easy to implement and does something not useless.

Maybe two-levels is enough or at least for you & me a better place for the discussion to start? For 2-levels, "master" command alone dumps a 1st level subcommand table, "master help 2ndLvl" or master "2ndLvl -h" tell the user they need to type just "master 2ndLvl" which dumps the full table. Then "master 2ndLvl sub1 -h" or "master 2ndLvl help sub1" both work.

Honestly, this is pretty rare out there in the world at large. I don't think there are standard behaviors/well-defined expectations (which also argues for not being very usable). Maybe some usage messages can be better and I'm happy to fiddle with those if you think that could help.

c-blake commented 5 years ago

Also, if all you want to do is "notionally group" commands for users without as much nesting structure in the dispatch table, you can just use common prefixes like foo-cmd1 foo-cmd2 bar-cmd1 bar-cmd2. I mean, the space bar is a big easy to type key, but - isn't so much worse. We could probably easily make '/' act like '-' in identifier matching if that helped.

There are a few syntactic weirdnesses that arise with sub-sub-..commands like what happens to interspersed -options and so on. I don't think I have any elegant answers for that. CVS really started this subcommand trend. Before that people just put multiple binaries in a subdirectory of some /bin in one's PATH and typed mh/inc. The filesystem itself already has a fine, understood hierarchical namespace. I guess POSIX made path search rules break that pattern (foolishly in my view), but you can reactivate it with e.g. setopt PATH_DIRS in Zsh and probably some equivalent Bashism.

pb-cdunn commented 5 years ago

I agree.

I actually will try this for a third, semi-hidden level. I need the 2-level help to work for the main sub-commands, but not for the semi-hidden one. I'll just try it and see what happens ...

pb-cdunn commented 5 years ago

The reasons multiple binaries does not work are:

  1. static linkage (disk-usage can add up)
  2. build-time

Nim has become a lot slower than it used to be, so I like to use a single app. But usually a second, flat level is enough.

c-blake commented 5 years ago

Ok. I get the multi-binary issue. Not sure how many dozens of sub commands you are bundling up there.

It may be news that unlike a regular command just running ./FullyAutoMulti with no arguments at all will dump the top level help table. That's sort of the behavior I was imitating with "master sub sub-sub". So, ./MultiMulti gives top-level and ./MultiMulti apple gives 2nd level. I recall it being tricky to dump the "right/maybe best" help at the right time in all cases, though, and that getting worse at the 3rd level.

pb-cdunn commented 5 years ago

Ok. Too many issues with taking it to a whole-nother-level. 2 levels are fine.