From 903328c1ce4245efb74b492bc2246cf41c2641d9 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Fri, 28 Mar 2014 14:04:22 -0400 Subject: [PATCH 1/8] Added bash completion support --- README.md | 68 ++++++++++++++++++++++------- optparse.bash | 49 ++++++++++++++++++--- sample_event.sh | 14 ++++++ sample_event_generate_completion.sh | 15 +++++++ 4 files changed, 124 insertions(+), 22 deletions(-) mode change 100644 => 100755 README.md mode change 100644 => 100755 optparse.bash create mode 100755 sample_event.sh create mode 100755 sample_event_generate_completion.sh diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 09f6978..f138401 --- a/README.md +++ b/README.md @@ -1,44 +1,78 @@ #Optparse -A BASH wrapper for getopts, for simple command-line argument parsing +A BASH wrapper for getopts and compgen, for simple command-line argument parsing an bash completion. ##What is this? -A wrapper that provides a clean and easy way to parse arguments to your BASH scripts. It lets you define short and long option names, handle flag variables, and set default values for optional arguments, all while aiming to be as minimal as possible: *One line per argument definition*. +A wrapper that provides a clean and easy way to parse arguments and create Tab completion to your BASH scripts. It lets you define short and long option names, handle flag variables, set default values for optional arguments and an optional list of posible values for options to complete, all while aiming to be as minimal as possible: *One line per argument definition*. ##Usage -##### See `sample_head.sh` for a demonstration of optparse -###1. Define your arguments +###1. Install bash-completion package. +###2. Create a script to generate completion and option parsing files. +###3. Source file optparse.bash in the script. +###4. Define your arguments in the script. -Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets and the default value (if any). +Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets, the default value (if any) and a list of posible values (if any). ```bash -optparse.define short=f long=file desc="The input file" variable=filename +optparse.define short=n long=name desc="The event name" variable=name ``` Flags are defined in exactly the same way, but with an extra parameter `value` that is assigned to the variable. ```bash -optparse.define short=v long=verbose desc="Set flag for verbose mode" variable=verbose_mode value=true default=false -``` +optparse.define short=c long=country desc="The event country" variable=country list="USA Canada Japan Brasil England" +``` + +```bash +optparse.define short=y long=year desc="The event year" variable=year list="2006 2010 2014 2020" +``` + +Another way to pass a completion list is to assign a command output to list variable as follow. + +```bash +optparse.define short=y long=year desc="The event year" variable=year list="\$(my_command)" +``` -###2. Evaluate your arguments -The `optparse.build` function creates a temporary header script based on the provided argument definitions. Simply source the file the function returns, to parse the arguments. +###5. Evaluate your arguments +The `optparse.build` function creates a header script and a configuration file in $HOME/.bash_completion.d/ based on the provided argument definitions. ```bash -source $( optparse.build ) +optparse.build script_name ``` +###5. Allow execution to the script and execute it. +##### See `sample_event_generate_completion.sh` for a demonstration. +###6. Source profile bash completion configuration, example: +```bash +$ source $HOME/.bash_completion.d/* +``` + +###7. In your command script( The script to parse arguments and generate completion ) source the optparse generated file to parse and evaluate arguments. + ####That's it! -The script can now make use of the variables. Running the script (without any arguments) should give you a neat usage description. +The script can now show completion and make use of the variables. Running the script (without any arguments) should give you a neat usage description. usage: ./script.sh [OPTIONS] OPTIONS: - -f --file : The input file - -v --verbose : Set flag for verbose mode + -n --name : The event name + -c --country : The country name + -y --year : The year -? --help : usage - + +##### See `sample_event.sh` for a demonstration. +### Now to use the command script we can write: +```bash +$ ./sample_event.sh [TAB][TAB] +$ --name --country --year +$ ./sample_event.sh --country [TAB][TAB] +$ USA Canada Japan Brasil +$ ./sample_event.sh --name "Football World Cup" --country Brasil --year 2014 +$ The Football World Cup will be in Brasil in 2014. +``` + + ##Supported definition parameters All definition parameters for `optparse.define` are provided as `key=value` pairs, seperated by an `=` sign. ####`short` @@ -53,13 +87,15 @@ the value to set the variable to. If unspecified, user is expected to provide a a short description of the argument (to build the usage description) ####`default`(optional) the default value to set the variable to if argument not specified +####`list`(optional) +the list of posible arguments for an option to autocomplete. It could be a list of strings or a command. ##Installation 1. Download/clone `optparse.bash` 2. Add ```bash -`source /path/to/optparse.bash` +source /path/to/optparse.bash ``` to `~/.bashrc` diff --git a/optparse.bash b/optparse.bash old mode 100644 new mode 100755 index 731e7f5..90a0e38 --- a/optparse.bash +++ b/optparse.bash @@ -1,4 +1,4 @@ -# Optparse - a BASH wrapper for getopts +# Optparse - a BASH wrapper for getoptions # @author : nk412 / nagarjuna.412@gmail.com optparse_usage="" @@ -6,6 +6,8 @@ optparse_contractions="" optparse_defaults="" optparse_process="" optparse_arguments_string="" +optparse_process_completion="" +options="" # ----------------------------------------------------------------------------------------------------------------------------- function optparse.throw_error(){ @@ -45,6 +47,8 @@ function optparse.define(){ local variable="$value" elif [ "$key" = "value" ]; then local val="$value" + elif [ "$key" = "list" ]; then + local list="$value" fi done @@ -57,7 +61,7 @@ function optparse.define(){ fi # build OPTIONS and help - optparse_usage="${optparse_usage}#NL#TB${short} $(rpad "$long:" 25) ${desc}" + optparse_usage="${optparse_usage}#NL#TB${short} $(printf "%-25s %s" "${long}:" "${desc}")" if [ "$default" != "" ]; then optparse_usage="${optparse_usage} [default:$default]" fi @@ -70,11 +74,22 @@ function optparse.define(){ optparse_arguments_string="${optparse_arguments_string}:" fi optparse_process="${optparse_process}#NL#TB#TB${shortname})#NL#TB#TB#TB${variable}=\"$val\";;" + + # Complete options + options="${options} ${long}" + # Complete command arguments + if [ "$list" != "" ]; then + optparse_process_completion="${optparse_process_completion}#NL#TB#TB--${variable})#NL#TB#TB#TB${variable}_list=\"$list\"#NL#TB#TB#TBCOMPREPLY=( \$(compgen -W \"\${${variable}_list}\" -- \${cur}) )#NL#TB#TB#TBreturn 0;;" + fi + } # ----------------------------------------------------------------------------------------------------------------------------- function optparse.build(){ - local build_file="/tmp/optparse-${RANDOM}.tmp" + local script=${1:?} + local build_file="${script}_optparse" + local completion_dir="$HOME/.bash_completion.d/" + local completion_file="${completion_dir}${script}" # Building getopts header here @@ -132,12 +147,36 @@ while getopts "$optparse_arguments_string" option; do esac done +EOF + +# Create completion script +mkdir -p $completion_dir + cat << EOF > $completion_file +_$script(){ + local cur prev options + COMPREPLY=() + cur=\${COMP_WORDS[COMP_CWORD]} + prev=\${COMP_WORDS[COMP_CWORD-1]} + + # The basic options we'll complete. + options="${options}" + + # Complete the arguments to some of the basic commands. + case \$prev in + $optparse_process_completion + *) + esac + COMPREPLY=(\$(compgen -W "\${options}" -- \${cur})) + return 0 +} +complete -F _$script $script EOF local -A o=( ['#NL']='\n' ['#TB']='\t' ) for i in "${!o[@]}"; do sed -i "s/${i}/${o[$i]}/g" $build_file + sed -i "s/${i}/${o[$i]}/g" $completion_file done # Unset global variables @@ -146,8 +185,6 @@ EOF unset optparse_arguments_string unset optparse_defaults unset optparse_contractions - - # Return file name to parent - echo "$build_file" + unset options } # ----------------------------------------------------------------------------------------------------------------------------- diff --git a/sample_event.sh b/sample_event.sh new file mode 100755 index 0000000..83e2d62 --- /dev/null +++ b/sample_event.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Source the sample_event_optparse file --------------------------------------------------- +source sample_event.sh_optparse + +if [ -z "$name" ] || [ -z "$country" ] || [ -z "$year" ]; then + usage; exit 1 +fi + +# Display event information +echo "The $name event will be in $country in $year." + +exit 0 + diff --git a/sample_event_generate_completion.sh b/sample_event_generate_completion.sh new file mode 100755 index 0000000..c7cf16c --- /dev/null +++ b/sample_event_generate_completion.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Source the optparse.bash file --------------------------------------------------- +source optparse.bash + +# Define options +optparse.define short=n long=name desc="The event name" variable=name +optparse.define short=c long=country desc="The event country" variable=country list="USA Canada Japan Brasil England" +optparse.define short=y long=year desc="The event year" variable=year list="2006 2010 2014 2020" + +# Generate optparse and autocompletion scripts +script_name="sample_event.sh" +optparse.build $script_name + +exit 0 From e4266871516fea4b6c15029ac3acf957364d0e69 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Fri, 4 Jul 2014 11:17:14 -0400 Subject: [PATCH 2/8] Improved option and parameter validation, added command wrapper example, Readme.md updated --- README.md | 40 +++++++++++++--------- optparse.bash | 53 +++++++++++++++++++++++------ sample_event.sh | 24 ++++++++++--- sample_event_generate_completion.sh | 3 +- wget_dir.sh | 35 +++++++++++++++++++ wget_dir_generate_completion.sh | 24 +++++++++++++ 6 files changed, 146 insertions(+), 33 deletions(-) mode change 100755 => 100644 optparse.bash create mode 100755 wget_dir.sh create mode 100755 wget_dir_generate_completion.sh diff --git a/README.md b/README.md index f138401..2db777f 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A BASH wrapper for getopts and compgen, for simple command-line argument parsing an bash completion. ##What is this? -A wrapper that provides a clean and easy way to parse arguments and create Tab completion to your BASH scripts. It lets you define short and long option names, handle flag variables, set default values for optional arguments and an optional list of posible values for options to complete, all while aiming to be as minimal as possible: *One line per argument definition*. +A wrapper that provides a clean and easy way to parse arguments and create Tab completion to your BASH scripts. You could also create wrappers for linux commands. It let you define short and long option names, handle flag variables, set default values for optional arguments and an optional list of posible values for options to complete, all while aiming to be as minimal as possible: *One line per argument definition*. ##Usage ###1. Install bash-completion package. @@ -18,12 +18,20 @@ optparse.define short=n long=name desc="The event name" variable=name Flags are defined in exactly the same way, but with an extra parameter `value` that is assigned to the variable. +```bash +optparse.define short=s long=say-hello desc="Say Hello" variable=say_hello value=true default=false +``` + +Posible arguments could be defined in exactly the same way, but with an extra parameter `list` that is assigned to the variable. + ```bash optparse.define short=c long=country desc="The event country" variable=country list="USA Canada Japan Brasil England" ``` +Required parameters are defined in exactly the same way, but with an extra parameter `required` that is assigned to the variable. + ```bash -optparse.define short=y long=year desc="The event year" variable=year list="2006 2010 2014 2020" +optparse.define short=y long=year desc="The event year" variable=year required=true ``` Another way to pass a completion list is to assign a command output to list variable as follow. @@ -33,20 +41,20 @@ optparse.define short=y long=year desc="The event year" variable=year list="\$(m ``` ###5. Evaluate your arguments -The `optparse.build` function creates a header script and a configuration file in $HOME/.bash_completion.d/ based on the provided argument definitions. +The `optparse.build` function creates a header script and a configuration file in /etc/bash_completion.d/ based on the provided argument definitions. ```bash optparse.build script_name ``` -###5. Allow execution to the script and execute it. -##### See `sample_event_generate_completion.sh` for a demonstration. -###6. Source profile bash completion configuration, example: +###6. Allow execution to the script and execute it as sudo. +##### See `sample_event_generate_completion.sh` for a demonstration. For a more complex example see `wget_dir_generate_completion.sh`. +###7. Source profile bash completion configuration, example: ```bash -$ source $HOME/.bash_completion.d/* +$ source /etc/bash_completion ``` -###7. In your command script( The script to parse arguments and generate completion ) source the optparse generated file to parse and evaluate arguments. +###8. In your command script( The script to parse arguments and generate completion ) source the optparse generated file to parse and evaluate arguments. Also you could check if there are missing options. ####That's it! The script can now show completion and make use of the variables. Running the script (without any arguments) should give you a neat usage description. @@ -56,12 +64,13 @@ The script can now show completion and make use of the variables. Running the sc OPTIONS: -n --name : The event name + -s --say-hello: Say Hello [default:false] -c --country : The country name -y --year : The year -? --help : usage -##### See `sample_event.sh` for a demonstration. +##### See `sample_event.sh` for a demonstration. For a more complex example see `wget_dir.sh`. ### Now to use the command script we can write: ```bash $ ./sample_event.sh [TAB][TAB] @@ -70,9 +79,10 @@ $ ./sample_event.sh --country [TAB][TAB] $ USA Canada Japan Brasil $ ./sample_event.sh --name "Football World Cup" --country Brasil --year 2014 $ The Football World Cup will be in Brasil in 2014. +$ ./sample_event.sh --sey-hello --name "Football World Cup" --country Brasil --year 2014 +$ Hello!!! The Football World Cup will be in Brasil in 2014. ``` - - + ##Supported definition parameters All definition parameters for `optparse.define` are provided as `key=value` pairs, seperated by an `=` sign. ####`short` @@ -89,13 +99,11 @@ a short description of the argument (to build the usage description) the default value to set the variable to if argument not specified ####`list`(optional) the list of posible arguments for an option to autocomplete. It could be a list of strings or a command. +####`required`(optional) +the requirement for the option ##Installation 1. Download/clone `optparse.bash` -2. Add -```bash -source /path/to/optparse.bash -``` -to `~/.bashrc` + diff --git a/optparse.bash b/optparse.bash old mode 100755 new mode 100644 index 90a0e38..d0f2e71 --- a/optparse.bash +++ b/optparse.bash @@ -1,3 +1,4 @@ +#!/bin/bash # Optparse - a BASH wrapper for getoptions # @author : nk412 / nagarjuna.412@gmail.com @@ -7,7 +8,11 @@ optparse_defaults="" optparse_process="" optparse_arguments_string="" optparse_process_completion="" -options="" +short_options="" +long_options="" +required_short_options="" +required_long_options="" +declare -A hash_options # ----------------------------------------------------------------------------------------------------------------------------- function optparse.throw_error(){ @@ -49,6 +54,8 @@ function optparse.define(){ local val="$value" elif [ "$key" = "list" ]; then local list="$value" + elif [ "$key" = "required" ]; then + local required="$value" fi done @@ -66,6 +73,7 @@ function optparse.define(){ optparse_usage="${optparse_usage} [default:$default]" fi optparse_contractions="${optparse_contractions}#NL#TB#TB${long})#NL#TB#TB#TBparams=\"\$params ${short}\";;" + optparse_contractions="${optparse_contractions}#NL#TB#TB${long}=*)#NL#TB#TB#TBparams=\"\$params ${short}=\${param#*=}\";;" if [ "$default" != "" ]; then optparse_defaults="${optparse_defaults}#NL${variable}=${default}" fi @@ -73,22 +81,28 @@ function optparse.define(){ if [ "$val" = "\$OPTARG" ]; then optparse_arguments_string="${optparse_arguments_string}:" fi - optparse_process="${optparse_process}#NL#TB#TB${shortname})#NL#TB#TB#TB${variable}=\"$val\";;" - + optparse_process="${optparse_process}#NL#TB#TB${shortname})#NL#TB#TB#TB${variable}=\"$val\"" + optparse_process="${optparse_process}#NL#TB#TB#TB\$(grep -q '^=' <<< \"\$OPTARG\") && hash_options[-${shortname}\"\$OPTARG\"]=${long}\"\$OPTARG\";;" # Complete options - options="${options} ${long}" + long_options="${long_options} ${long}" + short_options="${short_options} ${short}" # Complete command arguments if [ "$list" != "" ]; then - optparse_process_completion="${optparse_process_completion}#NL#TB#TB--${variable})#NL#TB#TB#TB${variable}_list=\"$list\"#NL#TB#TB#TBCOMPREPLY=( \$(compgen -W \"\${${variable}_list}\" -- \${cur}) )#NL#TB#TB#TBreturn 0;;" + optparse_process_completion="${optparse_process_completion}#NL#TB#TB${long})#NL#TB#TB#TB${variable}_list=\"$list\"#NL#TB#TB#TBCOMPREPLY=( \$(compgen -W \"\${${variable}_list}\" -- \${cur}) )#NL#TB#TB#TBreturn 0;;" fi - + # Take obligatory parameters + if [ "$required" == "true" ]; then + required_short_options="${required_short_options} ${short}" + required_long_options="${required_long_options} ${long}" + fi + hash_options["${short}"]="${long}" } # ----------------------------------------------------------------------------------------------------------------------------- function optparse.build(){ local script=${1:?} local build_file="${script}_optparse" - local completion_dir="$HOME/.bash_completion.d/" + local completion_dir="/etc/bash_completion.d/" local completion_file="${completion_dir}${script}" # Building getopts header here @@ -133,15 +147,29 @@ eval set -- "\$params" # Set default variable values $optparse_defaults -# Process using getopts +# Get required options and parameters +required_short_options="$( sed 's/^ //' <<< "$required_short_options")" +required_long_options="$( sed 's/^ //' <<< "$required_long_options")" + +# Create an associative array with with short options as keys and long options as values +declare -A hash_options=(\ +$(for option in ${short_options} +do +echo -n "[$option]=${hash_options[$option]} " +done)) + +# Process using getopts while getopts "$optparse_arguments_string" option; do + # Return error when argument is an option of type Ex: --option or --option=xxxxx + [[ -n "\$OPTARG" ]] && [[ "\${required_short_options}" == *"\${OPTARG/=*/}"* ]] && echo "Invalid parameter: \${hash_options["\${OPTARG/=*/}"]}"=\${OPTARG#*=} && usage case \$option in # Substitute actions for different variables $optparse_process :) echo "Option - \$OPTARG requires an argument" exit 1;; - *) + *) + echo "Unknown option: \$option" usage exit 1;; esac @@ -159,7 +187,7 @@ _$script(){ prev=\${COMP_WORDS[COMP_CWORD-1]} # The basic options we'll complete. - options="${options}" + options="${long_options}" # Complete the arguments to some of the basic commands. case \$prev in @@ -185,6 +213,9 @@ EOF unset optparse_arguments_string unset optparse_defaults unset optparse_contractions - unset options + unset long_options + + # Return file name to parent + echo "$build_file" } # ----------------------------------------------------------------------------------------------------------------------------- diff --git a/sample_event.sh b/sample_event.sh index 83e2d62..52cb5b1 100755 --- a/sample_event.sh +++ b/sample_event.sh @@ -3,12 +3,26 @@ # Source the sample_event_optparse file --------------------------------------------------- source sample_event.sh_optparse -if [ -z "$name" ] || [ -z "$country" ] || [ -z "$year" ]; then - usage; exit 1 +# Take options enter by user +tr ' ' '\n' <<< "$@" | grep "\-" | sed -e 's/=.*//g' | sort > /tmp/options_entered + +# Compare options defined as required with options enter by user to obtain missing options +missing_options=$( tr ' ' '\n' <<< "$required_short_options" | sort | comm -32 - /tmp/options_entered | tr '\n' ' ' ) + +if [ -n "$missing_options" ]; then + echo "Missing required option: $missing_options" + usage; + exit 1; +else + + # Display event information + if [[ "$say_hello" == "true" ]]; then + salute="Hello!!! " + fi + echo $salute "The $name event will be in $country in $year." + exit 0 fi -# Display event information -echo "The $name event will be in $country in $year." -exit 0 + diff --git a/sample_event_generate_completion.sh b/sample_event_generate_completion.sh index c7cf16c..b9dbaa0 100755 --- a/sample_event_generate_completion.sh +++ b/sample_event_generate_completion.sh @@ -5,8 +5,9 @@ source optparse.bash # Define options optparse.define short=n long=name desc="The event name" variable=name +optparse.define short=s long=say-hello desc="Say Hello" variable=say_hello value=true default=false optparse.define short=c long=country desc="The event country" variable=country list="USA Canada Japan Brasil England" -optparse.define short=y long=year desc="The event year" variable=year list="2006 2010 2014 2020" +optparse.define short=y long=year desc="The event year" variable=year required=true # Generate optparse and autocompletion scripts script_name="sample_event.sh" diff --git a/wget_dir.sh b/wget_dir.sh new file mode 100755 index 0000000..637b6c8 --- /dev/null +++ b/wget_dir.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Source the sample_event_optparse file --------------------------------------------------- +source wget_dir.sh_optparse + +# Command +cmd="wget" + +# Take options enter by user +tr ' ' '\n' <<< "$@" | grep "\-" | sed -e 's/=.*//g' | sort > /tmp/options_entered + +# Compare options defined as required with options enter by user to obtain missing options +missing_options=$( tr ' ' '\n' <<< "$required_short_options" | sort | comm -32 - /tmp/options_entered | tr '\n' ' ' ) + +if [ -n "$missing_options" ]; then + echo "Missing required option: $missing_options" + usage; + exit 1; +else + # Add options and parameters to command + for option in "$@" + do + if [ -z "${hash_options[$option]}" ]; then + cmd="$cmd $option" + else + cmd="$cmd ${hash_options[$option]}" + fi + done + # Execute command + echo "Executing command: " + echo "$cmd" + eval "$cmd" + exit 0 +fi + diff --git a/wget_dir_generate_completion.sh b/wget_dir_generate_completion.sh new file mode 100755 index 0000000..8a12a9d --- /dev/null +++ b/wget_dir_generate_completion.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Source the optparse.bash file --------------------------------------------------- +source optparse.bash + +# Define options +optparse.define short=r long=recursive desc="turn on recursive retrieving." variable=recursive value=true default=false required=true +optparse.define short=c long=continue desc="resume getting a partially-downloaded file." variable=continue value=true default=false +optparse.define short=o long=no-directories desc="Do not preserve directory hierarchy" variable=no_dirs value=true default=false +optparse.define short=h long=no-host-directories desc="Disable generation of host-prefixed directories" variable=no_host_dirs value=true default=false +optparse.define short=n long=no-parent desc="Destination directory to save all files" variable=no_parent value=true default=false required=true +optparse.define short=x long=directory-prefix desc="Destination directory to save all files" variable=directory required=true +optparse.define short=d long=progress desc="Progress indicator you wish to use." variable=progress list="bar dot" +optparse.define short=U long=user-agent desc="identify as agent-string to the HTTP server." variable=agent list="Mozilla" +optparse.define short=i long=cut-dirs desc="ignore number remote directory components." variable=ignore_dirs +optparse.define short=u long=user desc="user to use" variable=user +optparse.define short=p long=password desc="user password." variable=password + +# Generate optparse and autocompletion scripts +script_name="wget_dir.sh" +optparse.build $script_name + +exit 0 + From 68c9a08cc9e3ca5c7c45f6800d81bfa064217c91 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Fri, 4 Jul 2014 11:20:19 -0400 Subject: [PATCH 3/8] Readme.md updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2db777f..d519398 100755 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A BASH wrapper for getopts and compgen, for simple command-line argument parsing A wrapper that provides a clean and easy way to parse arguments and create Tab completion to your BASH scripts. You could also create wrappers for linux commands. It let you define short and long option names, handle flag variables, set default values for optional arguments and an optional list of posible values for options to complete, all while aiming to be as minimal as possible: *One line per argument definition*. ##Usage -###1. Install bash-completion package. +###1. Install bash-completion package from your linux repository. ###2. Create a script to generate completion and option parsing files. ###3. Source file optparse.bash in the script. ###4. Define your arguments in the script. From 82e02b08d83df144b5d3e400bae848e6bf3b41f9 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Fri, 4 Jul 2014 11:27:07 -0400 Subject: [PATCH 4/8] Readme.md updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d519398..878fb8f 100755 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A wrapper that provides a clean and easy way to parse arguments and create Tab c ###3. Source file optparse.bash in the script. ###4. Define your arguments in the script. -Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets, the default value (if any) and a list of posible values (if any). +Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets, the default value (if any) and a list of posible values (if any). Also you could define options as required to your script. ```bash optparse.define short=n long=name desc="The event name" variable=name From 4afd71945d8ecd7f9fb814984cc4a6147ed13708 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Fri, 4 Jul 2014 14:53:40 -0400 Subject: [PATCH 5/8] added clean up after self --- optparse.bash | 3 +++ 1 file changed, 3 insertions(+) diff --git a/optparse.bash b/optparse.bash index bddacb0..ce84e7f 100644 --- a/optparse.bash +++ b/optparse.bash @@ -179,6 +179,9 @@ while getopts "$optparse_arguments_string" option; do esac done +# Clean up after self +rm $build_file + EOF # Create completion script From a27d622d40af8038468bd9c9859ce69e650bf40e Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Mon, 14 Jul 2014 08:27:58 -0400 Subject: [PATCH 6/8] Fix remove tmp script --- optparse.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optparse.bash b/optparse.bash index ce84e7f..ec3fd5c 100644 --- a/optparse.bash +++ b/optparse.bash @@ -180,7 +180,7 @@ while getopts "$optparse_arguments_string" option; do done # Clean up after self -rm $build_file +[[ -z "$script" ]] && rm $build_file EOF From 51052ddb27b2c60d62cb7e2dee8e8e7f8acb644b Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Thu, 13 Nov 2014 10:42:28 -0500 Subject: [PATCH 7/8] Added completion to system file parameters, Added optional parameter completion directory to optparse.build function. Readme updated. --- README.md | 15 +++++++++++++-- optparse.bash | 21 +++++++++++++++------ wget_dir_generate_completion.sh | 16 ++++++++-------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 878fb8f..98a1098 100755 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A wrapper that provides a clean and easy way to parse arguments and create Tab c ###3. Source file optparse.bash in the script. ###4. Define your arguments in the script. -Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets, the default value (if any) and a list of posible values (if any). Also you could define options as required to your script. +Each argument to the script is defined with `optparse.define`, which specifies the option names, a short description, the variable it sets, the default value (if any) and a list of posible values (if any). Also you could define options as required to your script. If you use filesystem file parameters you could define the parameter as a file. ```bash optparse.define short=n long=name desc="The event name" variable=name @@ -40,18 +40,29 @@ Another way to pass a completion list is to assign a command output to list vari optparse.define short=y long=year desc="The event year" variable=year list="\$(my_command)" ``` +File parameters are defined in exactly the same way, but with an extra parameter `file` that is assigned to the variable. See `wget_dir_generate_completion.sh` as example. + +```bash +optparse.define short=x long=directory-prefix desc="Destination directory to save all files" variable=directory file=true required=true +``` + ###5. Evaluate your arguments The `optparse.build` function creates a header script and a configuration file in /etc/bash_completion.d/ based on the provided argument definitions. ```bash optparse.build script_name ``` +If you want to generate completion file in another location, you could path location as parameter to `optparse.build` function. + +```bash +optparse.build script_name "." +``` ###6. Allow execution to the script and execute it as sudo. ##### See `sample_event_generate_completion.sh` for a demonstration. For a more complex example see `wget_dir_generate_completion.sh`. ###7. Source profile bash completion configuration, example: ```bash -$ source /etc/bash_completion +$ source /etc/bash_completion ``` ###8. In your command script( The script to parse arguments and generate completion ) source the optparse generated file to parse and evaluate arguments. Also you could check if there are missing options. diff --git a/optparse.bash b/optparse.bash index ec3fd5c..260f861 100644 --- a/optparse.bash +++ b/optparse.bash @@ -1,5 +1,5 @@ #!/bin/bash -# Optparse - a BASH wrapper for getoptions +# Optparse - a BASH wrapper for getopts and compgen # @author : nk412 / nagarjuna.412@gmail.com optparse_usage="" @@ -54,6 +54,8 @@ function optparse.define(){ local val="$value" elif [ "$key" = "list" ]; then local list="$value" + elif [ "$key" = "file" ]; then + local file="$value" elif [ "$key" = "required" ]; then local required="$value" fi @@ -90,25 +92,31 @@ function optparse.define(){ if [ "$list" != "" ]; then optparse_process_completion="${optparse_process_completion}#NL#TB#TB${long})#NL#TB#TB#TB${variable}_list=\"$list\"#NL#TB#TB#TBCOMPREPLY=( \$(compgen -W \"\${${variable}_list}\" -- \${cur}) )#NL#TB#TB#TBreturn 0;;" fi + if [ "$file" == "true" ]; then + optparse_process_completion="${optparse_process_completion}#NL#TB#TB${long})#NL#TB#TB#TBcompopt -o default#NL#TB#TB#TBCOMPREPLY=()#NL#TB#TB#TBreturn 0;;" + fi # Take obligatory parameters if [ "$required" == "true" ]; then required_short_options="${required_short_options} ${short}" required_long_options="${required_long_options} ${long}" fi - hash_options["${short}"]="${long}" + hash_options["${short}"]="${long}" } # ----------------------------------------------------------------------------------------------------------------------------- function optparse.build(){ local script=$1 + local completion_dir=$2 if [[ -z "$script" ]]; then build_file="/tmp/optparse-${RANDOM}.tmp" else build_file="${script}_optparse" - completion_dir="/etc/bash_completion.d/" - completion_file="${completion_dir}${script}" + if [[ -z "$completion_dir" ]]; then + completion_dir="/etc/bash_completion.d" + fi + completion_file="${completion_dir}/${script}_completion" fi - + # Building getopts header here # Function usage @@ -189,6 +197,7 @@ if [[ -n "$completion_file" ]]; then cat << EOF > $completion_file _$script(){ local cur prev options + compopt +o default COMPREPLY=() cur=\${COMP_WORDS[COMP_CWORD]} prev=\${COMP_WORDS[COMP_CWORD-1]} @@ -229,6 +238,6 @@ fi unset hash_options # Return file name to parent - [[ -z "$script" ]] && echo "$build_file" + [[ -z "$script" ]] && echo "$build_file" || true } # ----------------------------------------------------------------------------------------------------------------------------- diff --git a/wget_dir_generate_completion.sh b/wget_dir_generate_completion.sh index 8a12a9d..a75265f 100755 --- a/wget_dir_generate_completion.sh +++ b/wget_dir_generate_completion.sh @@ -4,17 +4,17 @@ source optparse.bash # Define options -optparse.define short=r long=recursive desc="turn on recursive retrieving." variable=recursive value=true default=false required=true -optparse.define short=c long=continue desc="resume getting a partially-downloaded file." variable=continue value=true default=false +optparse.define short=r long=recursive desc="Turn on recursive retrieving." variable=recursive value=true default=false required=true +optparse.define short=c long=continue desc="Resume getting a partially-downloaded file." variable=continue value=true default=false optparse.define short=o long=no-directories desc="Do not preserve directory hierarchy" variable=no_dirs value=true default=false optparse.define short=h long=no-host-directories desc="Disable generation of host-prefixed directories" variable=no_host_dirs value=true default=false -optparse.define short=n long=no-parent desc="Destination directory to save all files" variable=no_parent value=true default=false required=true -optparse.define short=x long=directory-prefix desc="Destination directory to save all files" variable=directory required=true +optparse.define short=n long=no-parent desc="Do not ever ascend to the parent directory" variable=no_parent value=true default=false required=true +optparse.define short=x long=directory-prefix desc="Destination directory to save all files" variable=directory file=true required=true optparse.define short=d long=progress desc="Progress indicator you wish to use." variable=progress list="bar dot" -optparse.define short=U long=user-agent desc="identify as agent-string to the HTTP server." variable=agent list="Mozilla" -optparse.define short=i long=cut-dirs desc="ignore number remote directory components." variable=ignore_dirs -optparse.define short=u long=user desc="user to use" variable=user -optparse.define short=p long=password desc="user password." variable=password +optparse.define short=U long=user-agent desc="Identify as agent-string to the HTTP server." variable=agent list="Mozilla" +optparse.define short=i long=cut-dirs desc="Ignore number remote directory components." variable=ignore_dirs +optparse.define short=u long=user desc="User to use" variable=user +optparse.define short=p long=password desc="User password." variable=password # Generate optparse and autocompletion scripts script_name="wget_dir.sh" From e80bb72c944ed45a91eee8d400f32d0fd4afb525 Mon Sep 17 00:00:00 2001 From: danyboy1104 Date: Thu, 13 Nov 2014 11:06:09 -0500 Subject: [PATCH 8/8] minor format in code optparse.bash --- optparse.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/optparse.bash b/optparse.bash index 260f861..f7f0f83 100644 --- a/optparse.bash +++ b/optparse.bash @@ -56,7 +56,7 @@ function optparse.define(){ local list="$value" elif [ "$key" = "file" ]; then local file="$value" - elif [ "$key" = "required" ]; then + elif [ "$key" = "required" ]; then local required="$value" fi done @@ -99,7 +99,7 @@ function optparse.define(){ if [ "$required" == "true" ]; then required_short_options="${required_short_options} ${short}" required_long_options="${required_long_options} ${long}" - fi + fi hash_options["${short}"]="${long}" }