[152524] contrib/mp-buildbot/mpbb
larryv at macports.org
larryv at macports.org
Sun Sep 11 18:58:52 PDT 2016
Revision: 152524
https://trac.macports.org/changeset/152524
Author: larryv at macports.org
Date: 2016-09-11 18:58:52 -0700 (Sun, 11 Sep 2016)
Log Message:
-----------
mpbb: Parse command-line arguments with a function
This will facilitate the separation of global options and subcommand
options because each subcommand function will be able to parse its own
arguments with only a few lines of code instead of an unwieldy `case`
statement.
The new function requires enhanced getopt(1) [*], which is not included
with macOS but is available in the `getopt` port. It recognizes flags in
`--OPT=ARG` form, permits optional arguments, and correctly handles
missing arguments.
[*]: http://frodo.looijaard.name/project/getopt
Modified Paths:
--------------
contrib/mp-buildbot/mpbb
Modified: contrib/mp-buildbot/mpbb
===================================================================
--- contrib/mp-buildbot/mpbb 2016-09-12 01:58:50 UTC (rev 152523)
+++ contrib/mp-buildbot/mpbb 2016-09-12 01:58:52 UTC (rev 152524)
@@ -25,36 +25,36 @@
OPTIONS
- --archive-site URL
+ --archive-site=URL
Base URL of the packages archive to check whether an archive was not
published yet. Default is "https://packages.macports.org".
--help
Print this usage message.
- --prefix PREFIX
+ --prefix=PREFIX
The prefix of the MacPorts installation that will build the ports. Defaults
to "/opt/local".
- --svn BINARY
+ --svn=BINARY
Absolute path to the svn binary that you want to use for SVN operations. The
default is to find svn in your path.
- --svn-url SVNURL
+ --svn-url=SVNURL
URL to a Subversion repository in a format accepted by Subversion. The
referenced folder must contain a dports and a base folder. The default is
"https://svn.macports.org/repository/macports/trunk".
- --svn-revision REVISION
+ --svn-revision=REVISION
Revision number in the specified Subversion repository to checkout. Defaults
to "HEAD".
- --staging-dir DIR
+ --staging-dir=DIR
Directory where new distributable archives should be copied for deployment
on the archive server. Defaults to the 'archive-staging' subfolder in the
current directory.
- --work-dir WORKDIR
+ --work-dir=WORKDIR
A scratch area that mpbb will use to put temporary files, ideally kept
between builds. Your MacPorts installation in --prefix needs to be able to
access this location. Defaults to your current directory, or
@@ -96,73 +96,76 @@
usage
fi
-## Flag Parsing
-while [[ $# -gt 0 ]]; do
- key=$1
+# TODO Documentation, obviously :)
+parseopt() {
+ # Be stricter about this than getopt(1) is.
+ if ! [[ ${1-} =~ ^[[:alnum:]-]+:{0,2}(,[[:alnum:]-]+:{0,2})*$ ]]; then
+ err 'Invalid argument given to parseopt'
+ return 3
+ fi
- case "$key" in
- --*)
- # Shellcheck doesn't see the invocations in the sourced
- # scripts, so we'll have to disable a number of false
- # positives here.
-
- # shellcheck disable=SC2034
- case "$key" in
- --archive-site)
- option_archive_site=$2
- shift
- ;;
- --help)
- option_help=1
- ;;
- --port)
- # Deprecated and will be removed in the near future.
- option_port=$2
- shift
- ;;
- --prefix)
- option_prefix=$2
- shift
- ;;
- --staging-dir)
- option_staging_dir=$2
- shift
- ;;
- --svn)
- option_svn=$2
- shift
- ;;
- --svn-url)
- option_svn_url=$2
- shift
- ;;
- --svn-revision)
- option_svn_revision=$2
- shift
- ;;
- --work-dir)
- option_work_dir=$2
- shift
- ;;
- --)
- shift
- break
- ;;
- *)
- err "Unknown option: ${key}"
- option_help=1
- break
- ;;
- esac
-
- shift
+ # Use "--options +" to prevent arguments from being rearranged.
+ local opts
+ opts=$(getopt --name "$0" --opt + --longopt "$1" -- "${@:2}")
+ case $? in
+ 0)
;;
+ 1)
+ # getopt(1) will print the bad argument to standard error.
+ echo >&2 "Try \`$0 --help' for more information."
+ return 2
+ ;;
*)
- break
+ err 'getopt encountered an internal error'
+ return 3
;;
esac
-done
+ readonly opts
+ local -a validopts
+ IFS=, read -ra validopts <<<"$1"
+ readonly validopts=("${validopts[@]/#/--}")
+
+ eval set -- "$opts"
+
+ local opt validopt
+ # getopt(1) ensures that the options are always terminated with "--".
+ while [[ $1 != -- ]]; do
+ opt=$1
+ shift
+ # XXX Do NOT touch anything below unless you know exactly what
+ # you're doing (http://mywiki.wooledge.org/BashFAQ/006#eval).
+ for validopt in "${validopts[@]}"; do
+ if [[ $validopt == "$opt:" || $validopt == "$opt::" ]]; then
+ opt=${opt#--}
+ # $1 is null for omitted optional arguments.
+ eval option_"${opt//-/_}"'=$1'
+ shift
+ continue 2
+ fi
+ if [[ $validopt == "$opt" ]]; then
+ opt=${opt#--}
+ eval option_"${opt//-/_}"'=1'
+ continue 2
+ fi
+ done
+ # Unreachable unless there is a bug in this function or in getopt(1).
+ err 'parseopt encountered an internal error'
+ return 3
+ done
+ args=("${@:2}")
+}
+
+unset GETOPT_COMPATIBLE
+if getopt -T >/dev/null; then
+ # http://frodo.looijaard.name/project/getopt
+ err "Cannot find an enhanced getopt(1)"
+ exit 3
+fi
+
+# Process options.
+parseopt archive-site:,help,port:,prefix:,svn:,svn_revision:,svn_url:,staging-dir:,work-dir: "$@" || exit
+
# Use sensible defaults for options that weren't set on the command line.
: "${option_port=}"
: "${option_prefix=/opt/local}"
@@ -178,6 +181,11 @@
# Not really options, but pretend they are because they're global.
option_log_dir=${option_work_dir}/logs
+# shellcheck disable=SC2086
+# Set up the positional arguments for the subcommand. With "set -u"
+# enabled, "${foo[@]}" doesn't work if foo is empty.
+set -- ${args+"${args[@]}"}
+
## If subcommand help is requested, print that
if [[ $option_help -eq 1 ]]; then
usage
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20160911/ae0f1b57/attachment.html>
More information about the macports-changes
mailing list