flush
authorMichael Wallner <mike@php.net>
Fri, 10 Jan 2014 10:26:57 +0000 (11:26 +0100)
committerMichael Wallner <mike@php.net>
Fri, 10 Jan 2014 10:26:57 +0000 (11:26 +0100)
20 files changed:
README.md
TODO.md [new file with mode: 0644]
bin/btr
bin/btr-irc-relay [new file with mode: 0755]
bin/btr-irc-send [new file with mode: 0755]
curl.example.conf [new file with mode: 0644]
lib/btr/btr.sh
lib/btr/build/composer.mk [new file with mode: 0644]
lib/btr/build/gnu.mk
lib/btr/build/pecl.mk
lib/btr/build/php.mk
lib/btr/irc.php [new file with mode: 0755]
lib/btr/report/irc.mk [new file with mode: 0644]
lib/btr/report/mail.mk
lib/btr/report/notify-send.mk
lib/btr/report/twilio.mk
lib/btr/source/cvs.mk [new file with mode: 0644]
lib/btr/source/git.mk
lib/btr/source/svn.mk
php.example.conf [new file with mode: 0644]

index f482cc8..23e91e0 100644 (file)
--- a/README.md
+++ b/README.md
@@ -8,34 +8,57 @@ A simple tool to automate reporting of build and test results.
 
 ### Currently supported rulesets:
 
-* ***source:*** git, svn
-* ***build:*** php, pecl, gnu
-* ***report:*** mail, notify-send
+* ***source:*** git, svn, cvs
+* ***build:*** php, pecl, gnu, composer
+* ***report:*** mail, notify-send, twilio
 
 #### Usage
 ```
-Usage: btr [-hv] [<options>] <repository>
+Usage: btr [-hyvqcC] [<options>]
 
     -h, --help      Display this help
+    -y, --yes       Always assume yes
     -v, --verbose   Be more verbose
+    -q, --quiet     Be more quiet
+    -c, --clean     Clean build
+    -C, --vcsclean  Clean repo/branch
 
   Options:
+    -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
-    -C, --configure=<options>     Define $CONFIGURE options
+
+  Rules format:
+    type=argument    e.g: git=git@github.com:m6w6/btr.git
+                          irc=irc://btr@chat.freenode.org/#btr
+                          mail="-c copy@to rcpt@to"
+                          notify-send="-u low"
+
+    Note though, that some rules do not use any argument.
 
   Rulesets:
-        source: git svn
-         build: gnu pecl php
-        report: mail notify-send
-```
-#### Examples
+        source: cvs git svn
+         build: composer gnu pecl php
+        report: irc mail notify-send twilio
 
-`./bin/btr -s svn -b pecl -r mail -v https://svn.php.net/repository/pecl/http -B branches/DEV_2`
+  Examples:
 
-`USER=mike@php.net TESTS=tests/output ./bin/btr -s git -b php -r mail git@git.php.net:php-src.git`
+  Clone PHP's git, use PHP-5.5 branch, build with php ruleset and
+  run the test suite with valgrind (-m) on a debug build and report
+  the results with a simple OSD notification:
+    $ btr -s git=git@php.net:php/php-src.git -B PHP-5.5 \
+          -b "php=--enable-debug" -T-m -r notify-send
+  See also php.example.conf
 
+  Clone CURL's git (use master), build with GNU autotools
+  ruleset which runs 'make check' and mail the report to the
+  current user. Verbosely show all actions taken:
+    $ btr -v -s git=https://github.com/bagder/curl.git -b gnu -r mail
+  See also curl.example.conf
+
+```
diff --git a/TODO.md b/TODO.md
new file mode 100644 (file)
index 0000000..fb03ab8
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,15 @@
+# Report
+
+* Twilio  
+  Sanitize and make usable
+* Mail  
+  Tidy up
+
+# Source
+
+* Mercurial  
+  Implement!
+
+# Administrative
+
+* Get a release out
diff --git a/bin/btr b/bin/btr
index 022416c..7446454 100755 (executable)
--- a/bin/btr
+++ b/bin/btr
@@ -8,19 +8,22 @@ export LIBDIR=$(realpath $(dirname $0)/../lib/btr)
 
 . $LIBDIR/btr.sh
 
+QUIET=false
 VERBOSE=false
+FORCEYES=false
 
-parseopts $@
+parseopts "$@"
 setup
 
 if $VERBOSE
 then
        show_conf
-       confirm "Do you want to continue?" || exit
+       $FORCEYES || confirm "Everything setup. Do you want to continue?" || exit
 fi
 
-REPORT="$(make -s -C $BTRDIR -f $LIBDIR/source/$SOURCE_RULES.mk && \
-       make -s -C $BTRDIR -f $LIBDIR/build/$BUILD_RULES.mk)"
-make -s -C $BTRDIR -f $LIBDIR/report/$REPORT_RULES.mk REPORT="$REPORT"
+set -e
+make -e $SILENT_FLAG -C $BTRDIR -f $LIBDIR/source/$SOURCE_RULES.mk
+make -e $SILENT_FLAG -C $BTRDIR -f $LIBDIR/build/$BUILD_RULES.mk
+make -e $SILENT_FLAG -C $BTRDIR -f $LIBDIR/report/$REPORT_RULES.mk
 
 # vim: noet
diff --git a/bin/btr-irc-relay b/bin/btr-irc-relay
new file mode 100755 (executable)
index 0000000..7bda9fc
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+<?php
+
+require __DIR__."/../lib/btr/irc.php";
+
+if ($argc != 3) {
+       fatal("Usage: %s <url> <fifo>\n", basename($argv[0]));
+}
+
+if (!($hnd = mkfifo($_SERVER["argv"][2]))) {
+       fatal("%s", error_get_last()["message"]);
+} else {
+       pcntl_signal(SIGINT, "fatal");
+       pcntl_signal(SIGTERM, "fatal");
+       pcntl_signal(SIGQUIT, "fatal");
+       pcntl_signal(SIGHUP, function() {
+               // daemonize
+               switch (pcntl_fork()) {
+               case 0:
+                       if (posix_setsid() !== -1) {
+                               break;
+                       }
+               case -1:
+                       fatal();
+                       break;
+               default:
+                       $_SERVER["argv"][2] = null;
+                       exit;
+               }
+       });
+       register_shutdown_function(function() {
+               if (isfifo($_SERVER["argv"][2])) {
+                       @unlink($_SERVER["argv"][2]);
+               }
+       });
+}
+
+$rfd = $wfd = [];
+$bot = new Client($argv[1], function() use($hnd, &$rfd) {
+       stream_set_blocking($hnd, false);
+       $rfd[] = $hnd;
+});
+
+do {
+       if (false === ($r = $bot->getSession()->run($rfd, $wfd))) {
+               break;
+       }
+       while ($r && $r[0] && ($message = fgets($r[0][0]))) {
+               $bot->send($message);
+       }
+       pcntl_signal_dispatch();
+} while (!feof($hnd));
+
+# vim: noet
diff --git a/bin/btr-irc-send b/bin/btr-irc-send
new file mode 100755 (executable)
index 0000000..4b2259a
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+<?php
+
+require __DIR__."/../lib/btr/irc.php";
+
+if ($argc != 3) {
+       fatal("Usage: %s <url|fifo> <message>\n", basename($argv[0]));
+}
+
+if (isfifo($argv[1])) {
+       file_put_contents($argv[1], $argv[2]);
+} else {
+       $bot = new Client($argv[1], function($bot) {
+               $bot->send($_SERVER["argv"][2]);
+       });
+       $bot->getSession()->onNumeric = function($origin, $event) use ($bot) {
+               if ($event == \irc\client\RPL_ENDOFNAMES) {
+                       $bot->getSession()->disconnect();
+               }
+       };
+       $bot->getSession()->run();
+}
+
+# vim: noet
diff --git a/curl.example.conf b/curl.example.conf
new file mode 100644 (file)
index 0000000..0039ed6
--- /dev/null
@@ -0,0 +1,5 @@
+VERBOSE=true
+SOURCE_RULES=git
+SOURCE_ARGS=https://github.com/bagder/curl.git
+BUILD_RULES=gnu
+REPORT_RULES=mail
index 96376ef..d0db095 100755 (executable)
@@ -1,21 +1,34 @@
 #!/bin/sh
 
 function help {
-       echo "btr v0.2.0, (c) Michael Wallner <mike@php.net>"
+       echo "btr v0.3.0, (c) Michael Wallner <mike@php.net>"
        echo
-       echo "Usage: $(basename $0) [-hv] [<options>] <repository>"
+       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 "    -C, --configure=<options>     Define \$CONFIGURE options"
+       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
@@ -24,12 +37,27 @@ function help {
                        "$(find "$LIBDIR/$ruleset" -name '*.mk' -exec basename {} .mk \; | sort | xargs)"
        done
        echo
+       echo "  Examples:"
+       echo 
+       echo "  Clone PHP's git, use PHP-5.5 branch, build with php ruleset and"
+       echo "  run the test suite with valgrind (-m) on a debug build and report"
+       echo "  the results with a simple OSD notification:"
+       echo "    $ btr -s git=git@php.net:php/php-src.git -B PHP-5.5 \\"
+       echo "          -b \"php=--enable-debug\" -T-m -r notify-send"
+       echo "  See also php.example.conf"
+       echo
+       echo "  Clone CURL's git (use master), build with GNU autotools"
+       echo "  ruleset which runs 'make check' and mail the report to the"
+       echo "  current user. Verbosely show all actions taken:"
+       echo "    $ btr -v -s git=https://github.com/bagder/curl.git -b gnu -r mail"
+       echo "  See also curl.example.conf"
+       echo
        exit
 }
 
 function parseopts {
-       local shortoptions="hvB:D:S:C:s:b:r:"
-       local longoptions="help,verbose,branch:,directory:,suffix:,configure:,source:,build:,report:"
+       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" \
@@ -49,8 +77,27 @@ function parseopts {
                                help
                                ;;
                        -v|--verbose)
+                               QUIET=false
                                VERBOSE=true
                                ;;
+                       -q|--quiet)
+                               QUIET=true
+                               VERBOSE=false
+                               ;;
+                       -y|--yes)
+                               FORCEYES=true
+                               ;;
+                       -c|--clean)
+                               BUILD_CLEAN=true
+                               ;;
+                       -C|--vcsclean)
+                               SOURCE_CLEAN=true
+                               ;;
+                       ####
+                       -f|--config)
+                               source "$2"
+                               shift
+                               ;;
                        ####
                        -B|--branch)
                                BRANCH="$2"
@@ -64,43 +111,44 @@ function parseopts {
                                SUFFIX="$2"
                                shift
                                ;;
-                       -C|--configure)
-                               CONFIGURE="$2"
+                       -T|--test)
+                               TEST_ARGS="$2"
                                shift
                                ;;
                        ####
                        -s|--source)
                                case "$2" in
-                                       git)
-                                               SOURCE_RULES="git"
-                                               test -z "$BRANCH" && BRANCH="master"
-                                               ;;
-                                       svn)
-                                               SOURCE_RULES="svn"
-                                               test -z "$BRANCH" && BRANCH="trunk"
-                                               ;;
+                               git*)
+                                       test -z "$BRANCH" && BRANCH=master
+                                       ;;
+                               svn*)
+                                       test -z "$BRANCH" && BRANCH=trunk
+                                       ;;
+                               cvs*)
+                                       test -z "$BRANCH" && BRANCH=HEAD
+                                       ;;
                                esac
+                               SOURCE_RULES="$(cut -d= -f1 <<<$2)"
+                               SOURCE_ARGS="$(cut -s -d= -f2- <<<$2)"
                                shift
                                ;;
                        -b|--build)
-                               case "$2" in
-                                       *)
-                                               BUILD_RULES="$2"
-                                               ;;
-                               esac
+                               BUILD_RULES="$(cut -d= -f1 <<<$2)"
+                               BUILD_ARGS="$(cut -s -d= -f2- <<<$2)"
                                shift
                                ;;
                        -r|--report)
-                               case "$2" in
-                                       *)
-                                               REPORT_RULES="$2"
-                                               ;;
-                               esac
+                               REPORT_RULES="$(cut -d= -f1 <<<$2)"
+                               REPORT_ARGS="$(cut -s -d= -f2- <<<$2)"
                                shift
                                ;;
                        ####
                        --)
-                               SOURCE_URL="$2"
+                               # legacy
+                               if test "$2"
+                               then
+                                       SOURCE_ARGS="$2"
+                               fi
                                shift
                                ;;
                esac
@@ -114,22 +162,52 @@ function error {
 }
 
 function setup {
-       if test -z "$SOURCE_URL" -o -z "$SOURCE_RULES" -o -z "$BUILD_RULES" -o -z "$REPORT_RULES"
+       if test -z "$SOURCE_RULES" -o -z "$BUILD_RULES" -o -z "$REPORT_RULES"
        then
                help
        fi
 
-       export SOURCE_URL BRANCH SOURCE_RULES BUILD_RULES REPORT_RULES
-
+       if $VERBOSE
+       then
+               QUIET_FLAG=
+               SILENT_FLAG=
+               VERBOSE_FLAG="-v"
+               SAY="echo; echo"
+       elif $QUIET
+       then
+               QUIET_FLAG="-q"
+               SILENT_FLAG="-s"
+               VERBOSE_FLAG=
+               SAY="@true"
+       else
+               QUIET_FLAG=
+               SILENT_FLAG="-s"
+               VERBOSE_FLAG=
+               SAY="@echo"
+       fi
+       
+       export QUIET VERBOSE FORCEYES QUIET_FLAG SILENT_FLAG VERBOSE_FLAG SAY
+       
        if test -z "$BTRDIR"
        then
                export BTRDIR="/tmp/btr"
        else
                export BTRDIR=$(realpath "$BTRDIR")
        fi
+       
+       mkdir -p "$BTRDIR" || error "Could not create $BTRDIR"
 
-       export REPO=$(basename $(sed -re 's~^.*[/:]~~' <<<"$SOURCE_URL") .git)
-       export SAFE_BRANCH=$(tr ":" "_" <<<$(basename "$BRANCH"))
+       
+       export SOURCE_RULES BUILD_RULES REPORT_RULES
+       test -z "$SOURCE_ARGS"  || export SOURCE_ARGS
+       test -z "$SOURCE_CLEAN" || export SOURCE_CLEAN
+       test -z "$BUILD_ARGS"   || export BUILD_ARGS
+       test -z "$BUILD_CLEAN"  || export BUILD_CLEAN
+       test -z "$TEST_ARGS"    || export TEST_ARGS
+       test -z "$REPORT_ARGS"  || export REPORT_ARGS
+       REPO=$(basename $(sed -re 's~^.*[/:#]~~' <<<"$SOURCE_ARGS") .git)
+       SAFE_BRANCH=$(tr ":" "_" <<<$(basename "$BRANCH"))
+       export REPO BRANCH SAFE_BRANCH
 
        if test -z "$SUFFIX"
        then
@@ -144,28 +222,40 @@ function setup {
        export CONFIG_REPORT="btr+config-$BUILD-$DATE"
        export BUILD_REPORT="btr+build-$BUILD-$DATE"
        export TEST_REPORT="btr+tests-$BUILD-$DATE"
-       export LAST_REPORT=$(basename $(ls -t "$BTRDIR/btr+tests-$BUILD"* 2>/dev/null | tail -n1) 2>/dev/null)
-       export REPORT=""
+       export LAST_REPORT=$(basename $(ls -t "$BTRDIR/btr+tests-$BUILD"* 2>/dev/null | head -n1) 2>/dev/null)
+       export REPORT="btr+report-$BUILD-$DATE"
 }
 
 function show_conf {
        echo
-       echo "BTRDIR             = $BTRDIR"
-       echo "BINDIR             = $BINDIR"
-       echo "LIBDIR             = $LIBDIR"
-       echo "SOURCE_URL         = $SOURCE_URL"
+       echo "Configuration:"
+       echo "=============="
+       echo
+       echo "BTRDIR         = $BTRDIR"
+       echo "BINDIR         = $BINDIR"
+       echo "LIBDIR         = $LIBDIR"
+       echo
        echo "SOURCE_RULES   = $SOURCE_RULES"
-       echo "BUILD_RULES       = $BUILD_RULES"
+       echo "SOURCE_ARGS    = $SOURCE_ARGS"
+       echo "SOURCE_CLEAN   = $SOURCE_CLEAN"
+       echo "BUILD_RULES    = $BUILD_RULES"
+       echo "BUILD_ARGS     = $BUILD_ARGS"
+       echo "BUILD_CLEAN    = $BUILD_CLEAN"
+       echo "TEST_ARGS      = $TEST_ARGS"
        echo "REPORT_RULES   = $REPORT_RULES"
-       echo "BRANCH             = $BRANCH"
-       echo "SAFE_BRANCH       = $SAFE_BRANCH"
-       echo "CLEAN_DIR   = $CLEAN_DIR"
-       echo "BRANCH_DIR         = $BRANCH_DIR"
-       echo "BUILD_DIR   = $BUILD_DIR"
+       echo "REPORT_ARGS    = $REPORT_ARGS"
+       echo
+       echo "REPO           = $REPO"
+       echo "BRANCH         = $BRANCH"
+       echo "SAFE_BRANCH    = $SAFE_BRANCH"
+       echo
+       echo "CLEAN_DIR      = $CLEAN_DIR"
+       echo "BRANCH_DIR     = $BRANCH_DIR"
+       echo "BUILD_DIR      = $BUILD_DIR"
        echo "CONFIG_REPORT  = $CONFIG_REPORT"
        echo "BUILD_REPORT   = $BUILD_REPORT"
-       echo "TEST_REPORT       = $TEST_REPORT"
-       echo "LAST_REPORT       = $LAST_REPORT"
+       echo "TEST_REPORT    = $TEST_REPORT"
+       echo "LAST_REPORT    = $LAST_REPORT"
        echo
 }
 
diff --git a/lib/btr/build/composer.mk b/lib/btr/build/composer.mk
new file mode 100644 (file)
index 0000000..f08e8e2
--- /dev/null
@@ -0,0 +1,66 @@
+BUILD_CLEAN=false
+BUILD_ARGS= install --dev
+TEST_ARGS= --strict --coverage-text
+
+.PHONY: all clean
+.SUFFIXES:
+
+all: clean $(REPORT)
+       $(SAY) "Result: $$(cat $(REPORT))"
+
+clean: $(CONFIG_REPORT)
+       if $(BUILD_CLEAN); \
+       then \
+               cd $(BUILD_DIR) && \
+                       rm -rf vendor; \
+       fi;
+
+$(REPORT): $(TEST_REPORT)
+       @( \
+               TESTS_PASSED=$$(grep -Pc '^ok \d+' < $(TEST_REPORT)); \
+               TESTS_FAILED=$$(grep -Pc '^not ok \d+' < $(TEST_REPORT)); \
+               \
+               printf "%d/%d" $$TESTS_PASSED $$TESTS_FAILED >$@; \
+               if test -s "$(LAST_REPORT)"; then \
+                       LAST_PASSED=$$(grep -Pc '^ok \d+' < $(LAST_REPORT)); \
+                       LAST_FAILED=$$(grep -Pc '^not ok \d+' < $(LAST_REPORT)); \
+                       DIFF_PASSED=$$(bc <<<"$$TESTS_PASSED - $$LAST_PASSED"); \
+                       DIFF_FAILED=$$(bc <<<"$$TESTS_FAILED - $$LAST_FAILED"); \
+                       printf " %+d/%+d" $$DIFF_PASSED $$DIFF_FAILED >>$@; \
+               fi; \
+               printf "\n" >>$@; \
+       )
+
+$(TEST_REPORT): $(BUILD_REPORT)
+       $(SAY) "Running unit tests..."
+       cd $(BUILD_DIR) && \
+               phpunit --tap $(TEST_ARGS) . >../$@
+
+$(BUILD_REPORT): $(CONFIG_REPORT) $(BUILD_DIR)/composer.lock
+       $(SAY) "Installing dependencies..."
+       cd $(BUILD_DIR) && \
+               ./composer.phar -n --no-ansi $(QUIET_FLAG) $(VERBOSE_FLAG) $(BUILD_ARGS) \
+                       >../$@
+
+$(CONFIG_REPORT): $(BUILD_DIR)/composer.json $(BUILD_DIR)/composer.phar 
+       touch $(CONFIG_REPORT)
+
+$(BUILD_DIR)/composer.phar:
+       $(SAY) "Orchestrating composer..."
+       @cd $(BUILD_DIR) && ( \
+               COMPOSER=$$(command -v composer); \
+               if test $$? -eq 0; \
+               then \
+                       ln -s $$COMPOSER composer.phar; \
+               else \
+                       curl $(SILENT_FLAG) -S http://getcomposer.org/installer | php; \
+               fi; \
+       ) >>$(CONFIG_REPORT)
+
+$(BUILD_DIR)/composer.json: $(BRANCH_DIR)/composer.json
+       rsync $(QUIET_FLAG) $(VERBOSE_FLAG) -a --delete $(BRANCH_DIR)/ $(BUILD_DIR)/ \
+               >> $(CONFIG_REPORT)
+
+$(BUILD_DIR)/composer.lock: $(BUILD_DIR)/composer.json $(BUILD_DIR)/composer.phar
+
+# vim: noet
index bd37c2c..8dc05e3 100644 (file)
@@ -1,34 +1,52 @@
-.PHONY: all
+BUILD_CLEAN=false
+BUILD_ARGS=
+TEST_ARGS=
+
+.PHONY: all clean
 .SUFFIXES:
 
 CONFIGS=$(wildcard $(BRANCH_DIR)/configure.*)
 
-all: $(TEST_REPORT)
+all: clean $(REPORT)
+       $(SAY) "Result: $$(cat $(REPORT))"
+
+clean: $(CONFIG_REPORT)
+       if $(BUILD_CLEAN); \
+       then \
+               cd $(BUILD_DIR) && \
+                       make $(SILENT_FLAG) clean; \
+       fi;
+
+$(REPORT): $(TEST_REPORT)
        if test -z "$(LAST_REPORT)"; then \
                echo 0; \
        elif test -s "$(LAST_REPORT)" -o -s "$(TEST_REPORT)"; then \
-               cmp $(LAST_REPORT) $(TEST_REPORT); 2>&1 || true \
+               cmp $(LAST_REPORT) $(TEST_REPORT) 2>&1 || true; \
        else \
                echo 0; \
        fi;
 
 $(TEST_REPORT): $(BUILD_REPORT)
+       $(SAY) "Running checks..."
        cd $(BUILD_DIR) && \
-       make check $(CHECKS) > ../$@
+               make check $(TEST_ARGS) >../$@ 2>&1
 
 $(BUILD_REPORT): $(CONFIG_REPORT)
+       $(SAY) "Making build..."
        cd $(BUILD_DIR) && \
-       make -j $(CPUS) > ../$@
+               make -j $(CPUS) >../$@ 2>&1
        
 $(CONFIG_REPORT): $(BRANCH_DIR)/configure $(BUILD_DIR)
+       $(SAY) "Running configure..."
        cd $(BUILD_DIR) && \
-       ../$(BRANCH_DIR)/configure -C $(CONFIGURE) > ../$@
+               ../$(BRANCH_DIR)/configure -C $(BUILD_ARGS) >../$@ 2>&1
 
 $(BUILD_DIR):
        mkdir -p $@
        
 $(BRANCH_DIR)/configure: $(CONFIGS)
+       $(SAY) "Building configure..."
        cd $(BRANCH_DIR) && \
-       autoreconf -i -f -W none >/dev/null
+               autoreconf -i -f -W none >/dev/null
 
 # vim: noet
index 0eaa17b..c27b23a 100644 (file)
@@ -1,38 +1,58 @@
-.PHONY: all
+BUILD_CLEAN=false
+BUILD_ARGS=
+TEST_ARGS= -q
+
+.PHONY: all clean
 .SUFFIXES:
 
 CONFIGS=$(wildcard $(BRANCH_DIR)/config*.m4 $(BRANCH_DIR)/*/config*.m4)
 
-all: $(TEST_REPORT)
-       TESTS_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(TEST_REPORT)); \
-       TESTS_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(TEST_REPORT)); \
-       if test -z "$(LAST_REPORT)"; then \
-               printf "%d/%d\n" $$TESTS_PASSED $$TESTS_FAILED; \
-       else \
-               LAST_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(LAST_REPORT)); \
-               LAST_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(LAST_REPORT)); \
-               DIFF_PASSED=$$(bc <<<"$$TESTS_PASSED - $$LAST_PASSED"); \
-               DIFF_FAILED=$$(bc <<<"$$TESTS_FAILED - $$LAST_FAILED"); \
-               printf "+%d/+%d\n" $$DIFF_PASSED $$DIFF_FAILED; \
+all: clean $(REPORT)
+       $(SAY) "Result: $$(cat $(REPORT))"
+
+clean: $(CONFIG_REPORT)
+       if $(BUILD_CLEAN); \
+       then \
+               cd $(BUILD_DIR) && \
+                       make $(SILENT_FLAG) clean; \
        fi;
 
+$(REPORT): $(TEST_REPORT)
+       @(\
+               TESTS_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(TEST_REPORT)); \
+               TESTS_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(TEST_REPORT)); \
+               printf "%d/%d" $$TESTS_PASSED $$TESTS_FAILED >$@; \
+               if test -s "$(LAST_REPORT)"; then \
+                       LAST_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(LAST_REPORT)); \
+                       LAST_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(LAST_REPORT)); \
+                       DIFF_PASSED=$$(bc <<<"$$TESTS_PASSED - $$LAST_PASSED"); \
+                       DIFF_FAILED=$$(bc <<<"$$TESTS_FAILED - $$LAST_FAILED"); \
+                       printf " %+d/%+d" $$DIFF_PASSED $$DIFF_FAILED >>$@; \
+               fi; \
+               printf "\n" >>$@; \
+       )
+
 $(TEST_REPORT): $(BUILD_REPORT)
+       $(SAY) "Running tests... "
        cd $(BUILD_DIR) && \
-       make test TESTS=../$(BRANCH_DIR)/$(TESTS) > ../$@
+               make test TESTS="$(TEST_ARGS) -s ../$@" >/dev/null
 
 $(BUILD_REPORT): $(CONFIG_REPORT)
+       $(SAY) "Making build..."
        cd $(BUILD_DIR) && \
-       make -j $(CPUS) > ../$@
+               make -j $(CPUS) >../$@ 2>&1
        
 $(CONFIG_REPORT): $(BRANCH_DIR)/configure $(BUILD_DIR)
+       $(SAY) "Running 'configure'..."
        cd $(BUILD_DIR) && \
-       ../$(BRANCH_DIR)/configure -C $(CONFIGURE) > ../$@
+               ../$(BRANCH_DIR)/configure -C $(BUILD_ARGS) >../$@ 2>&1
 
 $(BUILD_DIR):
        mkdir -p $@
        
 $(BRANCH_DIR)/configure: $(CONFIGS)
+       $(SAY) "Running phpize..."
        cd $(BRANCH_DIR) && \
-       phpize > /dev/null
+               phpize >/dev/null
 
 # vim: noet
index 28ae1f7..35a7c71 100644 (file)
@@ -1,38 +1,58 @@
-.PHONY: all
+BUILD_CLEAN=false
+BUILD_ARGS= --enable-debug
+TEST_ARGS= -q
+
+.PHONY: all clean
 .SUFFIXES:
 
 CONFIGS=$(wildcard $(BRANCH_DIR)/ext/*/config*.m4)
 
-all: $(TEST_REPORT)
-       TESTS_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(TEST_REPORT)); \
-       TESTS_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(TEST_REPORT)); \
-       if test -z "$(LAST_REPORT)"; then \
-               printf "%d/%d\n" $$TESTS_PASSED $$TESTS_FAILED; \
-       else \
-               LAST_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(LAST_REPORT)); \
-               LAST_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(LAST_REPORT)); \
-               DIFF_PASSED=$$(bc <<<"$$TESTS_PASSED - $$LAST_PASSED"); \
-               DIFF_FAILED=$$(bc <<<"$$TESTS_FAILED - $$LAST_FAILED"); \
-               printf "+%d/+%d\n" $$DIFF_PASSED $$DIFF_FAILED; \
+all: clean $(REPORT)
+       $(SAY) "Result: $$(cat $(REPORT))"
+
+clean: $(CONFIG_REPORT)
+       if $(BUILD_CLEAN); \
+       then \
+               cd $(BUILD_DIR) && \
+                       make $(SILENT_FLAG) clean; \
        fi;
 
+$(REPORT): $(TEST_REPORT)
+       @(\
+               TESTS_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(TEST_REPORT)); \
+               TESTS_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(TEST_REPORT)); \
+               printf "%d/%d" $$TESTS_PASSED $$TESTS_FAILED >$@; \
+               if test -s "$(LAST_REPORT)"; then \
+                       LAST_PASSED=$$(awk '/^Tests passed/{print $$4}' < $(LAST_REPORT)); \
+                       LAST_FAILED=$$(awk '/^Tests failed/{print $$4}' < $(LAST_REPORT)); \
+                       DIFF_PASSED=$$(bc <<<"$$TESTS_PASSED - $$LAST_PASSED"); \
+                       DIFF_FAILED=$$(bc <<<"$$TESTS_FAILED - $$LAST_FAILED"); \
+                       printf " %+d/%+d" $$DIFF_PASSED $$DIFF_FAILED >>$@; \
+               fi; \
+               printf "\n" >>$@; \
+       )
+
 $(TEST_REPORT): $(BUILD_REPORT)
+       $(SAY) "Running tests... "
        cd $(BUILD_DIR) && \
-       make test TESTS=../$(BRANCH_DIR)/$(TESTS) > ../$@
+               make test TESTS="$(TEST_ARGS) -s ../$@"
 
 $(BUILD_REPORT): $(CONFIG_REPORT)
+       $(SAY) "Making build..."
        cd $(BUILD_DIR) && \
-       make -j $(CPUS) > ../$@
+               make -j $(CPUS) >../$@ 2>&1
        
 $(CONFIG_REPORT): $(BRANCH_DIR)/configure $(BUILD_DIR)
+       $(SAY) "Running 'configure'..."
        cd $(BUILD_DIR) && \
-       ../$(BRANCH_DIR)/configure -C $(CONFIGURE) > ../$@
+               ../$(BRANCH_DIR)/configure -C $(BUILD_ARGS) >../$@ 2>&1
 
 $(BUILD_DIR):
        mkdir -p $@
        
 $(BRANCH_DIR)/configure: $(BRANCH_DIR)/buildconf $(CONFIGS)
+       $(SAY) "Building configure..."
        cd $(BRANCH_DIR) && \
-       ./buildconf > /dev/null
+               ./buildconf >/dev/null
 
 # vim: noet
diff --git a/lib/btr/irc.php b/lib/btr/irc.php
new file mode 100755 (executable)
index 0000000..8af2209
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+function fatal() {
+       if (func_num_args()) {
+               $args = func_get_args();
+       } elseif (($error = error_get_last())) {
+               $args = ["%s", $error["message"]];
+       }
+       
+       if (!empty($args)) {
+               if (count($args) === 1 && is_numeric($args[0])) {
+                       array_unshift($args, "Got signal %d");
+               }
+               trigger_error(call_user_func_array("sprintf", $args), E_USER_ERROR);
+       }
+       
+       exit;
+}
+
+function mkfifo($path) {
+       if (!isfifo($path, $stat)) {
+               $stat and unlink($path);
+               if (!posix_mkfifo($path, 0660)) {
+                       return false;
+               }
+       }
+       return fopen($path, "r+");
+}
+
+function isfifo($path, &$stat = null) {
+       return ($stat = @stat($path)) && ($stat["mode"] & POSIX_S_IFIFO);
+}
+
+class Client
+{
+       protected $session;
+       protected $channel;
+       protected $keyword;
+       protected $joined;
+       protected $queue = array();
+       
+       function __construct($url, callable $onJoin) {
+               if (!$url = parse_url($url)) {
+                       fatal("could not parse url: '%s'", $url);
+               }
+               
+               $this->session = $session = new irc\client\Session(
+                       $url["user"],
+                       $url["user"],
+                       $url["user"]
+               );
+               
+               @list($this->channel, $this->keyword) = 
+                       explode(" ", $url["fragment"]);
+               
+               $session->onConnect = $session->onPart = function($origin, array $args) {
+                       $this->joined = false;
+                       $this->session->doJoin("#".$this->channel, $this->keyword);
+               };
+               $session->onJoin = function($origin, array $args) use ($onJoin) {
+                       $this->joined = true;
+                       $onJoin($this, $origin, $args);
+               };
+               $session->doConnect(false, $url["host"], @$url["port"]?:6667, @$url["pass"]);
+       }
+       
+       function send($message = null) {
+               if (isset($message)) {
+                       $this->queue[] = $message;
+               }
+               
+               if ($this->joined) {
+                       while ($this->queue) {
+                               $this->session->doMsg("#".$this->channel, array_shift($this->queue));
+                       }
+               }
+       }
+       
+       function getSession() {
+               return $this->session;
+       }
+}
+
+if (!extension_loaded("ircclient")) {
+       fatal("ext/ircclient not loaded");
+}
+
+# vim: noet
diff --git a/lib/btr/report/irc.mk b/lib/btr/report/irc.mk
new file mode 100644 (file)
index 0000000..7360fa6
--- /dev/null
@@ -0,0 +1,12 @@
+.PHONY: all
+.SUFFIXES:
+
+all: 
+       $(SAY) "Notifying IRC ($(REPORT_ARGS))"
+       CONFIG_URL=$$(curl -sSF sprunge="@$(CONFIG_REPORT)" sprunge.us); \
+       BUILD_URL=$$(curl -sSF sprunge="@$(BUILD_REPORT)" sprunge.us); \
+       TEST_URL=$$(curl -sSF sprunge="@$(TEST_REPORT)" sprunge.us); \
+       $(BINDIR)/btr-irc-send "$(REPORT_ARGS)" "[btr] $(BUILD) $$(cat $(REPORT)) \
+               -- Config: $$CONFIG_URL -- Build: $$BUILD_URL -- Test: $$TEST_URL";
+
+# vim: noet
index 0cc9fbd..d16a646 100644 (file)
@@ -1,10 +1,15 @@
+REPORT_ARGS=$(USER)
+
 .PHONY: all
 .SUFFIXES:
 
 all: 
-       MESSAGE=$$(printf "\nbtr %s %s\n\n-- \nbtr mail report\n" "$(BUILD)" "$(REPORT)"); \
-       mail -s "[btr] $(BUILD) $(REPORT)" \
-               -a $(CONFIG_REPORT) -a $(BUILD_REPORT) -a $(TEST_REPORT) \
-               $(USER) <<<"$$MESSAGE"
+       $(SAY) "Mailing report to $(REPORT_ARGS)"
+       @printf "\nbtr %s %s\n\n-- \nbtr mail report\n" "$(BUILD)" "$$(cat $(REPORT))" | \
+               mail -s "[btr] $(BUILD) $$(cat $(REPORT))" \
+                       -a $(CONFIG_REPORT) \
+                       -a $(BUILD_REPORT) \
+                       -a $(TEST_REPORT) \
+                       $(REPORT_ARGS)
 
 # vim: noet
index f4c5197..cfc20cc 100644 (file)
@@ -2,6 +2,11 @@
 .SUFFIXES:
 
 all: 
-       notify-send "[btr] $(BUILD) $(REPORT)"
+       $(SAY) "Notifying $(USER) about the report"
+       CONFIG_URL=$$(curl -sSF sprunge="@$(CONFIG_REPORT)" sprunge.us); \
+       BUILD_URL=$$(curl -sSF sprunge="@$(BUILD_REPORT)" sprunge.us); \
+       TEST_URL=$$(curl -sSF sprunge="@$(TEST_REPORT)" sprunge.us); \
+       notify-send $(REPORT_ARGS) "[btr] $(BUILD) $$(cat $(REPORT))" \
+               "Config: $$CONFIG_URL -- Build: $$BUILD_URL -- Test:$$TEST_URL";
 
 # vim: noet
index e420833..54ac53a 100644 (file)
@@ -5,7 +5,7 @@ all:
        curl "https://api.twilio.com/2010-04-01/Accounts/$(TWILIO_ACCOUNT)/SMS/Messages.json" \
        --data-urlencode "From=$(TWILIO_NUMBER)" \
        --data-urlencode "To=$(REPORT_NUMBER)" \
-       --data-urlencode "Body=[btr] $(BUILD) $(REPORT)" \
+       --data-urlencode "Body=[btr] $(BUILD) $$(cat $(REPORT))" \
        -u $(TWILIO_ACCOUNT):$(TWILIO_TOKEN)
 
 # vim: noet
diff --git a/lib/btr/source/cvs.mk b/lib/btr/source/cvs.mk
new file mode 100644 (file)
index 0000000..839efa2
--- /dev/null
@@ -0,0 +1,31 @@
+SOURCE_CLEAN=false
+CVSROOT=$(shell cut -d'\#' -f1 <<<$(SOURCE_ARGS))
+CVS_MOD=$(shell cut -d'\#' -f2 -s <<<$(SOURCE_ARGS))
+CVS_RSH=ssh
+
+export
+
+ifeq ($(value QUIET_FLAG), -q)
+override QUIET_FLAG = -Q
+endif
+
+.PHONY: all clean login
+.SUFFIXES:
+
+all: $(BRANCH_DIR) clean
+       $(SAY) "Updating $(BRANCH)..."
+       cd $(BRANCH_DIR) && \
+               cvs $(QUIET_FLAG) -z3 update -RPd;
+
+clean: $(BRANCH_DIR)
+       if $(SOURCE_CLEAN); \
+       then \
+               cd $(BRANCH_DIR) && \
+                       cvs $(QUIET_FLAG) -z3 update -CRPd; \
+       fi;
+
+$(BRANCH_DIR):
+       $(SAY) "Performing checkout of $(CVS_MOD) from $(CVSROOT)..."
+       cvs $(QUIET_FLAG) checkout -RP -r $(BRANCH) -d $(BRANCH_DIR) $(CVS_MOD)
+
+# vim: noet
index 4e80904..3808590 100644 (file)
@@ -1,18 +1,31 @@
-.PHONY: pull all
+SOURCE_CLEAN=false
+
+.PHONY: fetch all clean
 .SUFFIXES:
 
-all: $(BRANCH_DIR) pull
+all: $(BRANCH_DIR) clean fetch
+       $(SAY) "Merging $(BRANCH) of $(REPO)..."
        cd $(BRANCH_DIR) && \
-       git pull -q
+               git merge $(QUIET_FLAG) --ff-only;
+
+clean: $(BRANCH_DIR)
+       if $(SOURCE_CLEAN); \
+       then \
+               cd $(BRANCH_DIR) && \
+                       git reset --hard $(QUIET_FLAGS); \
+       fi;
 
-pull: $(CLEAN_DIR)
+fetch: $(CLEAN_DIR)
+       $(SAY) "Fetching $(REPO)..."
        cd $(CLEAN_DIR) && \
-       git pull -q
+               git fetch $(QUIET_FLAG);
 
 $(CLEAN_DIR):
-       git clone -q $(SOURCE_URL) $(CLEAN_DIR)
+       $(SAY) "Cloning from $(SOURCE_ARGS)..."
+       git clone $(QUIET_FLAG) $(SOURCE_ARGS) $(CLEAN_DIR);
 
 $(BRANCH_DIR): $(CLEAN_DIR)
+       $(SAY) "Creating workdir for $(BRANCH)"
        git-new-workdir $(CLEAN_DIR) $(BRANCH_DIR) $(BRANCH)
 
 # vim: noet
index 5e36e08..b18782e 100644 (file)
@@ -1,11 +1,22 @@
-.PHONY: all
+SOURCE_CLEAN=false
+
+.PHONY: all clean
 .SUFFIXES:
 
-all: $(BRANCH_DIR)
+all: $(BRANCH_DIR) clean
+       $(SAY) "Updating $(BRANCH)..."
        cd $(BRANCH_DIR) && \
-       svn update -q
+               svn update $(QUIET_FLAG);
+
+clean: $(BRANCH_DIR)
+       if $(SOURCE_CLEAN); \
+       then \
+               cd $(BRANCH_DIR) && \
+                       svn revert $(QUIET_FLAG); \
+       fi;
 
 $(BRANCH_DIR):
-       svn checkout $(SOURCE_URL)/$(BRANCH) $(BRANCH_DIR)
+       $(SAY) "Performing checkout from $(SOURCE_ARGS)..."
+       svn checkout $(QUIET_FLAG) $(SOURCE_ARGS)/$(BRANCH) $(BRANCH_DIR)
 
 # vim: noet
diff --git a/php.example.conf b/php.example.conf
new file mode 100644 (file)
index 0000000..4a1bd10
--- /dev/null
@@ -0,0 +1,7 @@
+SOURCE_RULES=git
+SOURCE_ARGS=git@php.net:php/php-src.git
+BRANCH=PHP-5.5
+BUILD_RULES=php
+BUILD_ARGS=--enable-debug
+TEST_ARGS=-m
+REPORT_RULES=notify-send