docopt / docopts

Shell interpreter for docopt, the command-line interface description language.
Other
494 stars 53 forks source link

Enable the half-implemented -f, --function option #57

Open rqelibari opened 2 years ago

rqelibari commented 2 years ago
  1. When docopts is run inside functions it shall not exit but rather return.
  2. Variables should be defined using local.

This PR solves #43.

Sylvain303 commented 2 years ago

Hi, @rqelibari

Thanks for your contribution. Could you also give some bash use-case in #43 on how to use it?

On repetitive function call it could be a real performance killer if I'm remember well the multi docopts call I did on some old benchmark.

rqelibari commented 2 years ago

Of course.

#!/usr/bin/env bash

sayMyName() {
  eval "`docopts -f -V - -h - : "$@" <<-USAGE
  Usage: $0 <your-name>
  ----
  Version: 1.0
  USAGE`"
  echo "hello ${your_name}"
}

# Will output 'hello James'
sayMyName James

# This will print 'hello '
echo "hello ${your_name}"

# Will output 'error: Usage: ...'. No 'hello ...' will be printed.
sayMyName

# This line will get executed
echo "Done!"

Notice: The lines of the here-doc must be indented using a TAB (not spaces). As GitHub replaces TABs with spaces you cannot just copy & paste these lines of code.

Regarding the performance question docopts is fast enough IMHO. On special cases e.g. with a lot of recursion you could either use a better suited programming language that does not need to parse the USAGE string on every run or split the recursive function such that no docopts call is needed inside the recursive function.

Sylvain303 commented 2 years ago

I'll move this conversation/discussion to related issue #43, and we will keep here for PR details.

Thanks. I'm a bit busy actually I will review and test it in a next couple of days/week, see my word/thinking in the issue comment (when I'll post it actually in Draft).

about the function, the usage syntax is a bit tricky, your proposed full bash syntax activate a lot of bash "dirty tricks" and nested parsing/reading:

eval => string opening " => docopts nested exec inside string => docopts arguments and parsed usage string value argument => $@ quoted array expansion => stdin for usage parsing => HEREDOC opening => indented HEREDOC => ending_HEREDOC => ending string for eval parameter "

Could you think about something more simple? The job could be done in golang or in bash wrapper docopts.sh.

To be continued.