Giter VIP home page Giter VIP logo

argbash's People

Contributors

ariutta avatar btamayo avatar conduitry avatar deining avatar farmergreg avatar felipecrs avatar kamalmarhubi avatar kevcui avatar matejak avatar salim-b avatar sgallagher avatar svetlemodry avatar tzrlk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

argbash's Issues

Alias support

Some arguments can have long descriptive names s.a. --add-another-value, so it can be convenient to add a long, but abbreviated option (i.e. alias) s.a. --aavalue.

Parity with docopt

I was wondering if argbash has any future plans to have parity with http://docopt.org/ in terms of help and usage formatting (not necessarily API/templating), provided that docopt is POSIX-compliant?

Right now, docopt has python dependencies, and has no pure bash implementation.

Example with combined shorthand for flags

I would like to see please an example with the following type of options, where the short bool options (flags) can be combined into a single option:

Example:

Simple:

$ tar -xvzf tarfile.tar.gz

Where the options -x, -v, -z, -f are combined.

Slightly more complex:

$ tar -rv -f abc.tar abc.txt

Flags combined + case sensitive argument (-C) + positional (filename "abc.tar.gz"):

$ tar -xvzf abc.tar.gz -C /opt/folder/

Examples from: http://www.binarytides.com/linux-tar-command/

At the moment, I'm not sure how much support argbash templates and API have for these flags.

Quotation marks in help arguments

The following directive doesn't work as expected:

# ARG_OPTIONAL_SINGLE([foo],[],[bar "bar2 bar3". bar4.])

The printf command gets confused, as it gets multiple strings, instead of one with escaped quotes.

Multiple required positional arguments?

I'm trying to generate the following type of usage template:

Usage: my_program <host> <port>

So far, I've realized I can't use ARG_POSITIONAL_SINGLE twice in a row as it throws an error.

And using the following template:

# ARG_POSITIONAL_MULTI([host][port],[Your host][Your port],2,[hosts][port])
# ARG_HELP([short program description (optional)], [long program description (optional)])
# ARGBASH_GO()

generates the help message:

short program description (optional)
Usage: script [-h|--help] <hostport-1> [<hostport-2>]
	<hostport>: Your hostYour port (defaults for <hostport-2>: 'hostsport')
	-h,--help: Prints help

long program description (optional)

Although they are technically repeated arguments with a max number of 2 repeats, I would like to know if it's possible to customize the template so that it generates my desired output.

Would really appreciate any guidance here. Thanks!

Customizing argbash proposals

A few minor proposals that would smooth out argbash integration as described in #1. Didn't want to spam x issues and it's all a bit related.


Problem:

I want to avoid duplicate static text as much as possible in my argbash templates.

Use case:

Contextual help setup as described in the linked issue. Currently every "subparser" has to duplicate some static app header text in it's help message. On changes I need to touch potentially many files.

Proposal:

Add something like ARG_HELP_HEADER(["some header text"]) that, if defined, would display it's text before ARG_HELP, this could then be defined once and included via ARGBASH_WRAP in multiple scripts with different ARG_HELP texts.

Edit: On second thought, I guess I could just define a _app_help_header="my app (c) foo" variable in the main script and use ARG_HELP(["${_app_help_header} - command help"]) in the sourced templates?

EditEdit: ARG_HELP_FOOTER or the ability to disable the argument validation in the generated code, so I could print some further text after the generated help, would also be very helpful. For example displaying the available commands in the main script.


Problem:

For certain scripts I may need to override if print_help; exit 0 is called when --help is passed to the script.

Use case:

Contextual help setup as described in the linked issue. The main script that wraps the "subparsers" should not display it's help text if --help was intended for a valid sub-command, i.e. ./main.sh some-valid-cmd --help

Proposal:

Make automatic display of the help text in the generated parsing code configurable via template. When the auto-display is disabled the generated parsing code should instead define a variable like $_arg_help which would enable handling of the help display by the script itself.


Problem:

I want to configure the error messages related to argument parsing, mainly for too few/many arguments, per template. Currently it always displays FATAL ERROR: Not enough positional arguments - we require at least 1, but got only 0. for too few arguments. New users that may not be very familiar with bash are probably gonna be confused what a positional argument could refer to. For example Error: Expected a filename - we require at least 1, but got only 0. would most likely be much clearer for most people.

Use case:

Every script.

Proposal:

Make error message configurable. Maybe a configurable error prefix might be enough?


Problem:

For a contextual help setup I need to modify the script prefix in the help display.

Use case:

Contextual help setup as described in the linked issue. Example:

$ ./main.sh some-cmd --help
This is the help text of some-cmd!
Usage: ./main.sh [--(no-)no-deps]

The displayed help is the help text of a sourced sub command template. Ideally it would display Usage: ./main.sh some-cmd ....

Proposal:

Add something like ARG_HELP_USAGE_SCRIPT_ARG_PREFIX(["some-cmd"]) that would then be inserted in the help text usage line.


With these resolved argbash could be used to completly handle the parsing for a variety of constructs in a clean and elegant way. Thanks for this neat project!

Typo correction

It would be nice to have support for typo detection/suggestion, so e.g.
script --hepl would produce a --hepl is an invalid argument, did you mean --help? message

Silently fails if bash is invoked with -e

Invoking a script generated by argbash with -e set (either with set -e at the top or running it with bash -e) will make handle_passed_args_count fail silently with error code 1, since I guess the test command actually fails by design (returns 1) if all the correct arguments are supplied.

Wrapping wrapped scripts

Could it be possible to wrap scripts which are already wrapping other scripts?

It doesn't seem to work for the moment.

confused about mandatory options

All my arguments are mandatory. I am confused about how to specify mandatory options so that I don't have to write logic to check all my args are passed.

Quoting issue with repeated optional args

Hi,

I'm often using the ARG_OPTIONAL_REPEATED macro with a default value being a variable.
For example:
# ARG_OPTIONAL_REPEATED([test],[t],[this is a test],["${my_array[@]}"])

I put the quotes around my array in order to preserve spaces in its values.

Hence, the _arg_test variable is well set but in the help message, quotes are escaped, resulting in a weird display of my default values with quotes around as if they were only one long string.

Have you any idea how to deal with that ?

Dash-separated option referenced in ARG_TYPE_GROUP_SET generates invalid variable in bash

Following minimal reproducer:

$ cat invalid_group_var.m4                            
#!/bin/bash

# m4_ignore(
echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2
exit 11  #)Created by argbash-init v2.4.1a
# ARG_HELP([<The general help message of my script>])
# ARG_OPTIONAL_REPEATED([long-option])
# ARG_TYPE_GROUP_SET([MYGROUP], [GROUP-TYPE], [long-option], [ foo,bar ])
# ARGBASH_GO

# [ <-- needed because of Argbash

echo "Value of --foo: ${_arg_long_option[@]}"

# ] <-- needed because of Argbash
$ argbash -o invalid_group_var.sh invalid_group_var.m4

Ran with bash:

$ bash invalid_group_var.sh --long-option foo --long-option bar
invalid_group_var.sh: line 88: _arg_long_option__long-option_SUFFIX=foo: command not found
Value of --foo: foo bar

produces error ^.

Relevant line is 78:

$ nl invalid_group_var.sh | tail -n 10
    77	_arg_long_option="$(MYGROUP "$_arg_long_option" "long-option")" || exit 1
    78	_arg_long_option__long-option_SUFFIX="$(MYGROUP "$_arg_long_option" "long-option" idx)"
       
    79	### END OF CODE GENERATED BY Argbash (sortof) ### ])
    80	# [ <-- needed because of Argbash
       
       
    81	echo "Value of --foo: ${_arg_long_option[@]}"
       
    82	# ] <-- needed because of Argbash

I'm running the code with latest updates of Red Hat Enterprise Linux 7.4:

$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ m4 --version
m4 (GNU M4) 1.4.16
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Rene' Seindal.

Short option can be a duplicate

The code

# ARG_OPTIONAL_SINGLE([foo], f)
# ARG_OPTIONAL_SINGLE([bar], f)
# ARGBASH_GO()

doesn't produce the The short option 'f (in definition of '--bar') is already used error.

Allow an option to generate 'true' and 'false' as valid values for booleans

Sometimes, I would like to use true and false for boolean flag values. For example, some of the flags
would make their way into go programs. argbash uses on and off as keywords to mean a flag is set or unset

Sadly these values are not immediately acceptable to say go programs -- though go acceps a number of different values, see here for details:
https://golang.org/pkg/flag/#pkg-overview

So I end up having a function to convert off and on into appropriate flags. Any chance that argbash could have a generation option to configure these values?

The reason I report this to argbash instead of just rolling my own scripting is because, in general, I want to minimize the amount of arcane bash that I need to write. If I could delegate part of this to an automated code generator, I'd be a happier camper.

Cheers!

Implement manpage output.

Argbash could support a manpage generator of some form.
Easy: rst2man or similar (this one is even easy to extend via a template provided by a user).
Difficult: Produce ready-to-install manpages that somehow also contain stuff that should be in the man page and can't be inferred from the command-line interface.

Installation pains and blocks

Hi,
Just letting you know of some installation pains and some blockers.

mac OSX High Sierra + homebrew and the latest commit: a585507

running "sudo make install PREFIX=/usr" as example says caused a mkdir -p ///usr/bin to be executed. So inside the Make file I see that ROOT is set to / already so no need to include a slash between the $(ROOT)/$(PREFIX), furthermore "sudo make install PREFIX=usr" caused a permission denied error because that dir has some acl's on it. This did the trick though

"sudo make install PREFIX=usr/local"

Then after running arbash-init to create my template and attempting to "feed it back to argbash" I also get permission denied as follows:

BASHdan@ShuPro /Users/dan/bin/bash >>argbash rebuild.atmpl
cat: /usr/local/lib/argbash/argbash-lib.m4: Permission denied
cat: /usr/local/lib/argbash/output.m4: Permission denied

Error during autom4te run, aborting!

BASHdan@ShuPro /Users/dan/bin/bash >>sudo chmod -R 755 /usr/local/bin/argbash*
BASHdan@ShuPro /Users/dan/bin/bash >>argbash rebuild.atmpl
cat: /usr/local/lib/argbash/argbash-lib.m4: Permission denied
cat: /usr/local/lib/argbash/output.m4: Permission denied

Error during autom4te run, aborting!

BASHdan@ShuPro /Users/dan/bin/bash >>sudo chmod -R 755 /usr/local/lib/arg*
BASHdan@ShuPro /Users/dan/bin/bash >>argbash rebuild.atmpl
/


dan@ShuPro /Users/dan/bin/bash >>argbash rebuild.atmpl
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/m4:stdin:11: cannot open `collectors.m4': No such file or directory
autom4te: /usr/bin/m4 failed with exit status: 1
Error during autom4te run, aborting!

I wasnt' sure if autoconf was installed so checked that:

BASHdan@ShuPro /Users/dan/bin/bash >>brew install autoconf
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/php, caskroom/cask).
==> New Formulae
gocryptfs
==> Updated Formulae
homebrew/php/composer โœ”            app-engine-java                    docfx                              faas-cli                           git-imerge                         hubflow                            pandoc-citeproc                    snapcraft                          stockfish
abnfgen                            coffeescript                       emscripten                         fn                                 grpc                               libmicrohttpd                      quantlib                           sourcekitten                       swiftformat
amber                              diamond                            etcd                               gammaray                           heroku                             mercurial                          snakemake                          sslyze

Warning: autoconf 2.69 is already installed

So I think all my permissions are straightened out but my system doesn't seem to have the "collectors.m4" file.. Whatever that is. Is it a missing library.

#blocked.

Handle shellcheck issues of generated script

Using the "optional & pos." online example and pasting that into shellcheck shows many issues:

$ shellcheck myscript
 
Line 59:
        printf "%s\n" "The general script's help msg"
                  ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".
 
Line 61:
        printf "\t%s\n" "<positional-arg>: positional argument help  msg"
                ^-- SC1117: Backslash is literal in "\t". Prefer explicit escaping: "\\t".
                    ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".
 
Line 62:
        printf "\t%s\n" "-o,--option: optional argument help msg (no default)"
                ^-- SC1117: Backslash is literal in "\t". Prefer explicit escaping: "\\t".
                    ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".
 
Line 63:
        printf "\t%s\n" "--print,--no-print: boolean optional argument help msg (off by default)"
                ^-- SC1117: Backslash is literal in "\t". Prefer explicit escaping: "\\t".
                    ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".
 
Line 64:
        printf "\t%s\n" "-h,--help: Prints help"
                ^-- SC1117: Backslash is literal in "\t". Prefer explicit escaping: "\\t".
                    ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".
 
Line 162:
echo "Value of positional-arg: $_arg_positional_arg"
                               ^-- SC2154: _arg_positional_arg is referenced but not assigned.

$ 

Please let all shellcheck tests passโ€ฆ

leftover parsing - _our_args is not dereferenced

Hi,

# ARG_LEFTOVERS( .... )

produces

_our_args=$((${#_positionals[@]} - ${#_positional_names[@]}))
for (( ii = 0; ii < _our_args; ii++))
do
	_positional_names+=("_arg_leftovers[(($ii + 0))]")
done

but has to be

for (( ii = 0; ii < $_our_args; ii++))

Tested in the online version as of today.

Best regards,
Christian

Don't throw on positional errors if --help was passed

When a script has required positionals it should not throw an error if the user also passed --help. The help is displayed but it prevents using a custom help function via ARG_OPTIONAL_ACTION([help]..), as die() always calls the default print_help. A user has to call ./foo.sh asd --help to see the custom help function.

Also ./foo.sh --help ending with FATAL ERROR: .... is probably not the best user experience.

Make argbash help messages docopt-compliant.

Docopt is a great tool to build command-line interfaces from help messages.

Argbash-generated scripts could construct help messages in such way that they could serve as docopt input. This would add these benefits:

  • Interoperability - having Argbash would mean that one can easily transition to another language/solution.
  • Conformance: docopt would serve as a checker of help messages.

Infinite args - minimal call bug

Calling ARG_POSITIONAL_INF using its minimal signature causes a cryptic error.

#!/bin/bash

# ARG_POSITIONAL_INF([something], [bla bla])
# ARGBASH_GO 

Problem with multilines long help

You say in the doc here that with the long argument we can use \n to go to the next line.

However, when I did this the help print the "\n" rather than going to the next line.

After trying in my terminal I saw for printf "%s\n" "\nsalut" that the \n in the first string is used as new line and the one in the second string is printed as "\n"

Problems updating to 2.6.1

Hi,
I'm having some trouble updating argbash to v2.6.1 from v2.5.1 on Ubuntu 16.04. Running make develop or make install completes, and argbash appears to work perfectly aside from a weird issue when attempting to get the version number on the command line. However when I run make check I get the following:

make unittests
make[1]: Entering directory '/home/chris_l/argbash/resources'
autom4te -l m4sugar -I ../src/ -I ../tests/unittests ../tests/unittests/check-utils.m4 && autom4te -l m4sugar -I ../src/ -I ../tests/unittests ../tests/unittests/check-indentation.m4 && autom4te -l m4sugar -I ../src/ -I ../tests/unittests ../tests/unittests/check-list.m4 && autom4te -l m4sugar -I ../src/ -I ../tests/unittests ../tests/unittests/check-types.m4 && autom4te -l m4sugar -I ../src/ -I ../tests/unittests ../tests/unittests/check-arguments.m4 && true
../src/utilities.m4:1: warning: file `list.m4' included several times
../src/utilities.m4:1: warning: file `list.m4' included several times
../src/utilities.m4:1: warning: file `list.m4' included several times
make[1]: Leaving directory '/home/chris_l/argbash/resources'
make regressiontests
make[1]: Entering directory '/home/chris_l/argbash/resources'
diff -q ../tests/regressiontests/basic.sh ../tests/regressiontests/basic2.sh
test -z "shellcheck -x -e 2015" || shellcheck -x -e 2015 "../tests/regressiontests/basic.sh"
unrecognized option `-x'

Usage: shellcheck [OPTIONS...] FILES...
  -e CODE1,CODE2..  --exclude=CODE1,CODE2..  exclude types of warnings
  -f FORMAT         --format=FORMAT          output format
  -s SHELLNAME      --shell=SHELLNAME        Specify dialect (bash,sh,ksh)
  -V                --version                Print version information

../tests/regressiontests/Makefile:186: recipe for target 'stability' failed
make[1]: *** [stability] Error 3
make[1]: Leaving directory '/home/chris_l/argbash/resources'
Makefile:115: recipe for target 'check' failed
make: *** [check] Error 2

It appears to be complaining about the version of shellcheck I have installed, v0.3.7-5, and I just wasn't sure if there was anything wrong with argbash or if a newer version of shellcheck was required.

Required named arguments?

I don't see in the API a way to define a required named argument. If that is indeed not the case, I would like to request such an option.

Thanks!

ZSH support

Hi

Issue
Argbash doesn't seem to support ZSH ?

Symptom
When running with ZSH I'm seeing the following error:
Error during argument parsing, possibly an Argbash bug

Which points to the eval line below

assign_positional_args ()
{
	# We have an array of variables to which we want to save positional args values.
	# This array is able to hold array elements as targets.
	_positional_names=('_arg_task' )

	for (( ii = 0; ii < ${#_positionals[@]}; ii++))
	do
		eval "${_positional_names[ii]}=\${_positionals[ii]}" || die "Error during argument parsing, possibly an Argbash bug." 1
	done
}

Workaround
Runs fine with #!/bin/bash

Many thanks

Use parameter expansion for default variable initialization

Currently argument variables are initialized like this:

# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_print=off
_arg_foo_option="boo"

This is problematic when using sub-parsers, as optionals that were already parsed by the main script are reset to it's defaults and not parsed again. Could parameter expansion be used instead?

# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_print=${_arg_print:-off}
_arg_foo_option="${_arg_foo_option:-boo}"

Booleans have yes/no as default values and on/off as given values

Perhaps I am just doing wrong, but it seems inconsistent to me. The default value for a boolean is yes or no:

_arg_verbose=yes
_arg_download_only=no

But when the user supplies this argument, it is set to on or off:

_arg_download_only="on"
 test "${1:0:5}" = "--no-" && _arg_download_only="off"

This means that I have to check for both variants in order to get it right consistently. This can't be the intention, right?

ARG_OPTIONAL_REPEATED always appends to the defaults rather than replacing

The documentation for ARG_OPTIONAL_REPEATED reads:

The default default is an empty array. The argument can be repeated multiple times, but instead of the later specifications overriding earlier ones (s.a. ARG_OPTIONAL_SINGLE does), arguments are gradually appended to an array. The form of the default is what you normally put between the brackets when you create bash arrays, so put whitespace-separated values in there

The other options for argbash will supersede their defaults, but the effect of using the default option in ARG_OPTIONAL_REPEATED means that this set of values will always be present in the resulting list and that the arguments specified at the command-line merely supplement them.

Either the documentation should reflect this behavior or it should be changed to behave more similarly to the other options.

Design better boolean arguments

Currently, the ARG_OPTIONAL_BOOL does not behave optimally (see #2 ).
It seems to be a good idea to have more macros for switch-on, switch-off and both (as the current ARG_OPTIONAL_BOOL somehow attempts to).
Currently, ARG_OPTIONAL_BOOL assumes that one wants to switch something on (using long and short option) and autogenerating long option to switch something off. This falls on its head when one wants to switch something off.
Proposed behavior:

  • ARG_OPTIONAL_BOOL will remain, it will autodetect whether it is in a switch-on or switch-off mode by examining the default (or the option whether it begins withno-..., I'm not yet decided). It will use the provided long and short options for the detected mode, but it will also generate a long option for the opposite mode.
    • Occurence of ARG_OPTIONAL_BOOL(no-video, v) would make the script accept --no-video, -v, that would set _arg_video (which would be on by default) to off, and --video, that would set _arg_video to on, overriding possible previous occurence of -v or --no-video.
    • Conversely, occurence of ARG_OPTIONAL_BOOL(video, v) would make the script accept --video, -v, that would set _arg_video (which would be off by default) to on, and --no-video, that would set _arg_video to off, overriding possible previous occurence of -v or --video.

New macros would be introduced:

  • ARG_OPTIONAL_SWITCH_ON will be introduced. It will accept long and short option (and no default since off will be assumed as default).
    • Occurence of ARG_OPTIONAL_SWITCH_ON(video, v) would make the script accept --video, -v, that would set _arg_video (which would be off by default) to on.
  • ARG_OPTIONAL_SWITCH_OFF will be introduced. It will accept long and short option (and no default since on will be assumed).
    • Occurence of ARG_OPTIONAL_SWITCH_OFF(no-video, v) would make the script accept --no-video, -v, that would set _arg_video (which would be on by default) to off.
      Everybody's comments are highly appreciated!

INCLUDE_PARSING_CODE() but define ARG_... in main script

Currently my main.sh has something like:

# DEFINE_SCRIPT_DIR([])
# INCLUDE_PARSING_CODE([main.argbash])
# ARGBASH_GO()

And main.argbash has:

# ARG_OPTIONAL_BOOLEAN([foo],[f],[Use foo])
# ARG_POSITIONAL_SINGLE([bar],[File for bars])

However, it means that anyone reading main.sh has to reference main.argbash to see what variables it provides, and I've found myself in the situation of referencing a variable that I'd deleted from the included file.

So, it would be nice if either or both of (a) allow the # ARG_...() to be defined in the main file and/or (b) auto-add a reminder block to the main file like:

# $_arg_foo: "Use foo"
# $_arg_bar: "File for bars"

Failed to execute process

When using argbash's docker image to convert the file:

#!/bin/bash
#
# This is a rather minimal example Argbash potential
# Example taken from http://argbash.readthedocs.io/en/stable/example.html
#
# ARG_OPTIONAL_SINGLE([option], [o], [optional argument help msg])
# ARG_OPTIONAL_BOOLEAN([print], , [boolean optional argument help msg])
# ARG_POSITIONAL_SINGLE([positional-arg], [positional argument help  msg], )
# ARG_HELP([The general script's help msg])
# ARGBASH_GO
# [ <-- needed because of Argbash
echo "Value of --option: $_arg_option"
echo "print is $_arg_print"
echo "Value of positional-arg: 

using the script:

#!/bin/bash
docker run -it --rm -e PROGRAM=argbash \
  -v "$(pwd):/work" \
  matejak/argbash "$@"

to convert:

argbash test.sh > test_argbash.sh
chmod +x test_argbash.sh

one gets a file that fails to execute with bizarre errors:

Failed to execute process './test_argbash.sh'. Reason:
', which is not an executable command. the interpreter '/bin/bash

Looking into this a bit, and redirecting like so:

./test_argbash.sh  2>&1 | less

one gets something clearer:

Failed to execute process './test_argbash.sh'. Reason:
The file './test_argbash.sh' specified the interpreter '/bin/bash^M', which is not an executable command.

Leftover args bug

Argbash 2.4.0 fails on the following input:

#!/bin/bash
#
# This is a rather minimal example Argbash potential
# Example taken from http://argbash.readthedocs.io/en/stable/example.html
#
# ARG_POSITIONAL_SINGLE([command], [c], [optional argument help msg])
# ARG_OPTIONAL_BOOLEAN([verbose], , [if set, output will be verbose])

# ARG_VERSION([echo $0 v$VERSION])
# ARG_HELP([The general script's help msg])

# ARG_LEFTOVERS([define 1 or more input file; if ommited scripts can still act on different values of SLRUM_PROCID])
# ARGBASH_GO 

producing a false alarm about unknown number of positional args before defining leftover arguments.

Handling of wrapped scripts

Hi,

I'm working on a bash framework using argbash, so first I'd like to thank you for this generator.

That said, I have a question and/or a request.

I'm using a lot the wrapping functionality, so lately I tried to something fancy to see if it was working :

# ARGBASH_WRAP([directory/stem])

I was pleased to see that it doesn't make the generator fail, but sadly the output is not working.

I was wondering if wrapping with the relative path of the stem is something you have or would consider or is it really not a question (and so, shouldn't the generator failed) ?

I should precise that I know of the --search option and I use it, but in this precise case it is more of an organisation convenience as I provide a framework.

Customize Argbash messages

Some interaction with the user could be improved and made customizable, for instance:

  • error messages when supplied positional arguments don't match the interface,
  • error message when the argument type doesn't match.

License of code generated by ARGBASH

Hi,

This is great tool

I just want to know about the license of the files generated by argbash.

May I choose the license I want for the generated code (Eg Apache 2.0) or is the generated code
supposed to have the BSD-3-Clause license ?

[RFE] Bash completion generator

It would be fantastic if argbash could generate a framework for a bash-completion script that matches the arguments it accepts.

Contextual help possible?

Hello, I'm currently looking for a clean way to get contextual help in a bash project of mine and stumbled across argbash. Except for the lack of short argument clustering, which I can probably live with, it looks very promising. However after reading the docs and playing around a bit I'm not sure argbash is a good fit for contextual help. The pattern is fairly common now in modern cli applications like git or docker:

# print main help, global options like --verbose and main commands  with short description
./mainscript 
# print help text for command, global options and options specific to this command
./mainscript <command> --help

I pretty much have no idea what I'm doing yet, but it looks like I would need a conditional # INCLUDE_PARSING_CODE([cmd-foo-parsing.sh]) instruction to get the desired behaviour. Maybe I'm missing something obvious here. Could you provide a rough example if this is possible or what the best approach for this would be using argbash?

Ideally I would like to separate the parsing code completely and just regenerate some parsing templates occasionally when new commands/options are added.

Thanks!

Improve ARG_OPTIONAL_BOOLEAN help display

Currently ARG_OPTIONAL_BOOLEAN is displayed like so:

$ ./foo.sh --help
foo!
Usage: ./foo.sh [--(no-)no-deps]
-n,--no-deps,--no-no-deps: some description

With many of those the negating (no-) text adds a lot of visual noise and can be borderline silly as in the above case. I would imagine that most people have no use for an option flag that equals the application's default value.

Proposal:

Remove the (no-) and ,--no-<some-option> portions in the help output for ARG_OPTIONAL_BOOLEAN, or at least make it's display configurable.

Introduce macros that have different handling of defaults

The ARG_OPTIONAL_REPEATED and ARG_OPTIONAL_INCREMENTAL currently extend their defaults. It may make sense to give a possibility to pick the way defaults are handled, because there are legitimate use cases when users want the defaults to be forgotten if they supply value(s) to these commands (see #12 for more in-depth insights).
The proposal is to introduce two alternatives for each macro that is in question:

  • ARG_OPTIONAL_REPEATED_ADD
  • ARG_OPTIONAL_REPEATED_REPLACE
  • ARG_OPTIONAL_INCREMENTAL_ADD
  • ARG_OPTIONAL_INCREMENTAL_REPLACE

Those macros would accept the same arguments, but they would treat the defaults differently (and also the help message would have to be different).
Any feedback is welcome, but most importantly:

  • Does it look like a good idea?
  • Do the names feel right?

ARG_TYPE_GROUP_SET doesn't accept empty values

I'd like to create repeated option where user can select from one of allowed values. I'm using following code:

$ cat empty_group_value.m4
#!/bin/bash

# m4_ignore(
echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2
exit 11  #)Created by argbash-init v2.4.1a
# ARG_HELP([<The general help message of my script>])
# ARG_OPTIONAL_REPEATED([myopt], , [foo,bar,])
# ARG_TYPE_GROUP_SET([MYGROUP], , [myopt], [foo,bar,])
# ARGBASH_GO

# [ <-- needed because of Argbash

echo "Value of --myopt: ${_arg_myopt[@]}"

# ] <-- needed because of Argbash

After compilation:

$ argbash -o empty_group_value.sh empty_group_value.m4

Non-empty single and repeated options works as expected:

$ ./empty_group_value.sh --myopt foo                  
Value of --myopt: foo
$ ./empty_group_value.sh --myopt foo --myopt bar
Value of --myopt: foo bar

But when I try to skip this option or even set it to empty string:

$ bash ./empty_group_value.sh
Value '' (of argument 'myopt') doesn't match the list of allowed values: 'foo', 'bar' and ''
$ bash ./empty_group_value.sh --myopt ''
Value '' (of argument 'myopt') doesn't match the list of allowed values: 'foo', 'bar' and ''

script doesn't accept that and even print misleading error message.

I'm running the code with latest updates of Red Hat Enterprise Linux 7.4:

$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ m4 --version
m4 (GNU M4) 1.4.16
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Rene' Seindal.

argbash --version prints nothing

This is what I get when running argbash through a docker container:

$ argbash --version
argbash v

It seems that the version number is missing. I would suggest fixing this issue: it's a small one, but undermines the confidence in argbash performance.

instructions for make install are wrong

The instructions indicate that you should run

make install PREFIX=/usr/bin to get argbash installed system wide. But that puts it in /usr/bin/bin/argbash.

to do it and get the expected behavior, it should either read make install PREFIX=/usr or update the Makefile

Unexpected result using online generation with ARGBASH_SET_INDENT and explanatory comments

When I use online generation with ARGBASH_SET_INDENT and select to generate explanatory comments, the comment block beginning # Function that evaluates whether a value passed to an argument is not appropriately commented.

using test.m4

#!/bin/bash

# m4_ignore(
echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2
exit 11  #)

# ARG_VERSION([echo "test/1.0.0"])

# ARG_OPTIONAL_SINGLE([option])
# ARG_OPTIONAL_BOOLEAN([print])
# ARG_HELP([<The general help message of my script>])

# DEFINE_SCRIPT_DIR([script_dir)])

# ARG_DEFAULTS_POS()
# ARG_RESTRICT_VALUES([no-local-options])
# ARGBASH_SET_INDENT([    ])
# ARGBASH_GO

# [ <-- needed because of Argbash

printf 'Value of --%s: %s\n' 'option' "$_arg_option"
printf "'%s' is %s\\n" 'print' "$_arg_print"

# ] <-- needed because of Argbash

generated test.sh

#!/bin/bash

#

# ARG_VERSION([echo "test/1.0.0"])

# ARG_OPTIONAL_SINGLE([option])
# ARG_OPTIONAL_BOOLEAN([print])
# ARG_HELP([<The general help message of my script>])

# DEFINE_SCRIPT_DIR([script_dir)]))

# ARG_DEFAULTS_POS([])
# ARG_RESTRICT_VALUES([no-local-options])
# ARGBASH_SET_INDENT([    ])
# ARGBASH_GO()
# needed because of Argbash --> m4_ignore([
### START OF CODE GENERATED BY Argbash v2.6.1 one line above ###
# Argbash is a bash code generator used to get arguments parsing right.
# Argbash is FREE SOFTWARE, see https://argbash.io for more info
# Generated online by https://argbash.io/generate

# When called, the process ends.
# Args:
#     $1: The exit message (print to stderr)
#     $2: The exit code (default is 1)
# if env var _PRINT_HELP is set to 'yes', the usage is print to stderr (prior to )
# Example:
#     test -f "$_arg_infile" || _PRINT_HELP=yes die "Can't continue, have to supply file as an argument, got '$_arg_infile'" 4
die()
{
    local _ret=$2
    test -n "$_ret" || _ret=1
    test "$_PRINT_HELP" = yes && print_help >&2
    echo "$1" >&2
    exit ${_ret}
}

# Function that evaluates whether a value passed to an argument
# does not violate the global rule imposed by the ARG_RESTRICT_VALUES macro:
# _CASE_RESTRICT_VALUES([],
		[The value must not match any long or short option this script uses],
		[The value must not match anything that looks like any long or short option.])
# _INDENT_()$1: The name of the option
# _INDENT_()$2: The passed value
evaluate_strictness()
{
    [[ "$2" =~ ^-(-(version|option|print|help)$|[vh]) ]] && die "You have passed '$2' as a value of argument '$1', which makes it look like that you have omitted the actual value, since '$2' is an option accepted by this script. This is considered a fatal error."
}

# Function that evaluates whether a value passed to it begins by a character
# that is a short option of an argument the script knows about.
# This is required in order to support getopts-like short options grouping.
begins_with_short_option()
{
    local first_option all_short_options
    all_short_options='vh'
    first_option="${1:0:1}"
    test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}



# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_option=
_arg_print="off"

# Function that prints general usage of the script.
# This is useful if users asks for it, or if there is an argument parsing error (unexpected / spurious arguments)
# and it makes sense to remind the user how the script is supposed to be called.
print_help ()
{
    printf '%s\n' "<The general help message of my script>"
    printf 'Usage: %s [-v|--version] [--option <arg>] [--(no-)print] [-h|--help]\n' "$0"
    printf '\t%s\n' "-v,--version: Prints version"
    printf '\t%s\n' "-h,--help: Prints help"
}

# The parsing of the command-line
parse_commandline ()
{
    while test $# -gt 0
    do
        _key="$1"
        case "$_key" in
            # The version argurment doesn't accept a value,
            # we expect the --version or -v, so we watch for them.
            -v|--version)
                echo "test/1.0.0"
                exit 0
                ;;
            # We support getopts-style short arguments clustering,
            # so as -v doesn't accept value, other short options may be appended to it, so we watch for -v*.
            # After stripping the leading -v from the argument, we have to make sure
            # that the first character that follows coresponds to a short option.
            -v*)
                echo "test/1.0.0"
                exit 0
                ;;
            # We support whitespace as a delimiter between option argument and its value.
            # Therefore, we expect the --option value, so we watch for --option.
            # Since we know that we got the long option,
            # we just reach out for the next argument to get the value.
            --option)
                test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
                _arg_option="$2"
                shift
                evaluate_strictness "$_key" "$_arg_option"
                ;;
            # We support the = as a delimiter between option argument and its value.
            # Therefore, we expect --option=value, so we watch for --option=*
            # For whatever we get, we strip '--option=' using the ${var##--option=} notation
            # to get the argument value
            --option=*)
                _arg_option="${_key##--option=}"
                evaluate_strictness "$_key" "$_arg_option"
                ;;
            # See the comment of option '--version' to see what's going on here - principle is the same.
            --no-print|--print)
                _arg_print="on"
                test "${1:0:5}" = "--no-" && _arg_print="off"
                ;;
            # See the comment of option '--version' to see what's going on here - principle is the same.
            -h|--help)
                print_help
                exit 0
                ;;
            # See the comment of option '-v' to see what's going on here - principle is the same.
            -h*)
                print_help
                exit 0
                ;;
            *)
                _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
                ;;
        esac
        shift
    done
}

# Now call all the functions defined above that are needed to get the job done
parse_commandline "$@"

# OTHER STUFF GENERATED BY Argbash
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || die "Couldn't determine the script's running directory, which probably matters, bailing out" 2

### END OF CODE GENERATED BY Argbash (sortof) ### ])
# [ <-- needed because of Argbash


printf 'Value of --%s: %s\n' 'option' "$_arg_option"
printf "'%s' is %s\\n" 'print' "$_arg_print"

# ] <-- needed because of Argbash

weirdness in test.sh lines 39-45 (see 42,43 missing indent conversion and comment prefix)

# Function that evaluates whether a value passed to an argument
# does not violate the global rule imposed by the ARG_RESTRICT_VALUES macro:
# _CASE_RESTRICT_VALUES([],
		[The value must not match any long or short option this script uses],
		[The value must not match anything that looks like any long or short option.])
# _INDENT_()$1: The name of the option
# _INDENT_()$2: The passed value

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.