Handle --config FILE[,FILE,...] in parse_options.sh.

This commit is contained in:
Daniel Nichter
2012-01-24 11:18:41 -07:00
parent cab3bb6eab
commit 4905e3503c
3 changed files with 72 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
# This program is copyright 2011 Percona Inc. # This program is copyright 2011-2012 Percona Inc.
# Feedback and improvements are welcome. # Feedback and improvements are welcome.
# #
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED # THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
@@ -22,9 +22,9 @@
# parse_options parses Perl POD options from Bash tools and creates # parse_options parses Perl POD options from Bash tools and creates
# global variables for each option. # global variables for each option.
# *********************************************************** # XXX
# GLOBAL $TMPDIR AND $TOOL MUST BE SET BEFORE USING THIS LIB! # GLOBAL $TMPDIR AND $TOOL MUST BE SET BEFORE USING THIS LIB!
# *********************************************************** # XXX
# Parsing command line options with Bash is easy until we have to dealt # Parsing command line options with Bash is easy until we have to dealt
# with values that have spaces, e.g. --option="hello world". This is # with values that have spaces, e.g. --option="hello world". This is
@@ -39,10 +39,10 @@
# because it's a line from a file, not a command line where Bash will # because it's a line from a file, not a command line where Bash will
# interpret the quotes and return a single value in the code. So... # interpret the quotes and return a single value in the code. So...
# *************************************************** # XXX
# BE CAREFUL MAKING CHANGES TO THIS LIB AND MAKE SURE # BE CAREFUL MAKING CHANGES TO THIS LIB AND MAKE SURE
# t/lib/bash/parse_options.sh STILL PASSES! # t/lib/bash/parse_options.sh STILL PASSES!
# *************************************************** # XXX
set -u set -u
@@ -52,8 +52,8 @@ ARGV="" # Non-option args (probably input files)
EXT_ARGV="" # Everything after -- (args for an external command) EXT_ARGV="" # Everything after -- (args for an external command)
HAVE_EXT_ARGV="" # Got --, everything else is put into EXT_ARGV HAVE_EXT_ARGV="" # Got --, everything else is put into EXT_ARGV
OPT_ERRS=0 # How many command line option errors OPT_ERRS=0 # How many command line option errors
OPT_VERSION="no" # If --version was specified OPT_VERSION="" # If --version was specified
OPT_HELP="no" # If --help was specified OPT_HELP="" # If --help was specified
PO_DIR="$TMPDIR/po" # Directory with program option spec files PO_DIR="$TMPDIR/po" # Directory with program option spec files
# Sub: usage # Sub: usage
@@ -80,13 +80,13 @@ usage() {
usage_or_errors() { usage_or_errors() {
local file="$1" local file="$1"
if [ "$OPT_VERSION" = "yes" ]; then if [ "$OPT_VERSION" ]; then
local version=$(grep '^pt-[^ ]\+ [0-9]' "$file") local version=$(grep '^pt-[^ ]\+ [0-9]' "$file")
echo "$version" echo "$version"
return 1 return 1
fi fi
if [ "$OPT_HELP" = "yes" ]; then if [ "$OPT_HELP" ]; then
usage "$file" usage "$file"
echo echo
echo "Command line options:" echo "Command line options:"
@@ -127,15 +127,18 @@ parse_options() {
local file="$1" local file="$1"
shift shift
# Reset the globals (mostly for testing). # XXX
# Reset all globals else t/lib/bash/parse_options.sh will fail.
# XXX
ARGV="" ARGV=""
EXT_ARGV="" EXT_ARGV=""
HAVE_EXT_ARGV="" HAVE_EXT_ARGV=""
OPT_ERRS=0 OPT_ERRS=0
OPT_VERSION="no" OPT_VERSION=""
OPT_HELP="no" OPT_HELP=""
PO_DIR="$TMPDIR/po" PO_DIR="$TMPDIR/po"
# Ready the directory for the program option (po) spec files.
if [ ! -d "$PO_DIR" ]; then if [ ! -d "$PO_DIR" ]; then
mkdir "$PO_DIR" mkdir "$PO_DIR"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@@ -150,9 +153,26 @@ parse_options() {
exit 1 exit 1
fi fi
_parse_pod "$file" _parse_pod "$file" # Parse POD into program option (po) spec files
_eval_po _eval_po # Eval po into existence with default values
_parse_config_files
# If the first option is --config FILES, then remove it and use
# those files instead of the default config files.
if [ $# -ge 2 ] && [ "$1" = "--config" ]; then
shift # --config
local user_config_files="$1"
shift # that ^
local old_ifs="$IFS"
IFS=","
for user_config_file in $user_config_files; do
_parse_config_files "$user_config_file"
done
IFS="$old_ifs"
else
_parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
fi
# Finally, parse the command line.
_parse_command_line "$@" _parse_command_line "$@"
} }
@@ -251,8 +271,8 @@ _eval_po() {
} }
_parse_config_files() { _parse_config_files() {
for config_file in "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
do for config_file in "$@"; do
# Next config file if this one doesn't exist. # Next config file if this one doesn't exist.
test -f "$config_file" || continue test -f "$config_file" || continue
@@ -270,6 +290,9 @@ _parse_config_files() {
# and end-of-line # comments. # and end-of-line # comments.
config_opt="$(echo "$config_opt" | sed -e 's/^[ ]*//' -e 's/[ ]*\$//' -e 's/[ ]*=[ ]*/=/' -e 's/[ ]*#.*$//')" config_opt="$(echo "$config_opt" | sed -e 's/^[ ]*//' -e 's/[ ]*\$//' -e 's/[ ]*=[ ]*/=/' -e 's/[ ]*#.*$//')"
# Skip blank lines.
[ "$config_opt" = "" ] && continue
# Options in a config file are not prefixed with --, # Options in a config file are not prefixed with --,
# but command line options are, so one or the other has # but command line options are, so one or the other has
# to add or remove the -- prefix. We add it for config # to add or remove the -- prefix. We add it for config
@@ -278,7 +301,9 @@ _parse_config_files() {
if ! [ "$HAVE_EXT_ARGV" ]; then if ! [ "$HAVE_EXT_ARGV" ]; then
config_opt="--$config_opt" config_opt="--$config_opt"
fi fi
_parse_command_line "$config_opt" _parse_command_line "$config_opt"
done < "$config_file" done < "$config_file"
HAVE_EXT_ARGV="" # reset for each file HAVE_EXT_ARGV="" # reset for each file

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
TESTS=49 TESTS=63
TMPFILE="$TEST_TMPDIR/parse-opts-output" TMPFILE="$TEST_TMPDIR/parse-opts-output"
TOOL="pt-stalk" TOOL="pt-stalk"
@@ -136,6 +136,28 @@ parse_options "$T_LIB_DIR/samples/bash/po001.sh" --string-opt zzz
is "$OPT_STRING_OPT" "zzz" "Command line overrides config file" is "$OPT_STRING_OPT" "zzz" "Command line overrides config file"
# User-specified --config
parse_options "$T_LIB_DIR/samples/bash/po001.sh" --config "$T_LIB_DIR/samples/bash/config003.conf" --string-opt bar
is "$OPT_STRING_OPT" "bar" "--config string option"
is "$OPT_STRING_OPT2" "foo" "--config string option2"
is "$OPT_TYPELESS_OPTION" "" "--config typeless option"
is "$OPT_NOPTION" "yes" "--config negatable option"
is "$OPT_INT_OPT" "123" "--config int option"
is "$OPT_INT_OPT2" "42" "--config int option2"
is "$OPT_VERSION" "" "--config version option"
is "$ARGV" "" "--config ARGV"
is "$EXT_ARGV" "" "--config External ARGV"
# Multiple --config files, last should take precedence.
parse_options "$T_LIB_DIR/samples/bash/po001.sh" --config $T_LIB_DIR/samples/bash/config001.conf,$T_LIB_DIR/samples/bash/config002.conf
is "$OPT_STRING_OPT" "hello world" "Two --config string option"
is "$OPT_TYPELESS_OPTION" "yes" "Two --config typeless option"
is "$OPT_INT_OPT" "100" "Two --config int option"
is "$ARGV" "" "Two --config ARGV"
is "$EXT_ARGV" "--host=127.1 --user=daniel" "Two--config External ARGV"
# ############################################################################ # ############################################################################
# Option values with spaces. # Option values with spaces.
# ############################################################################ # ############################################################################

View File

@@ -0,0 +1,2 @@
string-opt=from config file
int-opt=123