iffy / nim-argparse

Argument parsing for Nim
MIT License
120 stars 8 forks source link

Support custom short-circuited flags (like how --help works) #43

Closed rrthomas closed 3 years ago

rrthomas commented 3 years ago

run() does not return anything, but flag() cannot have a run: action attached to it.

So, for example, consider a --version flag. It is natural to write something like this:

var p = newParser("syms"):
  flag("-V", "--version", help="show program's version number and exit")

let opts = p.parse()
if opts.version:
  echo "foo version 0.1"

But then if I have run actions, they will not be executed. On the other hand, if I replace

let opts = p.parse()

with

p.run()

then I cannot test whether --version was given later. And I cannot write:

var p = newParser("syms"):
  flag("-V", "--version", help="show program's version number and exit"):
    run:
      echo "foo version 0.1"

p.run()

So I am unsure how run: actions are supposed to be mixed with option parsing…I'm new to Nim, so I guess I've probably overlooked something. Thanks for argparse!

iffy commented 3 years ago

Hi @rrthomas

With argparse, it's intended that you'd either use p.parse() without run: blocks or p.run() with run: blocks, because, as you've noted, run: blocks aren't run when you parse.

You could achieve what you want with the following:

import argparse

var p = newParser("syms"):
  flag("-V", "--version")
  run:
    if opts.version:
      echo "foo version 0.1"
      raise newException(ShortCircuit, "version")
    else:
      echo "hi"

p.run()

But I'm going to leave this issue open because this workaround should be documented (and possibly improved).

rrthomas commented 3 years ago

Thanks for the workaround!

iffy commented 3 years ago

In the master branch (which will hopefully be released soon) you can now do this:

var p = newParser:
  flag("-V", "--version", shortcircuit=true)

try:
  p.run()
except ShortCircuit as e:
  if e.flag == "version":
    echo "1.0.0"
    quit(0)

try:
  discard p.parse()
except ShortCircuit as e:
  if e.flag == "version":
    echo "1.0.0"
    quit(0)
rrthomas commented 3 years ago

Thanks, that's great!