#!/usr/bin/env bash # (c) Neels J. Hofmeyr # Published under the GNU GPL v3 or later. # # Hi, I am Patch-Man Pat! # I can help you writing patches for the Subversion project. # # To install, just put me in your $PATH (e.g. copy to /usr/local/bin or # ~/bin) and make me executable ('chmod a+x /usr/local/bin/pat'). # # Simply run # pat # to see the online help. # # Once-off, do # pat init # and follow further instructions as desired... # # Set dependencies' versions in the default OR per-workspace config file. # Just run `pat config' and you'll see. # # I hope it's useful :) # ~Neels # Subversion source repos base URL (e.g. "$svnrepos/trunk") svnrepos="https://svn.apache.org/repos/asf/subversion" # Pat website pat_website="http://len.stsp.name/pat-bot" maintainermode_opt="--enable-maintainer-mode" if [ -n "$NONMAINTAINER" ]; then maintainermode_opt="" fi function success_notify_cmd(){ #beep -f 600 -l 50 -d 0 -n -f 1200 -l 200 echo "SUCCESS!" if [ -n "$(which ding)" ]; then ding fi } function failure_notify_cmd(){ #beep -f 150 -l 30 -d 60 -r 4 echo "FAIL!" if [ -n "$(which dong)" ]; then dong fi } set -e +m base="$PAT_DIR" if [ -z "$base" ]; then base="$HOME/pat" fi # Just some names to use for files and folders. _pat_cruft=".pat-base" _deps="$_pat_cruft/deps" _pristine="$_pat_cruft/pristine" _tmp="$_pat_cruft/tmp" _defaultconfig="$_pat_cruft/config-default" _patches="patches" _tests="tests" _blueprint="blueprint.test" _src="src" _prefix="prefix" _buildlog="buildlog" _checklog="checklog" _stable="stable" _log="log" _diff="diff" _config="config" _ctags="tags" _pat_ws_cruft=".pat" _name="$_pat_ws_cruft/name" _url="$_pat_ws_cruft/url" _last_autolog="$_pat_ws_cruft/last_autolog" pat_conf_line="conf: " trunk_url="$svnrepos/trunk" pristine_url="$trunk_url" pristine_src="$base/$_pristine" deps="$base/$_deps" deps_build="$deps/build" deps_prefix="$deps/$_prefix" bot="$base/$_pat_cruft/bot" bot_active_dir="$bot/active" bot_done_dir="$bot/done" function find_svn(){ quiet="$1" svn_binary="$base/$_stable/prefix/bin/svn" if [ ! -x "$svn_binary" ]; then if [ -z "$quiet" ]; then error_msg "Warning: svn binary not found: $svn_binary" fi svn_binary="$(which svn || echo "" )" if [ -z "$quiet" ]; then if [ -z "$svn_binary" ]; then error_msg "ERROR: Please provide a (stable) 'svn' binary in your \$PATH." error_msg "OR follow this recipe to build one:" error_msg "- Run 'pat config' to see if a subversion *tarball* URL is configured." error_msg " Edit the config file if necessary (see output of 'pat config')." error_msg "- Run 'pat new $_stable' and answer 'yes'." error_msg "OR manually download:" error_msg "- Run 'pat new stable', answering 'no' if asked and ignoring errors." error_msg "- Download a Subversion source release tar from subversion.apache.org" error_msg "- Unpack into $base/$_stable/" error_msg "- Rename the resulting 'subversion-xxx' folder 'src'" error_msg "- Run 'pat remake $_stable'" error "Note that pat automatically uses the '$_stable' svn build, if present." fi error_msg " Instead using $svn_binary" fi fi echo "$svn_binary" } function svn(){ svn_binary="$(find_svn)" if [ -z "$svn_binary" ]; then exit 1 fi "$svn_binary" "$@" } function verbose_svn(){ svn_binary="$(find_svn)" echo "$svn_binary $@" "$svn_binary" "$@" } function ensure_svn(){ svn --version >/dev/null } function usage(){ cat >&2 <, published under GPL v3 (or later). Hi, I am Patch-Man Pat! I can help you writing patches for Subversion. First and once, run 'pat init'. It will create pat's base in ~/pat. Then, build a stable svn with 'pat new stable; pat make'. (Will use a source tarball if svn is not installed on your system.) Each folder in ~/pat is a separate workspace, create one with 'pat new '. The workspace ~/pat/$_stable is special: if present, pat uses its built 'svn' to checkout and work with (any versions of) subversion source trees. Core features: - helps downloading, installing and configuring (pat make, pat deps) - helps writing log messages (pat diff) - helps using one of several built svns to test (pat use) - opens all modified files in an editor (pat edit) - can delegate other boxes to do a clean make check (pat bot) - saves all your progress in a Mercurial (pat save, pat clone, pat backup) - can run a build-bot daemon that tests patches (e.g. on a remote box) (Why Mercurial? It does not break when you break your svn, and it is a simple way to do versioned backups, particularly in single-user mode. Only your patches and tests will be saved, not entire svn sources or builds.) To take advantage of full pat convenience (*), include this in your ~/.bashrc: eval "\$(pat bashrc)" | | V Usage: * Description | Aliases: pat init Once-off, create ~/pat eval "\$(pat bashrc)" Do this in your ~/.bashrc, needed for * pat new [|] | create pat conf [] show current config pat deps build all deps | dependencies, make deps pat remake [] fully rebuild svn | rebuild, re pat make [] run 'make' | build, m, b pat use [] * set \$PATH to this svn | env, prefix, pow, power pat check [] run 'make check' | make check pat ctags [] run ctags on src/ | tags, tag pat edit [] edit modified files | e, ed, vi, vim pat diff [] edit the log message | view pat commit [] verify+COMMIT to svn | ci pat save [all|] commit pat state to pat's local Mercurial pat cd * cd to workspace root (~/pat/) pat cdp * cd to /patches/ pat cdt * cd to /tests/ pat cds * cd to /src/ pat cdtc * cd to src/subversion/tests/cmdline/ | cdc, cdct pat one of status, update, info, revert pat grep grep in src/, skip all ".svn" folders. pat delete saves and removes workspace. | del, remove, rm pat bot [] 'pat save' and send patch to a bot matching bot-name as configured, see 'pat conf' pat clone create a remote mercurial clone via ssh pat backup [all|] push to clone, no args defaults to all s You can also use 'hg' directly. In a cloned pat, there are no sources yet. Do: pat recheckout [|] | checkout, co pat apply [] | patch, ap pat bot-daemon Run a bot daemon on this box. corresponds to a folder name in ~/pat/ - You may omit when you are inside a pat workspace. Pat will find the workspace root automatically. - may be partial (like bash completion without hitting TAB). e.g. you can type 'pat cd tr' to go to 'trunk', if it's a unique match. EOF exit 1 } function error_msg(){ echo "pat: $@" >&2 } function error(){ error_msg "$@" exit 1 } function create_test_blueprint(){ path="$1" name="$2" if [ ! -e "$path" ]; then cat > "$path" < "\$REPOS/hooks/pre-revprop-change" < "$pat/$_name" } function pat_get_name(){ pat="$1" name="$(cat "$pat/$_name" 2>/dev/null || true)" if [ -z "$name" ]; then basename "$pat" else echo "$name" fi } function pat_store_url(){ pat="$1" url="$2" echo "$url" > "$pat/$_url" } function pat_get_url(){ pat="$1" url="$(cat "$pat/$_url" 2>/dev/null || true)" if [ -z "$url" ]; then echo "$pristine_url" else echo "$url" fi } function vc_configure(){ path="$1" if [ -n "$(which hg)" ]; then hgignore="$path/.hgignore" if [ ! -e "$hgignore" ]; then cat > "$hgignore" < "$path/.hg/hgrc" << EOF [paths] default = $url EOF fi fi } function vc_clone_config_path(){ echo "$1/.hg/hgrc" } function vc_add(){ path="$1" if [ -n "$(which hg)" ]; then echo "hg add $(nice_path "$1")" hg add "$1" fi } function vc_remove(){ path="$1" if [ -n "$(which hg)" ]; then echo "hg remove $1" hg remove "$1" fi } function vc_commit(){ path="$1" if [ -n "$(which hg)" ]; then if [ -z "$(hg status "$path")" ]; then echo "Nothing changed in $(nice_path "$path")" else if [ -z "$2" ]; then msg="pat autocommit" else msg="pat: $2" fi set +e echo "hg ci -m '$msg' $(nice_path "$path")" hg ci -m "$msg" "$path" ret="$?" set -e if [ "$ret" != "0" -a "$ret" != "255" ]; then exit 1 fi if [ "$ret" != "255" ]; then echo "Saved patches, tests and config of $(nice_path "$path")" fi fi fi } function vc_push(){ if [ -n "$(which hg)" ]; then echo "----- hg push \"$1\"" hg push --cwd "$1" echo fi } function get_timestamp(){ date "+%Y%m%d-%H%M%S" } function readable_timestamp(){ date "+%Y-%m-%d %H:%M:%S" } function vc_ensure_dir_available(){ path="$1" if [ -z "$(echo "$path" | grep "$vc_base" || true)" ]; then error "will not change anything outside of vc_base: $path" fi if [ -f "$path" ]; then stamp="$(get_timestamp)" hg mv "$path" "$path.$stamp" 2>/dev/null || { mv "$path" "$path.$stamp" }; fi } function copy_latest_pristine(){ copy_to_dir="$1" if [ -d "$pristine_src" ]; then svn info "$pristine_src" | grep "URL" || true if [ -n "$(svn st "$pristine_src")" ]; then error "pristine has modifications: $pristine_src" fi fi if [ ! -d "$pristine_src" ]; then echo "Checking out new pristine source" svn co -q "$svnrepos/trunk" "$pristine_src" else echo "Updating pristine source" echo "(if there's an error, just 'rm -rf $pristine_src')" svn up "$pristine_src" fi echo "Copying" cp -pPR "$pristine_src" "$copy_to_dir" } function cmd_init(){ if [ -n "$1" ]; then error "Sorry, not implemented: can only create pat-base in $base" fi new_base="$base" if [ ! -e "$new_base" ]; then mkdir -p "$new_base" vc_init "$new_base" write_default_config "$base/$_defaultconfig" echo echo "Created $new_base" else echo "Already exists: $new_base" vc_configure "$new_base" fi echo echo "NEXT STEPS (optional)" echo echo "- Create a custom built svn for pat to use to get svn sources:" echo " run 'pat new $_stable branches/1.6.x' and 'pat remake $_stable'" echo echo "- Run 'pat clone hostname' to create a backup location on a remote host." echo " This is done by a mercurial repository, via ssh." echo " All of sources, builds, deps and test runs are kept out of this." echo " The backup will include your patches, test scripts, log messages" echo " and any files created outside of src/, prefix/, deps/." echo " (I use Mercurial because it doesn't depend on Subversion and is" echo " handy for spreading versioned backups in single-user mode.)" echo } function cmd_clone(){ host="$1" if [ -z "$host" ]; then error_msg "Need a hostname." error_msg "E.g. configure hostname 'pat' in .ssh/config and call" error "pat clone pat" fi url="ssh://$host/pat" vc_clone "$base" "$url" echo echo "Created clone at $url" echo echo "You can now run" echo " pat backup" echo "at any time, which would 'pat save' your current patches and tests" echo "and push all outstanding changes to the default clone configured in" echo -n " "; vc_clone_config_path "$base" } function pat_add_and_commit(){ pat="$1" msg="$2" vc_configure "$base" vc_add "$pat" vc_commit "$pat" "$msg" } function cmd_backup(){ if [ -z "$1" -o "$1" = "all" ]; then cmd_save_all else pat="$(find_pat strict "$1")" pat_save "$pat" fi vc_push "$base" } function pat_re_checkout(){ pat="$1" url="$2" src="$pat/$_src" if [ -d "$src" ]; then if [ -n "$(echo "$(pwd)" | grep "^$src" || true)" ]; then echo "*** YOU ARE INSIDE A FOLDER I AM REMOVING. ***" cd "$pat" fi rm -rf "$src" fi copy_latest_pristine "$src" # if necessary, switch src to url if [ -n "$url" ]; then if [ -z "$(echo "$url" | grep "^\(\^/\|[a-z+]*:\)" || true)" ]; then url="$svnrepos/$url" fi echo "Switching to $url" verbose_svn switch "$url" "$src" else url="$pristine_url" fi echo "Checked out $url" pat_store_url "$pat" "$url" } function cmd_re_checkout(){ pat="$(find_pat strict "")" url="$1" echo "Saving state: $(nice_path "$pat")" pat_do_diff_and_make_patch "$pat" if [ -z "$url" ]; then url="$(pat_get_url "$pat")" fi pat_re_checkout "$pat" "$url" } function cmd_new(){ name="$1" url="$2" if [ -z "$name" ]; then usage fi pat="$base/$name" if [ -e "$pat" ]; then echo "Already exists: $(nice_path "$pat")" echo "To remove it, enter 'ok', 'yes' or 'y' and hit enter." echo "(This remove keeps the prefix usable until next full build)" read answer if [ "$answer" != "y" -a "$answer" != "yes" -a "$answer" != "ok" ]; then error "aborted." fi echo "Saving state: $(nice_path "$pat")" $0 save "$name" || true # we are going to remove $pat. If we are inside it, leave it first # to avoid errors like "shell-init: error retrieving current directory: # getcwd: cannot access parent directories: No such file or directory". if [ -n "$(echo "$(pwd)" | grep "^$pat" || true)" ]; then echo "*** YOU ARE INSIDE A FOLDER I AM REMOVING. ***" cd "$base" fi if [ -d "$pat/$_prefix" ]; then # Do a little trick to keep the prefix present until the last moment # (removed upon install). trash="$base/.trash-$name" if [ -e "$trash" ]; then error "Damn. Already exists: $trash" fi mv "$pat" "$trash" mkdir "$pat" mv "$trash/$_prefix" "$pat/" touch "$pat/$_prefix/THIS_BUILD_IS_STALE_BUT_LEFT_UNTIL_NEXT_FULL_BUILD" rm -rf "$trash" else # no prefix to be saved. rm -rf "$pat" fi fi pat_new "$pat" "$name" "$url" } function pat_new(){ pat="$1" name="$2" url="$3" if [ -z "$name" ]; then name="$(basename "$pat")" fi echo "Creating new workspace in $pat" mkdir -p "$pat/$_pat_ws_cruft" pat_store_name "$pat" "$name" pat_store_url "$pat" "$url" mkdir -p "$pat/$_patches" mkdir -p "$pat/$_tests" create_test_blueprint "$pat/$_tests/$_blueprint" "$name" # Offer a backdoor to build the stable svn from a tarball do_checkout=1 if [ "$name" = "stable" ]; then if [ -z "$(find_svn quiet)" ]; then do_checkout=0 pat_find_config conf_get_dep subversion if [ -n "$subversion_version" ]; then echo echo "You do not seem to have a subversion binary, so we cannot run 'svn checkout'." echo "However, you do have a subversion-$subversion_version tarball location configured:" echo "$subversion_config" echo echo "If you want to use this source tarball (and possibly download it)" echo "hit enter now. Otherwise hit Ctrl-C and get an 'svn' in your \$PATH." read conf_ensure_tarball "subversion" conf_unpack subversion mv "$subversion_build_dir" "$pat/$_src" echo echo "----- Extracted subversion from source tarball into 'stable'" echo echo "You can now call 'pat make stable' to build a stable svn." echo "('pat new ' uses this svn to checkout working copies.)" echo echo "When that is done, you can run 'pat new stable branches/1.6.x'" echo "to replace the subversion sources that came from the tarball with" echo "an actual svn working copy that you can keep up-to-date with 'pat up'." echo fi fi fi if [ "$do_checkout" = "1" ]; then # update or create the pristine checkout, copy to src pat_re_checkout "$pat" "$url" fi } function find_pat(){ strict="$1" arg="$2" pat="" if [ -z "$arg" ]; then # look for .pat folder now="$(pwd)" while [ "$now" != "/" ]; do if [ -d "$now/.pat" ]; then pat="$now" break fi now="$(dirname "$now")" done if [ -z "$pat" ]; then if [ "$strict" != "lax" ]; then error "This is not a pat workspace." fi elif [ "$(dirname "$pat")" != "$base" ]; then error "Expected to be in pat base $base -- not $(dirname "$pat")" fi else # if $arg is nonzero pat="$base/$arg" if [ ! -e "$pat" ]; then matches="$(ls -1d "$pat"*)" pat="$pat*" if [ -n "$matches" ]; then if [ "$(echo "$matches" | wc -l)" -gt 1 ]; then error "Multiple matches for $pat: $matches" else pat="$matches" fi fi fi if [ ! -e "$pat" ]; then error "does not exist: $pat" elif [ ! -d "$pat/.pat" ]; then error "not managed by pat: $pat" fi fi echo -n "$pat" } function cmd_cd(){ # The real cd is handled by the bash-env's pat function (pat bash include) pat="$(find_pat lax "$1")" if [ -z "$pat" ]; then pat="$base" fi echo "$pat" } function cmd_cdp(){ # The real cd is handled by the bash-env's pat function (pat bash include) pat="$(find_pat strict "$1")" echo "$pat/$_patches" } function cmd_cdt(){ # The real cd is handled by the bash-env's pat function (pat bash include) pat="$(find_pat strict "$1")" echo "$pat/$_tests" } function cmd_cdtc(){ # The real cd is handled by the bash-env's pat function (pat bash include) pat="$(find_pat strict "$1")" echo "$pat/$_src/subversion/tests/cmdline" } function cmd_cds(){ # The real cd is handled by the bash-env's pat function (pat bash include) pat="$(find_pat strict "$1")" echo "$pat/$_src" } function conf_ensure_tarball(){ name="$(echo "$1" | sed "s/-/_/g")" version="$(eval "echo \$${name}_version")" tarball="$(eval "echo \$${name}_tarball")" build_dir="$(eval "echo \$${name}_build_dir")" if [ -n "$version" ]; then if [ ! -r "$tarball" ]; then # try to get the tarball local_mirror="$(eval "echo \$${name}_local_mirror")" if [ -n "$local_mirror" ]; then cp "$local_mirror" "$tarball" else url="$(eval "echo \$${name}_url")" if [ -n "$url" ]; then wget_temp="$(pat_tempdir "$pat")" was_wd="$(pwd)" cd "$wget_temp" echo echo "----- Downloading $url" wget "$url" cd "$was_wd" downloaded="$wget_temp/$(basename "$tarball")" if [ ! -r "$downloaded" ]; then error_msg "An error occured while downloading $url" error "Can't find $downloaded" fi mkdir -p "$(dirname "$tarball")" mv "$downloaded" "$tarball" echo "Downloaded to $tarball" echo rm -rf "$wget_temp" fi fi fi fi } function conf_unpack(){ echo "$1" target_dir="$2" name="$(echo "$1" | sed "s/-/_/g")" tarball="$(eval "echo \$${name}_tarball")" build_dir="$(eval "echo \$${name}_build_dir")" build_dir_parent="$(dirname "$build_dir")" mkdir -p "$build_dir_parent" if [ -d "$build_dir" ]; then tempdir="$(mktemp -d -p "$build_dir_parent")" echo "Already exists: $build_dir" echo "Moving it out of the way to $tempdir" mv "$build_dir" "$tempdir" fi if [ -n "$(echo "$tarball" | grep "\.gz" || true)" ]; then flags="-xzf" elif [ -n "$(echo "$tarball" | grep "\.bz2" || true)" ]; then flags="-xjf" else error "Don't know archive format: $(nice_path "$tarball")" fi tempdir="$(mktemp -d -p "$build_dir_parent")" tar -C "$tempdir" "$flags" "$tarball" extracted_dir="$tempdir/$(ls $tempdir/)" if [ ! -d "$extracted_dir" ]; then error_msg "Inconsistency: Tarball $(nice_path "$tarball") extracted in unexpected way." error "Take a look inside $(nice_path "$tempdir")" fi mkdir -p "$(dirname "$target_dir")" mv "$extracted_dir" "$build_dir" rm -rf "$tempdir" if [ -n "$target_dir" ]; then mkdir -p "$(dirname "$target_dir")" mv "$build_dir" "$target_dir" fi } function cmd_deps(){ pat="$(find_pat lax "$1")" pat_read_deps_config "$pat" do_make_deps } # Need to call pat_read_deps_config before calling this. function do_make_deps(){ mkdir -p "$deps_prefix" # missing tars? errors="" for one_dep in db libiconv apr apr-util neon serf sqlite httpd; do conf_ensure_tarball "$one_dep" || errors="$errors $one_dep" done if [ -n "$errors" ]; then error "Cannot get source tars for:$errors." fi # build existed="" built="" # db if [ -n "$db_version" ]; then if [ -d "$db_prefix" ]; then existed="$existed\n$db_prefix" else echo echo "---------------- Building db" conf_unpack db was_wd="$(pwd)" set -x cd "$db_build_dir/build_unix" env CFLAGS="-g" ../dist/configure \ --prefix="$db_prefix" \ --enable-debug make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$db_prefix" fi fi # libiconv if [ -n "$libiconv_version" ]; then if [ -d "$libiconv_prefix" ]; then existed="$existed\n$libiconv_prefix" else echo echo "---------------- Building libiconv" conf_unpack libiconv was_wd="$(pwd)" set -x cd "$libiconv_build_dir" make -f Makefile.devel lib/aliases.h env CFLAGS="-g" ./configure \ --prefix="$libiconv_prefix" \ --enable-extra-encodings make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$libiconv_prefix" fi fi # apr if [ -n "$apr_version" ]; then if [ -d "$apr_prefix" ]; then existed="$existed\n$apr_prefix" else echo echo "---------------- Building apr" conf_unpack apr was_wd="$(pwd)" set -x cd "$apr_build_dir" env CFLAGS="-O0 -g" \ ./configure \ --prefix="$apr_prefix" \ --enable-maintainer-mode make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$apr_prefix" fi fi # apr-util if [ -n "$apr_util_version" ]; then if [ -d "$apr_util_prefix" ]; then existed="$existed\n$apr_util_prefix" else if [ ! -d "$apr_prefix" ]; then error_msg "not found: $apr_prefix" error "also need a custom apr build." fi echo echo "---------------- Building apr-util" conf_unpack apr-util was_wd="$(pwd)" set -x cd "$apr_util_build_dir" ./buildconf --with-apr="$apr_build_dir" env LD_LIBRARY_PATH="$db_prefix/lib" \ CFLAGS="-O0 -g" \ ./configure \ --prefix="$apr_util_prefix" \ --enable-maintainer-mode \ --with-apr="$apr_prefix" \ --with-berkeley-db="$db_prefix" \ --with-iconv="$libiconv_prefix" #--with-berkeley-db="$bd_prefix" \ make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$apr_util_prefix" fi fi # neon if [ -n "$neon_version" ]; then if [ -d "$neon_prefix" ]; then existed="$existed\n$neon_prefix" else echo echo "---------------- Building neon" conf_unpack neon was_wd="$(pwd)" cd "$neon_build_dir" set -x env CFLAGS="-g" \ ./configure \ --prefix="$neon_prefix" \ --with-ssl \ --enable-shared make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$neon_prefix" fi fi # sqlite if [ -n "$sqlite_version" ]; then if [ -d "$sqlite_prefix" ]; then existed="$existed\n$sqlite_prefix" else echo echo "---------------- Building sqlite" conf_unpack sqlite was_wd="$(pwd)" set -x cd "$sqlite_build_dir" env CFLAGS="-g" \ ./configure \ --prefix="$sqlite_prefix" \ --disable-tcl make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$sqlite_prefix" fi fi # httpd if [ -n "$httpd_version" ]; then if [ -d "$httpd_prefix" ]; then existed="$existed\n$httpd_prefix" else echo echo "---------------- Building httpd" conf_unpack httpd was_wd="$(pwd)" set -x cd "$httpd_build_dir" # hack. httpd's --with-apr and --with-apr-util don't work properly. # Maybe they do when a system-wide apr is installed? rm -rf "$httpd_build_dir/srclib/apr" "$httpd_build_dir/srclib/apr-util" conf_unpack apr "$httpd_build_dir/srclib/apr" conf_unpack apr-util "$httpd_build_dir/srclib/apr-util" ./configure \ --prefix="$httpd_prefix" \ --enable-maintainer-mode \ --enable-ssl \ --enable-dav \ --with-mpm=prefork \ --with-included-apr make $MAKE_OPTS make install set +x cd "$was_wd" built="$built\n$httpd_prefix" fi fi if [ -d "$deps_build" ]; then echo echo "Removing build dir." rm -rf "$deps_build" fi echo echo "---------------- Dependencies" if [ -n "$existed" ]; then echo echo -n "Dependencies existed, not rebuilt:" echo -e "$existed" echo "To rebuild, rm -rf one or more of these folders." fi if [ -n "$built" ]; then echo echo -n "Dependencies built:" echo -e "$built" fi } function pat_clean(){ pat="$1" src="$pat/$_src" if [ -e "$src/Makefile" ]; then set -x cd "$src" && make extraclean set +x fi } function write_default_config(){ config_file="$1" mkdir -p "$(dirname "$config_file")" cat > "$config_file" < "$success_file" set +x } 2>&1 | tee "$build_log" success="$(cat "$success_file")" rm "$success_file" if [ "$success" != "success" ]; then pat_failure fi cd "$orig" } function pat_build(){ pat="$1" src="$pat/$_src" if [ ! -e "$src/Makefile" ]; then pat_configure_svn "$pat" fi src="$pat/$_src" prefix="$pat/$_prefix" build_log="$pat/$_buildlog" echo echo "---------------- Building Subversion" echo "$src" echo "NOTE: Only printing warnings and errors." echo " Full build output is in $build_log" success_file="$(pat_tempfile)" { set -x cd "$src" && make $MAKE_OPTS && \ rm -rf "$prefix" && \ cd "$src" && make install && \ echo "success" > "$success_file" set +x #} } 2>&1 | tee -a "$build_log" | grep "^[^[:blank:]]\+: " | grep -v "^libtool: \(install\|finish\):" || true cat "$success_file" success="$(cat "$success_file")" rm "$success_file" if [ "$success" != "success" ]; then pat_failure else pat_success fi } function cmd_re_make(){ re="$1" name="$2" pat="$(find_pat strict "$name")" if [ "$re" = "remake" ]; then pat_clean "$pat" if [ -d "$pat/$_prefix" ]; then rm -rf "$pat/$_prefix" fi fi pat_build "$pat" } function pat_get_changed_files(){ pat="$1" was_wd="$(pwd)" cd "$pat/$_src" svn st | grep "^[^?S ]" | grep -v "^ L" | sed 's/^....... //' | sort || true cd "$was_wd" } function pat_tempfile(){ mkdir -p "$base/$_tmp" mktemp -p "$base/$_tmp" } function pat_tempdir(){ mkdir -p "$base/$_tmp" mktemp -d -p "$base/$_tmp" } function pat_append_ignore_line(){ file="$1" ignore_line="--This line, and those below, will be ignored--" if [ -z "$(cat "$file" | grep "^$ignore_line\$" || true)" ]; then echo -e "\n$ignore_line" >> "$file" fi } function pat_do_diff(){ pat="$1" if [ -d "$pat/$_src/.svn" ]; then user_log_file="$pat/$_log" user_diff_file="$pat/$_diff" last_autolog_file="$pat/$_last_autolog" tmp_autolog_file="$(pat_tempfile "$pat")" echo "Reading 'svn status'" files="$(pat_get_changed_files "$pat")" if [ -z "$files" ]; then error_msg "$(nice_path "$pat/$_src") is not modified." fi was_wd="$(pwd)" cd "$pat/$_src" # List the files affected, and attempt to list the functions affected. { echo "$files" | while read file; do echo echo "* $file" # Find the names of the functions affected, and list them in parentheses. # Diff with no context ('-U0') to get more accurate function names. svn diff --diff-cmd diff -x '-U0 -p' "$file" | sed -e "s/^@@ [^@]* @@ .*\<\([A-Za-z_][A-Za-z0-9_]*\) *(.*/ (\1): /" -e "t" -e "d" | uniq || exit 1 done } > "$tmp_autolog_file" # Now make the diff. { # Call 'svn diff' for each file separately, to get them # in the same order as the list above. echo "$files" | while read file; do svn diff --depth=empty --diff-cmd diff -x -up "$file" || exit 1 done } > "$user_diff_file" if [ ! -e "$user_log_file" -o -z "$(cat "$user_log_file" 2>/dev/null)" ]; then # Nothing there yet. Just copy the autolog to the user editable log. cp "$tmp_autolog_file" "$user_log_file" elif [ ! -e "$last_autolog_file" ]; then # The previous autolog is missing. Can't diff. pat_append_ignore_line "$user_log_file" cat "$tmp_autolog_file" >> "$user_log_file" elif [ -z "$(diff "$user_log_file" "$last_autolog_file")" ]; then # The user has not edited the automatically generated log. Replace. cp "$tmp_autolog_file" "$user_log_file" else autolog_diff="$(diff -uw "$last_autolog_file" "$tmp_autolog_file" || true)" if [ -n "$autolog_diff" ]; then # The autolog has changed. pat_append_ignore_line "$user_log_file" echo "$autolog_diff" | grep "^-[^-]" >> "$user_log_file" || true echo "$autolog_diff" | grep "^+[^+]" >> "$user_log_file" || true fi fi mv "$tmp_autolog_file" "$last_autolog_file" cd "$was_wd" fi } function pat_make_patch(){ pat="$1" if [ -d "$pat/$_src/.svn" ]; then user_log_file="$pat/$_log" user_diff_file="$pat/$_diff" tmp_autolog_file="$(pat_tempfile "$pat")" # Do the save pat_name="$(pat_get_name "$pat")" stamp="$(date "+%Y%m%d-%H%M")" patch_file="$pat/$_patches/$pat_name.$stamp" if [ -e "$patch_file" ]; then patch_file="$patch_file-$(ls -1d $patch_file* | wc -l)" if [ -e "$patch_file" ]; then error "gee, I can't get a free name here. $patch_file" fi fi cat "$user_log_file" > "$patch_file" echo >> "$patch_file" # pat_append_ignore_line "$patch_file" # pat_find_config "$pat" 1 >> "$patch_file" # pat_read_deps_config "$pat" >> "$patch_file" # pat_read_tests_config "$pat" >> "$patch_file" cat "$user_diff_file" >> "$patch_file" last_patch_file="$pat/$_patches/$pat_name" if [ -L "$last_patch_file" ]; then if [ -z "$(diff "$last_patch_file" "$patch_file" 2>&1)" ]; then # this patch is the same as the last one. No need to keep it. echo "Patch remains unchanged." rm "$patch_file" fi fi # if the new patch file still exists at this point, we have a # new, modified patch version. # keep the timestamped patch file, also copy it over the last patch file if [ -e "$patch_file" ]; then echo "New patch: $(nice_path "$patch_file")" if [ -L "$last_patch_file" ]; then rm "$last_patch_file" elif [ -e "$last_patch_file" ]; then error "This should be a symbolic link to a patch file: $last_patch_file" fi echo ln -s "$(basename "$patch_file")" "$last_patch_file" ln -s "$(basename "$patch_file")" "$last_patch_file" fi fi } function pat_do_diff_and_make_patch(){ pat_do_diff "$@" pat_make_patch "$@" } function cmd_diff(){ pat="$(find_pat strict "$1")" src="$pat/$_src" log_file="$pat/$_log" diff_file="$pat/$_diff" pat_do_diff "$pat" was_wd="$(pwd)" cd "$src" if [ -n "$(echo "$EDITOR" | grep "\" || true)" ]; then vim -o2 "$diff_file" "$log_file" -c "resize 45" elif [ -n "$EDITOR" ]; then "$EDITOR" "$log_file" "$diff_file" else echo "edit \"$log_file\" \"$diff_file\"" fi cd "$was_wd" # in case there were changes to the log and/or source files pat_do_diff_and_make_patch "$pat" } function pat_save(){ pat="$1" pat_do_diff_and_make_patch "$pat" pat_add_and_commit "$pat" "save" unsaved="$(svn st "$pat/$_src" | grep '^?' || true)" name="$(pat_get_name "$pat")" if [ -n "$unsaved" ]; then echo -e "*** THESE FILES ARE UNSAVED in $name:\n$unsaved\n" fi } function cmd_save(){ pat="$(find_pat strict "$1")" pat_save "$pat" } function cmd_save_all(){ ls -1 "$base" | while read pat_name; do pat="$base/$pat_name" if [ -d "$pat/.pat" ]; then echo "----- $pat_name" pat_save "$pat" echo else echo "Ignoring $pat_name" fi done pat_add_and_commit "$base" } function cmd_invoke_svn(){ pat="$(find_pat strict "")" src="$pat/$_src" was_wd="$(pwd)" cd "$src" pwd verbose_svn $@ cd "$was_wd" } function printout_pat_sh_includes(){ echo '#source this in your ~/.bashrc or something function pat(){ function pat_do_cd(){ pat_dir="$("$(which pat)" "$1" "$2")" if [ "$?" = 0 ]; then echo "you were in:" pwd cd "$pat_dir" fi unset pat_dir } case "$1" in cd|cdp|cdt|cdtc|cdct|cdc|cds) pat_do_cd "$1" "$2" ;; new) "$(which pat)" "$@" if [ "$?" = 0 ]; then pat_do_cd cd "$2" fi ;; env|use|prefix|pow|power) reply="$("$(which pat)" "$@")" if [ -n "$(echo "$reply" | grep "::" || true)" ]; then # evaluate the reply pow="$(echo "$reply" | sed -e "s#::.*\$##")" prefix="$(echo "$reply" | sed -e "s#^.*::##")" # in effect, this: export PATH="$prefix/bin:$PATH" # but with some bells and whistles: strippedpath="$(echo "$PATH" | sed -e "s#$HOME/pat/[^:]*:##g")" export PATH="$prefix/bin:$strippedpath" # echo "$PATH" # in effect, this: export PS1="[${pow}] $PS1" # but with some bells and whistles: if [ -z "`echo $PS1 | grep "POWER" || true`" ]; then export PS1="<\${POWER}> $PS1" fi export POWER="$pow" fi ;; *) "$(which pat)" "$@" if [ "$?" != "0" ]; then echo ":-(" false fi ;; esac }' } function cmd_env(){ pat="$(find_pat lax "$1")" if [ -z "$pat" ]; then pat="$(find_pat strict stable)" fi if [ ! -d "$pat/$_prefix" ]; then error "Is not compiled: $pat" fi echo "$(pat_get_name "$pat")::$pat/$_prefix" } function cmd_edit(){ pat="$(find_pat strict "$1")" files="$(pat_get_changed_files "$pat")" cmd="vim" if shift; then cmd="$cmd $@" fi cmd="$cmd$( echo "$files" | while read file; do echo -n " \"$file\""; done )" was_wd="$(pwd)" cd "$pat/$_src" echo "$cmd" eval "$cmd" cd "$was_wd" } function pat_make_check(){ pat="$1" success_file="$(pat_tempfile)" { cd "$pat/$_src" && make check CLEANUP=1 PARALLEL=1 && \ echo "success" > "$success_file" } 2>&1 | tee "$pat/$_checklog" success="$(cat "$success_file")" rm "$success_file" if [ "$success" != "success" ]; then pat_failure else pat_success fi } function cmd_check(){ pat="$(find_pat strict "$1")" pat_make_check "$pat" } function cmd_ctags(){ pat="$(find_pat strict "$1")" was_wd="$(pwd)" cd "$pat/$_src" tagsfile="$pat/$_src/$_ctags" ctags -f "$tagsfile" --c-kinds=+p --c++-kinds=+p --fields=+iaS --extra=+q -R cd "$was_wd" echo "Tags file written to $(nice_path "$tagsfile")" echo "Include this in your .vimrc: set tags=$_ctags" } function cmd_send_to_bot(){ pat="$(find_pat lax "")" bot_name="$1" pat_save "$pat" pat_name="$(pat_get_name "$pat")" last_patch_file="$pat/$_patches/$pat_name" conf_get_const bot if [ -n "$bot_name" ]; then echo "Selecting bots named '$bot_name'" const_bot="$(echo "$const_bot" | grep "$bot_name")" fi echo "$const_bot" | while read bot; do echo Trying $bot set +e scp "$last_patch_file" "$bot" returnval="$?" set -e if [ "$returnval" = 0 ]; then echo ":^D Sent to $bot" break else echo ":-( No access to: $bot" fi done } function cmd_commit(){ pat="$(find_pat strict "$1")" src="$pat/$_src" log="$pat/$_log" last_autolog_file="$pat/$_last_autolog" if [ ! -d "$src/.svn" ]; then error "Not a subversion working copy: $(nice_path "$src")" fi if [ ! -r "$log" -o -z "$(diff "$log" "$last_autolog_file")" ]; then error "No or unedited log file. Use 'pat diff'." fi pat_save "$pat" was_wd="$(pwd)" echo cd "$(nice_path "$src")" echo "-------- diff" cat "$pat/diff" # produced by above pat_save echo "-------- status" cd "$src" svn status echo "-------- log" cat "$log" echo "--------" shift || true echo svn commit "$@" echo echo "Are you sure?" echo "To commit, enter 'ok', 'yes' or 'y' and hit enter." read answer if [ "$answer" != "y" -a "$answer" != "yes" -a "$answer" != "ok" ]; then error "aborted." fi svn ci -F "$log" "$@" rm "$log" } function cmd_grep(){ pat="$(find_pat strict)" was_wd="$(pwd)" echo "cd $(nice_path "$pat/$_src")" cd "$pat/$_src" echo "grep --exclude-dir=\".svn\" --exclude-dir=\".libs\" --exclude=\"*.o\" -rn $@ . | grep -v Binary" grep --exclude-dir=".svn" --exclude-dir=".libs" --exclude-dir="swig" --exclude="*.o" --exclude="tags" --exclude="test.log" -rn "$@" . | grep -v Binary || true cd "$was_wd" } function pat_apply_patch(){ pat="$1" patch_file="$2" echo echo "--------------------------------- Applying patch" if [ -z "$(cat "$patch_file" | grep "^+++ " || true)" ]; then echo "Patch is empty." else echo "patch -d $(nice_path "$pat/$_src") -p0 < $(nice_path "$patch_file")" patch -d "$pat/$_src" -p0 < "$patch_file" fi } function pat_unapply_patch(){ pat="$1" patch_file="$2" echo "patch -d $(nice_path "$pat/$_src") -R -p0 < $(nice_path "$patch_file")" patch -d "$pat/$_src" -R -p0 < "$patch_file" } function cmd_apply_patch(){ if [ -f "$1" ]; then pat="$(find_pat strict "")" patch_file="$1" else pat="$(find_pat strict "$1")" patch_file="$2" fi if [ ! -f "$patch_file" ]; then error "Need (at least) a patch file argument." fi pat_apply_patch "$pat" "$patch_file" } function cmd_unapply_patch(){ pat="$(find_pat strict "$1")" pat_unapply_patch "$pat" } function _compose_content_index(){ name="$1" active="$2" echo "_title" if [ -n "$active" ]; then echo "refresh:60" echo "label:testing $name" else echo "refresh:600" echo "label:idle. last was $name" fi echo "tail:$name/failures status _subdirs label:older logs in ../moved-away" } function _compose_content_subdir(){ current_log="$1" active="$2" echo "_title" if [ -n "$active" ]; then echo "refresh:60" else echo "label:done." fi echo "tail:failures" if [ -n "$current_log" ]; then echo "tail:$current_log" fi echo "_files" } function cmd_bot_test_patch(){ patch_file="$1" log_dir="$2" if [ -z "$(echo "$log_dir" | grep "^/")" ]; then log_dir="$(pwd)/$log_dir" fi if [ ! -f "$patch_file" -o ! -d "$log_dir" ]; then error "Invalid arguments." fi if [ ! -w "$patch_file" ]; then error_msg "Will only run on files that I am allowed to remove." error_msg "Otherwise I might end up doing the same patch over and over." error "Not writable: $patch_file" fi patch_name="$(basename "$patch_file")" index_content_file="$log_dir/_content" _compose_content_index "$patch_name" active > "$index_content_file" bot_ws="bot-$patch_name" if [ -e "$base/$bot_ws" ]; then bot_ws="$bot_ws-$(get_timestamp)" if [ -e "$base/$bot_ws" ]; then sleep 1 bot_ws="$bot_ws-$(get_timestamp)" if [ -e "$base/$bot_ws" ]; then error "gee, I can't get a free name here. $bot_ws" fi fi fi patch_log_dir="$log_dir/$patch_name" if [ -e "$patch_log_dir" ]; then movedir="$(dirname "$log_dir")/moved-away" mkdir -p "$movedir" echo "time reverse" > "$movedir/_sort_by" mv "$patch_log_dir" "$movedir/$(get_timestamp).$patch_name" fi if [ -e "$patch_log_dir" ]; then error "what?" fi subdir_content_file="$patch_log_dir/_content" mkdir -p "$patch_log_dir" _compose_content_subdir "" 1 > "$subdir_content_file" echo "[$(readable_timestamp)] Preparing $patch_name" set +e if $0 new "$bot_ws" >/dev/null 2>&1; then cp "$patch_file" "$patch_log_dir/patch_file" apply_log="apply" build_log="build" test_log="test" success_log="$patch_log_dir/SUCCESS" full_test_log="$base/$bot_ws/src/tests.log" full_test_log_link="$patch_log_dir/tests.log" failures_log="$patch_log_dir/failures" _sort_by_file="$patch_log_dir/_sort_by" echo "time" > "$_sort_by_file" touch "$failures_log" _compose_content_subdir "$apply_log" 1 > "$subdir_content_file" if $0 apply "$bot_ws" "$patch_file" > "$patch_log_dir/$apply_log" 2>&1; then echo "[$(readable_timestamp)] Building $patch_name" _compose_content_subdir "$build_log" 1 > "$subdir_content_file" if $0 build "$bot_ws" > "$patch_log_dir/$build_log" 2>&1; then echo "[$(readable_timestamp)] Testing $patch_name" _compose_content_subdir "$test_log" 1 > "$subdir_content_file" if [ -d "$base/$bot_ws" ]; then ln -s "$full_test_log" "$full_test_log_link" # have a grep-pipe that prints only the failures. # have that pipe in a bash subprocess so we can kill the # whole thing. (otherwise we'd get only grep's pid, never tail's) set +m bash -c "set +m; tail -F \"$full_test_log\" --pid \"\$\$\" \ | grep --line-buffered \"^\(FAIL\|XPASS\)\" \ > \"$failures_log\" 2>/dev/null" >/dev/null 2>&1 & test_log_tail_pid="$!" fi if $0 check "$bot_ws" > "$patch_log_dir/$test_log" 2>&1; then echo "[$(readable_timestamp)] :^D Success"'!'" $patch_name is Good"'!' touch "$success_log" rm "$full_test_log_link" >/dev/null 2>&1 || true else echo "[$(readable_timestamp)] :,( Tests failed for $patch_name." | tee -a "$failures_log" rm "$full_test_log_link" >/dev/null 2>&1 || true cp "$full_test_log" "$full_test_log_link" fi if [ -n "$test_log_tail_pid" ]; then set +m kill "$test_log_tail_pid" >/dev/null 2>&1 || true fi else echo echo "[$(readable_timestamp)] :( Build failed for $patch_name." | tee -a "$failures_log" fi else echo echo "[$(readable_timestamp)] :( Applying patch $patch_name failed." | tee -a "$failures_log" fi else echo echo "[$(readable_timestamp)] o_O Checking out source failed." | tee -a "$failures_log" fi _compose_content_subdir "" > "$subdir_content_file" mv "$patch_file" "$bot_done_dir/" || true if [ -d "$base/$bot_ws" ]; then rm -rf "$base/$bot_ws" >/dev/null 2>&1 || true fi _compose_content_index "$patch_name" > "$index_content_file" } function get_file_username(){ if [ -n "$(uname | grep BSD)" ]; then stat -f "%Su" "$1" else stat -c "%U" "$1" fi } function cmd_bot_daemon(){ bot_pid_file="$1" bot_receive_dir="$2" bot_log_dir="$3" errors="" if [ -z "$bot_pid_file" ]; then errors="$errors\n No pid-file given." elif [ -e "$bot_pid_file" -a ! -w "$bot_pid_file" ]; then errors="$errors\n pid-file not writable." fi if [ ! -d "$bot_receive_dir" -o ! -w "$bot_receive_dir" ]; then if [ -z "$bot_receive_dir" ]; then errors="$errors\n No bot-receive folder given." else errors="$errors\n Bot-receive folder '$bot_receive_dir' not writable." fi fi if [ ! -d "$bot_log_dir" -o ! -w "$bot_log_dir" ]; then if [ -z "$bot_log_dir" ]; then errors="$errors\n No bot-log folder given." else errors="$errors\n Bot-log folder '$bot_log_dir' not writable." fi fi echo "Got:" echo " pid-file='$bot_pid_file'" echo " receive-dir='$bot_receive_dir'" echo " log-dir='$bot_log_dir'" if [ -n "$errors" ]; then echo "Invalid arguments. Need:" echo " pat bot-daemon " echo "Where and must be existing folders." echo -e "Errors:$errors" pwd exit 1 fi if [ -n "$bot_pid_file" ]; then echo -n "$$" > "$bot_pid_file" fi mkdir -p "$bot_active_dir" "$bot_done_dir" chmod o-w "$bot_active_dir" "$bot_done_dir" bot_status_log="$bot_log_dir/status" echo "Status log: $bot_status_log" while true; do set -e # make sure we're still authorized to run. if [ "$$" != "$(cat "$bot_pid_file")" ]; then exit 0 fi # Instead of doing one by one, queue first. # Like that, if unwritable patches are lying around, we won't get # stuck on them. next_patch_tempfile="$(pat_tempfile)" # Grab one from the receive dir into the queue ls -1cr "$bot_receive_dir" | while read next_basename; do next="$bot_receive_dir/$next_basename" if [ -f "$next" ]; then patch_name="$(get_file_username "$next")-$next_basename" if [ -w "$next" ]; then if mv "$next" "$bot_active_dir/$patch_name" 2>/dev/null; then echo "$patch_name" > "$next_patch_tempfile" break fi fi echo echo "----- Not Queueing $next" echo "Will only run on files that I am allowed to remove." echo "Otherwise I might end up doing the same patch over and over." fi done next_patch="$(cat "$next_patch_tempfile")" rm "$next_patch_tempfile" if [ -n "$next_patch" ]; then # ensure any tail -F don't skip the first line: if [ -f "$bot_status_log" ]; then rm "$bot_status_log" fi { "$0" bot_test_patch "$bot_active_dir/$next_patch" "$bot_log_dir" || true } 2>&1 | grep --line-buffered -v "[0-9] Terminated" | tee "$bot_status_log" else sleep 10 fi done } function cmd_remove(){ pat="$(find_pat strict "$1")" $0 save "$(pat_get_name "$pat")" || true vc_commit "$pat" echo echo "Are you sure you want to REMOVE '$pat'?" echo "Your patches and tests are still saved in version control." echo "To remove, enter 'ok', 'yes' or 'y' and hit enter." read answer if [ "$answer" != "y" -a "$answer" != "yes" -a "$answer" != "ok" ]; then error "aborted." fi echo "Removing $pat" rm -rf "$pat" vc_remove "$pat" } function cmd_httpd(){ pat="$(find_pat strict "")" if [ -z "$1" ]; then httpd_base="$pat/httpd" add_make_check_targets=1 else httpd_base="$(readlink -f "$1")" fi httpd_port="$2" if [ -z "$httpd_port" ]; then httpd_port=8090 fi if [ -e "$httpd_base" ]; then error_msg "Already exists: $httpd_base" echo "To remove, enter 'ok', 'yes' or 'y' and hit enter." read answer if [ "$answer" != "y" -a "$answer" != "yes" -a "$answer" != "ok" ]; then error "aborted." fi echo "Removing $httpd_base" rm -rf "$httpd_base" fi mkdir -p "$httpd_base" pat_read_deps_config "$pat" cp -a "$httpd_prefix/conf" "$httpd_base/" httpd_conf="$httpd_base/conf/httpd.conf" httpd_users="$httpd_base/users" httpd_parentpath="$httpd_base/svnparent" httpd_logs="$httpd_base/logs" httpd_htdocs="$httpd_base/htdocs" mkdir -p "$httpd_parentpath" mkdir -p "$httpd_logs" mkdir -p "$httpd_htdocs" ln -s "$httpd_prefix/modules/svn-$(pat_get_name "$pat")" "$httpd_base/modules" src="$pat/$_src" echo "jrandom:xCGl35kV9oWCY jconstant:xCGl35kV9oWCY" > "$httpd_users" echo "ServerRoot \"$httpd_base\" Listen 127.0.0.1:$httpd_port LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so DocumentRoot \"$httpd_htdocs\" Options FollowSymLinks AllowOverride None Order deny,allow Allow from all " > "$httpd_conf" if [ -n "$add_make_check_targets" ]; then echo "# These two Locations are used for 'make check' DAV svn SVNParentPath $src/subversion/tests/cmdline/svn-test-work/repositories AuthzSVNAccessFile $src/subversion/tests/cmdline/svn-test-work/authz AuthType Basic AuthName \"Subversion Repository\" AuthUserFile $httpd_users Require valid-user DAV svn SVNPath $src/subversion/tests/cmdline/svn-test-work/local_tmp/repos AuthzSVNAccessFile $src/subversion/tests/cmdline/svn-test-work/authz AuthType Basic AuthName \"Subversion Repository\" AuthUserFile $httpd_users Require valid-user " >> "$httpd_conf" echo 'RedirectMatch permanent ^/svn-test-work/repositories/REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1' >> "$httpd_conf" echo 'RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1' >> "$httpd_conf" fi echo "# This Location lets you access repositories dropped in the path below DAV svn SVNParentPath \"$httpd_parentpath\" Allow from all " >> "$httpd_conf" ld_library_path="$apr_prefix/lib:$libiconv_prefix/lib:$db_prefix/lib:$neon_prefix/lib:$sqlite_prefix/lib:$pat/$_prefix/lib" httpd_cmd="env LD_LIBRARY_PATH=$ld_library_path $httpd_prefix/bin/apachectl -f $httpd_conf" httpd_start="$httpd_base/start" httpd_stop="$httpd_base/stop" httpd_restart="$httpd_base/restart" echo "#!/bin/sh $httpd_cmd -k start \\ && echo \"Started httpd. $httpd_parentpath/ == http://localhost:$httpd_port/svn/\" \\ || tail -n 100 \"$httpd_logs/error_log\" " > "$httpd_start" echo "#!/bin/sh $httpd_cmd -k stop \\ && sleep 3 \\ && echo \"stopped httpd on http://localhost:$httpd_port\" \\ || echo \"stopping httpd failed, apparently.\" " > "$httpd_stop" echo "#!/bin/sh \"$httpd_stop\" sleep 3 \"$httpd_start\" " > "$httpd_restart" chmod a+x "$httpd_start" "$httpd_stop" "$httpd_restart" } case "$1" in init) shift cmd_init "$@" ;; sh|bashrc|rc|bash) printout_pat_sh_includes ;; new|create) shift cmd_new "$@" ;; recheckout|reco|checkout|co) shift cmd_re_checkout "$@" ;; deps|dependencies) shift cmd_deps "$@" ;; make|build|m|b) if [ "$2" = "deps" ]; then if [ -n "$3" ]; then error "does not take any arguments: $1 $2" fi shift shift cmd_deps "$@" else shift cmd_re_make make "$@" fi ;; remake|rebuild|re) if [ "$2" = "deps" ]; then error_msg "Ignoring 'remake' for deps. To rebuild all deps, do:" error " rm -rf \"$deps_prefix\"" fi shift cmd_re_make remake "$@" ;; env|use|prefix|pow|power) shift cmd_env "$@" ;; check) shift cmd_check "$@" ;; tag|tags|ctags) shift cmd_ctags "$@" ;; e|ed|edit|vi|vim) shift cmd_edit "$@" ;; tvim|tvi) shift cmd_ctags "$@" cmd_edit "$@" ;; diff|view|log) shift cmd_diff "$@" ;; save) shift if [ "$1" = "all" ]; then cmd_save_all else cmd_save "$@" fi ;; cd) shift cmd_cd "$@" ;; cdp) shift cmd_cdp "$@" ;; cdt) shift cmd_cdt "$@" ;; cds) shift cmd_cds "$@" ;; cdtc|cdct|cdc) shift cmd_cdtc "$@" ;; clone) shift cmd_clone "$@" ;; backup) shift cmd_backup "$@" ;; st|status|up|update|info|revert|resolved|blame|merge) cmd_invoke_svn "$@" ;; showconfig|config|conf) shift cmd_showconfig "$@" ;; bot|send) shift cmd_send_to_bot "$@" ;; test|test-patch|check-patch) shift cmd_test_patch "$@" ;; commit|ci) shift cmd_commit "$@" ;; grep) shift cmd_grep "$@" ;; apply|ap|patch) shift cmd_apply_patch "$@" ;; unpatch|unap|unapply) shift cmd_unapply_patch "$@" ;; hist|history) usage ;; bot-daemon) shift cmd_bot_daemon "$@" ;; bot_test_patch) shift cmd_bot_test_patch "$@" ;; delete|del|remove|rm) shift cmd_remove "$@" ;; httpd) shift cmd_httpd "$@" ;; *) usage ;; esac