btr-hook and some generalizations
authorMichael Wallner <mike@php.net>
Thu, 16 Jan 2014 15:24:17 +0000 (16:24 +0100)
committerMichael Wallner <mike@php.net>
Thu, 16 Jan 2014 15:24:17 +0000 (16:24 +0100)
20 files changed:
bin/btr-hook [new file with mode: 0755]
bin/btrc
share/btr/btr-hook.args [new file with mode: 0644]
share/btr/btr-hook.flags [new symlink]
share/btr/btr-hook.opts [new symlink]
share/btr/btr.flags [new file with mode: 0644]
share/btr/btr.opts [new file with mode: 0644]
share/btr/btr.sh
share/btr/btrc.args [new file with mode: 0644]
share/btr/btrc.opts [new file with mode: 0644]
share/btr/btrc.sh [changed mode: 0644->0755]
share/btr/btrd.flags [new symlink]
share/btr/btrd.opts [new symlink]
share/btr/btrd.sh
share/btr/build/gnu.mk
share/btr/build/pecl.mk
share/btr/build/php.mk
share/btr/common.flags [new file with mode: 0644]
share/btr/common.sh
share/btr/opt.awk [new file with mode: 0755]

diff --git a/bin/btr-hook b/bin/btr-hook
new file mode 100755 (executable)
index 0000000..bd0187b
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+export BTR_BINDIR=$(realpath $(dirname $0)/)
+export BTR_LIBDIR=$(realpath $(dirname $0)/../share/btr)
+BTR_BANNER="Install btr hook into your VCS reporitory."
+
+. $BTR_LIBDIR/common.sh
+. $BTR_LIBDIR/btr.sh
+
+btr-parseopts "$@"
+btr-setup false
+
+if $BTR_VERBOSE
+then
+       btr-conf-show
+fi
+
+btr-confirm "Everything setup. Do you want to install the '$BTR_EXTRA_ARGS' hook for '$BTR_SOURCE_RULES'?"
+
+case "$BTR_SOURCE_RULES" in
+git)
+       case "$BTR_EXTRA_ARGS" in
+       post-commit|post-applypatch|post-merge|post-checkout)
+               BTR_HOOK_FILE="${BTR_SOURCE_ARGS:-.}/.git/hooks/$BTR_EXTRA_ARGS"
+               (
+                       if test -f "$BTR_HOOK_FILE"
+                       then
+                               grep -Esv '^BTR_' "$BTR_HOOK_FILE"
+                       else
+                               echo "#!/bin/bash"
+                       fi
+                       echo $(btr-conf-dump) "'$BTR_BINDIR/btr' -qy &"
+               ) >"$BTR_HOOK_FILE.tmp" && \
+                       chmod +x "$BTR_HOOK_FILE.tmp" && \
+                       mv "$BTR_HOOK_FILE.tmp" "$BTR_HOOK_FILE" && \
+                       $SAY "Installed into $BTR_HOOK_FILE"
+               ;;
+       esac
+       ;;
+*)
+       error "Sorry, I don't know how to install the '$BTR_EXTRA_ARGS' for '$BTR_SOURCE_RULES'."
+esac
+
+# vim: noet
index 85634bd..82b9b7f 100755 (executable)
--- a/bin/btrc
+++ b/bin/btrc
@@ -7,7 +7,7 @@ BTR_BANNER="Control \`btrd\` daemons."
 . $BTR_LIBDIR/common.sh
 . $BTR_LIBDIR/btrc.sh
 
-btrc-parseopts "$@"
+btr-parseopts "$@"
 btrc-setup
 
 case "$BTR_ACTION" in
diff --git a/share/btr/btr-hook.args b/share/btr/btr-hook.args
new file mode 100644 (file)
index 0000000..d6fd0da
--- /dev/null
@@ -0,0 +1,2 @@
+<hook> The name of the hook, e.g. 'post-commit', 'post-merge', 'post-checkout', 'post-applypatch'
+# vim: noet sw=24 ts=24
diff --git a/share/btr/btr-hook.flags b/share/btr/btr-hook.flags
new file mode 120000 (symlink)
index 0000000..9167e12
--- /dev/null
@@ -0,0 +1 @@
+btr.flags
\ No newline at end of file
diff --git a/share/btr/btr-hook.opts b/share/btr/btr-hook.opts
new file mode 120000 (symlink)
index 0000000..ead2950
--- /dev/null
@@ -0,0 +1 @@
+btr.opts
\ No newline at end of file
diff --git a/share/btr/btr.flags b/share/btr/btr.flags
new file mode 100644 (file)
index 0000000..d334319
--- /dev/null
@@ -0,0 +1,4 @@
+c      clean   Clean build
+C      vcsclean        Clean repo/branch
+
+# vim: noet sw=24 ts=24
diff --git a/share/btr/btr.opts b/share/btr/btr.opts
new file mode 100644 (file)
index 0000000..7c04356
--- /dev/null
@@ -0,0 +1,10 @@
+f:     config:file     Read configuration from a file
+s:     source:rules    Use the specified source ruleset
+b:     build:rules     Use the specified build ruleset
+r:     report:rules    Use the specifued report ruleset
+T:     test:args       Provide test runner arguments
+B:     branch:branch   Checkout this branch
+D:     directory:directory     Use this directory as work root
+S:     suffix:suffix   Append suffix to the build name
+
+# vim: noet sw=24 ts=24
index 03cbdf3..04ac847 100755 (executable)
 #!/bin/sh
 
-function btr-help {
-       btr-banner
-       echo
-       echo "Usage: $(basename $0) [-hyvqcC] [<options>]"
-       echo
-       echo "    -h, --help      Display this help"
-       echo "    -y, --yes       Always assume yes"
-       echo "    -v, --verbose   Be more verbose"
-       echo "    -q, --quiet     Be more quiet"
-       echo "    -c, --clean     Clean build"
-       echo "    -C, --vcsclean  Clean repo/branch"
-       echo
-       echo "  Options:"
-       echo "    -f, --config=<file>           Read configuration from a file"
-       echo "    -s, --source=<rules>          Use the specified source ruleset"
-       echo "    -b, --build=<rules>           Use the specified build ruleset"
-       echo "    -r, --report=<rules>          Use the specifued report ruleset"
-       echo "    -T, --test=<args>             Provide test runner arguments"
-       echo "    -B, --branch=<branch>         Checkout this branch"
-       echo "    -D, --directory=<directory>   Use this directory as work root"
-       echo "    -S, --suffix=<suffix>         Append suffix to the build name"
-       echo
-       echo "  Rules format:"
-       echo "    type=argument    e.g: git=git@github.com:m6w6/btr.git"
-       echo "                          irc=irc://btr@chat.freenode.org/#btr"
-       echo "                          mail=\"-c copy@to rcpt@to\""
-       echo "                          notify-send=\"-u low\""
-       echo
-       echo "    Note though, that some rules do not use any argument."
-       echo
-       echo "  Rulesets:"
-       for ruleset in source build report
-       do
-               printf "    %10s: %s\n" $ruleset \
-                       "$(find "$BTR_LIBDIR/$ruleset" -name '*.mk' -exec basename {} .mk \; | sort | xargs)"
-       done
-       echo
-       exit
-}
-export -f btr-help
-
-function btr-parseopts {
-       local shortoptions="hvqycCf:T:B:D:S:s:b:r:"
-       local longoptions="help,verbose,quiet,yes,clean,vcsclean,config:,test:,branch:,directory:,suffix:,source:,build:,report:"
-       local options=$(getopt \
-               --options "$shortoptions" \
-               --longoptions "$longoptions" \
-               -- "$@" \
-       )
-
-       if test $? -ne 0 ; then
-               help
-       fi
-       
-       eval set -- "$options"
-       
-       while test $# -gt 0
-       do
-               case "$1" in
-                       -h|--help)
-                               btr-help
-                               ;;
-                       -v|--verbose)
-                               BTR_QUIET=false
-                               BTR_VERBOSE=true
-                               ;;
-                       -q|--quiet)
-                               BTR_QUIET=true
-                               BTR_VERBOSE=false
-                               ;;
-                       -y|--yes)
-                               BTR_FORCEYES=true
-                               ;;
-                       -c|--clean)
-                               BTR_BUILD_CLEAN=true
-                               ;;
-                       -C|--vcsclean)
-                               BTR_SOURCE_CLEAN=true
-                               ;;
-                       ####
-                       -f|--config)
-                               source "$2"
-                               shift
-                               ;;
-                       ####
-                       -B|--branch)
-                               BTR_BRANCH="$2"
-                               shift
-                               ;;
-                       -D|--directory)
-                               BTR_RUNDIR="$2"
-                               shift
-                               ;;
-                       -S|--suffix)
-                               BTR_SUFFIX="$2"
-                               shift
-                               ;;
-                       -T|--test)
-                               BTR_TEST_ARGS="$2"
-                               shift
-                               ;;
-                       ####
-                       -s|--source)
-                               case "$2" in
-                               git*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=master
-                                       ;;
-                               svn*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=trunk
-                                       ;;
-                               cvs*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=HEAD
-                                       ;;
-                               esac
-                               BTR_SOURCE_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_SOURCE_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       -b|--build)
-                               BTR_BUILD_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_BUILD_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       -r|--report)
-                               BTR_REPORT_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_REPORT_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       ####
-                       --)
-                               # legacy
-                               if test "$2"
-                               then
-                                       BTR_SOURCE_ARGS="$2"
-                               fi
-                               shift
-                               ;;
-               esac
-               shift
-       done
-}
-export -f btr-parseopts
-
 function btr-setup {
        if test -z "$BTR_SOURCE_RULES" -o -z "$BTR_BUILD_RULES" -o -z "$BTR_REPORT_RULES"
        then
+               btr-banner
                btr-help
        fi
 
-       btr-setup-verbosity true
+       btr-setup-verbosity ${1:-true}
        btr-setup-rundir
 
        export BTR_SOURCE_RULES BTR_BUILD_RULES BTR_REPORT_RULES
@@ -174,33 +32,14 @@ function btr-setup {
        export BTR_BRANCH_DIR="$BTR_BUILD/checkout"
        export BTR_BUILD_DIR="$BTR_BUILD/build"
        export BTR_LOG_DIR="$BTR_BUILD/log"
-       export BTR_CONFIG_REPORT="$BTR_LOG_DIR/config@$DATE.log"
-       export BTR_BUILD_REPORT="$BTR_LOG_DIR/build@$DATE.log"
-       export BTR_TEST_REPORT="$BTR_LOG_DIR/test@$DATE.log"
+       export BTR_CONFIG_REPORT="$BTR_LOG_DIR/config@$BTR_DATE.log"
+       export BTR_BUILD_REPORT="$BTR_LOG_DIR/build@$BTR_DATE.log"
+       export BTR_TEST_REPORT="$BTR_LOG_DIR/test@$BTR_DATE.log"
        export BTR_LAST_REPORT=$(basename $(ls -t "$BTR_RUNDIR/$BTR_LOG_DIR/test@"* 2>/dev/null | head -n1) 2>/dev/null)
-       export BTR_REPORT="$BTR_LOG_DIR/report@$DATE.log"
+       export BTR_REPORT="$BTR_LOG_DIR/report@$BTR_DATE.log"
 }
 export -f btr-setup
 
-function btr-conf-dump {
-       echo "BTR_QUIET='$BTR_QUIET'"
-       echo "BTR_VERBOSE='$BTR_VEROSE'"
-       echo "BTR_FORCEYES='$BTR_FORCEYES'"
-       echo "BTR_BRANCH='$BTR_BRANCH'"
-       echo "BTR_SUFFIX='$BTR_SUFFIX'"
-       echo "BTR_RUNDIR='$BTR_RUNDIR'"
-       echo "BTR_SOURCE_RULES='$BTR_SOURCE_RULES'"
-       test ${BTR_SOURCE_ARGS+defined} && echo "BTR_SOURCE_ARGS='$BTR_SOURCE_ARGS'"
-       test ${BTR_SOURC_CLEAN+defined} && echo "BTR_SOURCE_CLEAN='$BTR_SOURCE_CLEAN'"
-       echo "BTR_BUILD_RULES='$BTR_BUILD_RULES'"
-       test ${BTR_BUILD_ARGS+defined}  && echo "BTR_BUILD_ARGS='$BTR_BUILD_ARGS'"
-       test ${BTR_BUILD_CLEAN+defined} && echo "BTR_BUILD_CLEAN='$BTR_BUILD_CLEAN'"
-       test ${BTR_TEST_ARGS+defined}   && echo "BTR_TEST_ARGS='$BTR_TEST_ARGS'"
-       echo "BTR_REPORT_RULES='$BTR_REPORT_RULES'"
-       test ${BTR_REPORT_ARGS+defined} && echo "BTR_REPORT_ARGS='$BTR_REPORT_ARGS'"
-}
-export -f btr-conf-dump
-
 function btr-conf-show {
        echo
        echo "# Configuration:"
diff --git a/share/btr/btrc.args b/share/btr/btrc.args
new file mode 100644 (file)
index 0000000..9526539
--- /dev/null
@@ -0,0 +1,5 @@
+[action]       s[t[at[us]]]  Show the status of the build\\nr[un]         Make a BTR run\\nc[anc[el]]    Cancel currently running job\\nt[erm[inate]] Terminate the BTR daemon
+
+<build>        The build id of the `btrd` daemon.\\nUsually similar to $repo@$branch[-$suffix].
+
+# vim: noet ts=24 sw=24
diff --git a/share/btr/btrc.opts b/share/btr/btrc.opts
new file mode 100644 (file)
index 0000000..be6cbfd
--- /dev/null
@@ -0,0 +1,3 @@
+D:     directory:directory     Use this directory as work root
+
+# vim: noet sw=24 ts=24
old mode 100644 (file)
new mode 100755 (executable)
index beff3b4..8a38bb3
@@ -1,34 +1,7 @@
 #!/bin/bash
 
-function btrc-help {
-       btr-banner
-       echo
-       echo "Usage: $(basename $0) [-hyvq] [<options>] [action] <build>"
-       echo
-       echo "    -h, --help                Display this help"
-       echo "    -y, --yes                 Always assume yes"
-       echo "    -v, --verbose             Be more verbose"
-       echo "    -q, --quiet               Be more quiet"
-       echo
-       echo "  Options:"
-       echo "    -D, --directory=<directory>"
-       echo "                              Use this directory as work root"
-       echo
-       echo "  Actions:"
-       echo "    s[tatus]                  Show the status of the build"
-       echo "    r[un]                     Make a BTR run"
-       echo "    c[ancel]                  Cancel any currently running BTR job"
-       echo "    t[erminate]               Terminate the BTR daemon"
-       echo
-       echo "  Arguments:"
-       echo "    <build>                   The build id of the \`btrd\` daemon, usually"
-       echo "                              something like \$repository@\$branch[-\$suffix]."
-       echo
-       exit
-}
-export -f btrc-help
-
 function btrc-parseargs {
+       eval set -- "$BTR_EXTRA_ARGS"
        while test $# -gt 0
        do
                case "$1" in
@@ -57,57 +30,13 @@ function btrc-parseargs {
        done
 }
 
-function btrc-parseopts {
-       local shortoptions="hvqyD:"
-       local longoptions="help,verbose,quiet,yes,directory:"
-       local options=$(getopt \
-               --options "$shortoptions" \
-               --longoptions "$longoptions" \
-               -- "$@" \
-       )
-
-       if test $? -ne 0 ; then
-               btrc-help
-       fi
-       
-       eval set -- "$options"
-       
-       while test $# -gt 1
-       do
-               case "$1" in
-               -h|--help)
-                       btrc-help
-                       ;;
-               -y|--yes)
-                       BTR_FORCEYES=true
-                       ;;
-               -v|--verbose)
-                       BTR_VERBOSE=true
-                       BTR_QUIET=false
-                       ;;
-               -q|--quiet)
-                       BTR_QUIET=true
-                       BTR_VERBOSE=false
-                       ;;
-               #
-               -D|--directory)
-                       BTR_RUNDIR="$2"
-                       shift
-                       ;;
-               #
-               --)
-                       shift
-                       btrc-parseargs "$@"
-               esac
-               shift
-       done
-}
-export -f btrc-parseopts
-
 function btrc-setup {
+       btrc-parseargs
+       
        if test -z "$BTR_BUILD"
        then
-               btrc-help
+               btr-banner
+               btr-help
        fi
        
        if test -z "$BTR_ACTION"
@@ -116,7 +45,7 @@ function btrc-setup {
        fi
        
        btr-setup-rundir
-       btr-setup-verbosity
+       btr-setup-verbosity false
        
        BTR_PIDFILE="$BTR_RUNDIR/$BTR_BUILD.pid"
        BTR_LOGFILE="$BTR_RUNDIR/$BTR_BUILD.log"
@@ -131,7 +60,7 @@ function btrc-setup {
                        cat "$BTR_LOGFILE"
                        echo
                fi
-               error "Could not find pid file of btr daemon for '$BTR_BUILD' in $BTR_RUNDIR."
+               error "Could not find btrd pid file of '$BTR_BUILD' in $BTR_RUNDIR."
        fi
 }
 export -f btrc-setup
diff --git a/share/btr/btrd.flags b/share/btr/btrd.flags
new file mode 120000 (symlink)
index 0000000..9167e12
--- /dev/null
@@ -0,0 +1 @@
+btr.flags
\ No newline at end of file
diff --git a/share/btr/btrd.opts b/share/btr/btrd.opts
new file mode 120000 (symlink)
index 0000000..ead2950
--- /dev/null
@@ -0,0 +1 @@
+btr.opts
\ No newline at end of file
index ca9f55c..725f0e4 100755 (executable)
@@ -2,7 +2,7 @@
 
 function btrd-start {
        btrd-cancel
-       DATE=$(date +%Y%m%d%H%M%S)
+       BTR_DATE=$(date +%Y%m%d%H%M%S)
        btr-setup
        btr-run &
        BTR_WORKER=$!
index 1246cb1..cbb1da1 100644 (file)
@@ -37,7 +37,7 @@ $(BTR_TEST_REPORT): $(BTR_BUILD_REPORT)
 $(BTR_BUILD_REPORT): $(BTR_CONFIG_REPORT)
        $(SAY) "Making build..."
        (cd $(BTR_BUILD_DIR) && \
-               make -j $(CPUS) \
+               make -j $(BTR_CPUS) \
        ) >$@ 2>&1
        
 $(BTR_CONFIG_REPORT): $(BTR_BRANCH_DIR)/configure | $(BTR_BUILD_DIR) $(BTR_LOG_DIR)
index a073bc5..16a7715 100644 (file)
@@ -40,7 +40,7 @@ $(BTR_TEST_REPORT): $(BTR_BUILD_REPORT)
 $(BTR_BUILD_REPORT): $(BTR_CONFIG_REPORT)
        $(SAY) "Making build..."
        (cd $(BTR_BUILD_DIR) && \
-               make -j $(CPUS) \
+               make -j $(BTR_CPUS) \
        ) >$@ 2>&1
        
 $(BTR_CONFIG_REPORT): $(BTR_BRANCH_DIR)/configure | $(BTR_BUILD_DIR) $(BTR_LOG_DIR)
index 730418b..d5b3e7c 100644 (file)
@@ -40,7 +40,7 @@ $(BTR_TEST_REPORT): $(BTR_BUILD_REPORT)
 $(BTR_BUILD_REPORT): $(BTR_CONFIG_REPORT)
        $(SAY) "Making build..."
        (cd $(BTR_BUILD_DIR) && \
-               make -j $(CPUS) \
+               make -j $(BTR_CPUS) \
        ) >$@ 2>&1
        
 $(BTR_CONFIG_REPORT): $(BTR_BRANCH_DIR)/configure | $(BTR_BUILD_DIR) $(BTR_LOG_DIR)
diff --git a/share/btr/common.flags b/share/btr/common.flags
new file mode 100644 (file)
index 0000000..f6ddc7a
--- /dev/null
@@ -0,0 +1,6 @@
+h      help    Display this help
+y      yes     Always assume yes
+v      verbose Be more verbose
+q      quiet   Be more quiet
+
+# vim: noet sw=24 ts=24
index 4c7fb74..88f522e 100755 (executable)
@@ -1,11 +1,11 @@
 #!/bin/bash
 
-export DATE=$(date +%Y%m%d%H%M%S)
-export CPUS=${CPUS:-$(nproc)}
-
-BTR_QUIET=false
-BTR_VERBOSE=false
-BTR_FORCEYES=false
+export BTR_DATE=$(date +%Y%m%d%H%M%S)
+export BTR_CPUS=${CPUS:-$(nproc)}
+export BTR_PROG=$(basename "$0")
+export BTR_QUIET=false
+export BTR_VERBOSE=false
+export BTR_FORCEYES=false
 
 function error {
        echo "$@" >&2
@@ -14,7 +14,7 @@ function error {
 export -f error
 
 function btr-banner {
-       echo "$(basename ${0:btr}) v0.4.0, (c) Michael Wallner <mike@php.net>"
+       echo "$BTR_PROG v0.4.0, (c) Michael Wallner <mike@php.net>"
        if test "$BTR_BANNER"
        then
                echo "$BTR_BANNER"
@@ -26,6 +26,7 @@ function btr-confirm {
        local CONTINUE
        if ! $BTR_FORCEYES
        then
+               echo
                echo -n "$1 (y/N) "
                read -r CONTINUE
                case $CONTINUE in
@@ -57,7 +58,7 @@ export -f btr-setup-rundir
 function btr-setup-verbosity {
        local for_make=${1:-false}
        
-       if $BTR_VERBOSE
+       if ${BTR_VERBOSE:-false}
        then
                BTR_QUIET_FLAG=
                BTR_SILENT_FLAG=
@@ -85,4 +86,251 @@ function btr-setup-verbosity {
 }
 export -f btr-setup-verbosity
 
+function btr-shortoptions {
+       (
+               local f
+               local e
+               
+               for f in common $BTR_PROG
+               do
+                       for e in flags opts
+                       do
+                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf1 <"$BTR_LIBDIR/$f.$e"
+                       done
+               done
+       ) | xargs | tr -d " "
+}
+export -f btr-shortoptions
+
+function btr-longoptions {
+       (
+               local f
+               local e
+               
+               for f in common $BTR_PROG
+               do
+                       for e in flags opts
+                       do
+                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf2 <"$BTR_LIBDIR/$f.$e"
+                       done
+               done
+       )  | sed -r -e 's/(:+).*/\1/' | xargs | tr " " ","
+}
+export -f btr-longoptions
+
+function btr-flags {
+       (
+               local f
+               local e
+               
+               for f in common $BTR_PROG
+               do
+                       test -e "$BTR_LIBDIR/$f.flags" && cut -sf1 <"$BTR_LIBDIR/$f.flags"
+               done
+       ) | xargs | tr -d " "
+}
+export -f btr-flags
+
+function btr-help-options {
+       local f o=$(
+               for f in common $BTR_PROG
+               do
+                       test -e "$BTR_LIBDIR/$f.$1" && "$BTR_LIBDIR/opt.awk" <"$BTR_LIBDIR/$f.$1"
+               done
+       )
+       if test "$o"
+       then
+               echo
+               case "$1" in
+               flags)
+                       echo "  Flags:"
+                       ;;
+               opts)
+                       echo "  Options:"
+                       ;;
+               esac
+               echo "$o"
+       fi
+}
+export -f btr-help-options
+
+function btr-help-args {
+       local a d l
+       
+       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
+       then
+               echo
+               echo "  Arguments:"
+               while read a d
+               do
+                       printf "%b\n" "$d" | fold -sw46 | while read l
+                       do
+                               printf "    %-16s %s\n" "$a" "$l"
+                               a=
+                       done
+                       echo
+               done <"$BTR_LIBDIR/$BTR_PROG.args"
+       fi
+}
+export -f btr-help-args
+
+function btr-args {
+       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
+       then
+               cut -sf1 <"$BTR_LIBDIR/$BTR_PROG.args" | xargs
+       fi
+}
+export -f btr-args
+
+function btr-help {
+       echo
+       echo "Usage: $BTR_PROG [-$(btr-flags)] [<options>]" $(btr-args)
+       btr-help-options flags
+       btr-help-options opts
+       btr-help-args
+       if test $BTR_PROG != "btrc"
+       then
+       echo
+       echo "  Rules format:"
+       echo "    type=arg  e.g: notify-send=\"-u low\""
+       echo "                   mail=\"-c copy@to rcpt@to\""
+       echo "                   irc=\"tcp://btr@chat.freenode.org/#btr\""
+       echo "                   git=\$HOME/src/btr.git"
+       echo
+       echo "    Note though, that some rules do not use any argument."
+       echo
+       echo "  Rulesets:"
+       for ruleset in source build report
+       do
+               printf "    %10s: %s\n" $ruleset \
+                       "$(find "$BTR_LIBDIR/$ruleset" -name '*.mk' -exec basename {} .mk \; | sort | xargs)"
+       done
+       echo
+       fi
+       exit
+}
+export -f btr-help
+
+function btr-parseopts {
+       local shortoptions="$(btr-shortoptions common btr-flags btr-options)"
+       local longoptions="$(btr-longoptions common btr-flags btr-options)"
+       local options
+       
+       options=$(getopt \
+               --name $BTR_PROG \
+               --options "$shortoptions" \
+               --longoptions "$longoptions" \
+               -- "$@" \
+       )
+       if test $? -ne 0
+       then
+               btr-help
+       fi
+       
+       eval set -- "$options"
+       
+       while test $# -gt 0
+       do
+               case "$1" in
+                       -h|--help)
+                               btr-banner
+                               btr-help
+                               ;;
+                       -v|--verbose)
+                               BTR_QUIET=false
+                               BTR_VERBOSE=true
+                               ;;
+                       -q|--quiet)
+                               BTR_QUIET=true
+                               BTR_VERBOSE=false
+                               ;;
+                       -y|--yes)
+                               BTR_FORCEYES=true
+                               ;;
+                       -c|--clean)
+                               BTR_BUILD_CLEAN=true
+                               ;;
+                       -C|--vcsclean)
+                               BTR_SOURCE_CLEAN=true
+                               ;;
+                       ####
+                       -f|--config)
+                               source "$2"
+                               shift
+                               ;;
+                       ####
+                       -B|--branch)
+                               BTR_BRANCH="$2"
+                               shift
+                               ;;
+                       -D|--directory)
+                               BTR_RUNDIR="$2"
+                               shift
+                               ;;
+                       -S|--suffix)
+                               BTR_SUFFIX="$2"
+                               shift
+                               ;;
+                       -T|--test)
+                               BTR_TEST_ARGS="$2"
+                               shift
+                               ;;
+                       ####
+                       -s|--source)
+                               case "$2" in
+                               git*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=master
+                                       ;;
+                               svn*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=trunk
+                                       ;;
+                               cvs*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=HEAD
+                                       ;;
+                               esac
+                               BTR_SOURCE_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_SOURCE_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       -b|--build)
+                               BTR_BUILD_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_BUILD_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       -r|--report)
+                               BTR_REPORT_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_REPORT_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       ####
+                       --)
+                               shift
+                               BTR_EXTRA_ARGS="$@"
+                               break
+                               ;;
+               esac
+               shift
+       done
+}
+export -f btr-parseopts
+
+function btr-conf-dump {
+       echo "BTR_QUIET='$BTR_QUIET'"
+       echo "BTR_VERBOSE='$BTR_VEROSE'"
+       echo "BTR_FORCEYES='$BTR_FORCEYES'"
+       echo "BTR_BRANCH='$BTR_BRANCH'"
+       echo "BTR_SUFFIX='$BTR_SUFFIX'"
+       echo "BTR_RUNDIR='$BTR_RUNDIR'"
+       echo "BTR_SOURCE_RULES='$BTR_SOURCE_RULES'"
+       test ${BTR_SOURCE_ARGS+defined} && echo "BTR_SOURCE_ARGS='$BTR_SOURCE_ARGS'"
+       test ${BTR_SOURC_CLEAN+defined} && echo "BTR_SOURCE_CLEAN='$BTR_SOURCE_CLEAN'"
+       echo "BTR_BUILD_RULES='$BTR_BUILD_RULES'"
+       test ${BTR_BUILD_ARGS+defined}  && echo "BTR_BUILD_ARGS='$BTR_BUILD_ARGS'"
+       test ${BTR_BUILD_CLEAN+defined} && echo "BTR_BUILD_CLEAN='$BTR_BUILD_CLEAN'"
+       test ${BTR_TEST_ARGS+defined}   && echo "BTR_TEST_ARGS='$BTR_TEST_ARGS'"
+       echo "BTR_REPORT_RULES='$BTR_REPORT_RULES'"
+       test ${BTR_REPORT_ARGS+defined} && echo "BTR_REPORT_ARGS='$BTR_REPORT_ARGS'"
+}
+export -f btr-conf-dump
+
 # vim: noet
diff --git a/share/btr/opt.awk b/share/btr/opt.awk
new file mode 100755 (executable)
index 0000000..cdc0b76
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/awk -f
+
+BEGIN {
+       FS="\t"
+}
+
+{
+       sub("[[:space:]]*#.*", "");
+       if (NF) {
+               if (sub("::", "[=<", $2)) {
+                       $2 = $2">]"
+               }
+               if (sub(":", "=<", $2)) {
+                       $2 = $2">"
+               }
+               sub(":+", "", $1)
+               printf "    -%s, --%-24s %s\n", $1, $2, $3
+       }
+}