GithubHelp home page GithubHelp logo

Comments (23)

c-blake avatar c-blake commented on September 27, 2024 1

Options are supposed to be optional. ;-) If you are wrapping a valid proc with all defaulted parameters that can be invoke correctly as foo() then ./foo should also work with no arguments. So, I think you'll probably agree the defaults are right here. Conceptually, it sounds like you may have one or more mandatory parameters.

That said, you can do this use dispatchGen and call the generated dispatcher yourself. E.g.,:

proc foo(a=0, b=5.0) = discard

import cligen, os
dispatchGen(foo)
quit(dispatch_foo(if paramCount() > 0: commandLineParams() else: @[ "--help" ]))

from cligen.

c-blake avatar c-blake commented on September 27, 2024 1

There may be a useful new feature request embedded in this question, though..A kind of "standalone option" which if given means none of the mandatory parameters are actually mandatory (i.e., if one of those is present then the dispatcher acts as if every mandatory parameter had been in ImplicitDefault).

from cligen.

c-blake avatar c-blake commented on September 27, 2024 1

No, if you have proc yadda(..., blah="", ..) that should get an empty string default value and be considered optional. The node kind won't be nnkEmpty, but some node for a string literal (which happens to be the empty string).

from cligen.

c-blake avatar c-blake commented on September 27, 2024 1

The short answer is the dispatcher is designed to be called from inside a quit().

The long answer has to do with return value behaviors/translation/echoResult, etc. See the "Exit Code Behavior" section in DETAILS.md.

Another way to think about it is that, in cligens view, a command is a one-shot proc invocation. The Nim compiler would be happy enough if you just did discard dispatch_nistow(), but then a command-syntax error would not necessarily exit with an error code.

from cligen.

c-blake avatar c-blake commented on September 27, 2024 1

You're welcome. Yeah. Just string literals for now. Identifiers in the macro $ setting just get their name lifted. I'll let you know if I figure out a way to get it evaluated..Then things like that fancy staticExec become possible, or a staticRead to grab a string out of a file, etc.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

Conceptually, it sounds like you may have one or more mandatory parameters.

Right.. am trying to figure out how to make them optional.. having no luck..

I now have:

proc nistow*(version=false, simulate=false, verbose=false, force=false, app: string, dest: string) =

But I want to make nistow -v work and not have cligen throw this error:

Missing these required parameters:
  app
  dest
Run command with -h for more details.

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Well, you have a call with required string params app and dest, right? It looks like you are defaulting dest to getHomeDir() (in the current git-available version), and you want to error out if app is not provided. So, what am I missing? Did you want a full help message with missing mandatory parameters? I kinda figured those were most likely typos/misspellings of things/etc and the short message would be ok in this context.

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Oh, wait...I see. I looked at your code more carefully. You want -v to print a version and exit. That is not really supported behavior even with dispatchGen. You will probably need a wrapper proc to handle that which checks if version_only: write_version(); quit(). This sort of thing is necessary in most cases where the "one-shot control flow" of the command and API are not really in sync.

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Hmm. Even that may not be enough to block the missing mandatory error out. You may have to default those mandatory strings to something like "REQUIRED" yourself and check them in a wrapper proc.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

@c-blake

Thanks for giving your time to this discussion. Please bear with me as I am very much inexperienced in Nim.. And so the dumb questions follow..

you have a call with required string params app and dest, right?

Thanks. I reiterated with that proc signature to finally realize that all arguments are required. Being used to a lisp flavor, is there a way to mark a proc parameter as optional?

So, what am I missing? Did you want a full help message with missing mandatory parameters?

As you later realize, I am just expecting the proc to evaluate below and quit, and not care if the mandatory args have values.

  if version:
    writeVersion()
    quit()

FYI, I am working in this branch: https://github.com/kaushalmodi/nistow/tree/use-cligen

That is not really supported behavior even with dispatchGen

I have a lot of reading to do to understand what dispatchGen actually does.. I see that it is defined in cligen.nim. Also I have yet to learn Nim macros.

You may have to default those mandatory strings to something like "REQUIRED" yourself and check them in a wrapper proc.

Yes, that's what finally worked.. I was confused for a long time as to what makes a switch mandatory vs not. I was trying to default the values of those string switches to "", but apparently a string arg not being set is the same as being set to "" in Nim?

There may be a useful new feature request embedded in this question, though..A kind of "standalone option" which if given means none of the mandatory parameters are actually mandatory

That would be great! Thanks!

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Ok. I added that feature. Check out test/ImplicitDefault.nim to see how to use. Basically you just tack on a mandatoryOverrides = @["version"]. It's starting to get kind of far from the idea that the proc being auto-wrapped is something besides a command, though. A special invocation mode that overrides everything else is not unheard of for an API call, though.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

Ok. I added that feature.

Wow! Let me try that out. Thanks!

from cligen.

c-blake avatar c-blake commented on September 27, 2024

To answer one question/confusion implicit in your longer reply, Nim will just default uninitialized values to something, depending on the type (unless you use the {.noinit.} pragma). cligen decides on whether something is optional or mandatory based on an explicit assignment construct being syntactically present in the proc signature (by whether the [1].kind == nnkEmpty is true).

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

by whether the [1].kind == nnkEmpty is true

So that condition is true even when I explicitly set the arg to "" (empty string)?

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

No, if you have proc yadda(..., blah="", ..) that should get an empty string default value and be considered optional.

You are right! (kaushalmodi-forks/nistow@dd096a0), may be I am just going crazy..

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

Basically you just tack on a mandatoryOverrides = @["version"]

Thanks, that works! (kaushalmodi-forks/nistow@e6189ae).

from cligen.

c-blake avatar c-blake commented on September 27, 2024

You're welcome. I'm not really so happy with ImplicitDefault and mandatoryOverride because they actually create command syntax which would be disallowed as a Nim proc invocation. With a proc invocation, the caller needs to provide non-defaulted parameters. cligen generates the call and always provides all params. So, Nim is happy. There was kind of a gradual evolution (from suppress even) of command syntax that is more flexible than the proc call syntax, though I would prefer it not go any further, if possible.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

With a proc invocation, the caller needs to provide non-defaulted parameters. cligen generates the call and always provides all params. So, Nim is happy.

Thanks, I am now gradually understanding the role of cligen better.

There was kind of a gradual evolution (from suppress even) of command syntax that is more flexible than the proc call syntax

I have no idea about suppress, but it's alright, I am learning things as needed :)


And here's the last commit (kaushalmodi-forks/nistow@16f4cc9) where I made the --help be passed to the dispatch if user passes no switches.

Just one question with that.. Why is the quit needed? I obviously tried to see what happens, and not surprisingly an error:

        ... nistow.nim(91, 18) Error: expression 'dispatchnistow(if
        ...   ## "is greater" operator. This is the same as ``y < x``.
        ...   0 < paramCount(): commandLineParams() else: @["--help"],
        ...                "Stow 0.1.0 (Manage your dotfiles easily)", "${prelude}$command $args\L$doc  Options(opt-arg sep :|=|spc):\L$options$sep",
        ...                "", "")' is of type 'int' and has to be discarded; start of expression here: nistow.nim(81, 2)

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Hey. I don't know if you are still interested, but I just introduced a better way to handle "--version". See the new test/Version.nim program for example usage. The new way has the parser-dispatcher do all the work outside the API call. The CLI author provides the name of the long option (e.g. "version" or "Version") and a version string. The API code doesn't need to know anything about cligen. That is cleaner separation more in keeping with the overall cligen design.

{ This is more advanced and slightly off topic, but that version string could almost be something "automagic" like staticExec "git log -1 | head -n1" except currently this fails because Nim evaluates all the macro stuff before the staticExec. So, for now use a real string like "0.5.0". }

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

@c-blake Thanks! It works! kaushalmodi-forks/nistow@db5e38f.

Though, I tried setting the version to a const and use the const var instead of the string "0.1.0" in that commit, and it printed the identifier as-is i.e. did not evaluate it.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

Thanks, btw you need to update the module version in cligen.nimble.

from cligen.

c-blake avatar c-blake commented on September 27, 2024

Oops. Thanks. There are definitely too many little things to remember to do when releasing. I should script it all.

from cligen.

kaushalmodi avatar kaushalmodi commented on September 27, 2024

I should script it all.

Create a Nim package for that ;-)

Inspiration: https://github.com/goreleaser/goreleaser

from cligen.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.