#!/bin/bash # # Homepage: http://code.google.com/p/coderev # License: GPLv2, see "COPYING" # # Generate code review page of <workspace> vs <workspace>@HEAD, by using # `codediff.py' - a standalone diff tool # # Usage: cd your-workspace; coderev.sh [file|subdir ...] # # $Id: coderev.sh 10 2008-08-23 09:02:26Z mattwyl $ PROG_NAME=$(basename $0) BINDIR=$(cd $(dirname $0) && pwd -L) || exit 1 CODEDIFF=$BINDIR/codediff.py function help { cat << EOF Usage: $PROG_NAME [-r revsion] [-w width] [file|subdir ...] \`revision' is a revision number, or symbol (PREV, BASE, HEAD) in svn, see svn books for details. Default revision is revision of your working copy \`width' is a number to make code review pages wrap in specific column Default \`subdir' is working dir. Example 1: $PROG_NAME -w80 bin lib Generate coderev based on your working copy, web pages wrap in column 80. If you are working on the most up-to-date version, this is suggested way (faster). Example 2 (for SVN): $PROG_NAME -r HEAD bin lib Generate coderev based on HEAD revision (up-to-date version in repository), this will retrive diffs from SVN server so it's slower, but most safely. EOF return 0 } #################### VCS Operations Begin #################### # Return code: 0 - Unknown, 1 - SVN, 2 - CVS # function detect_vcs { [[ -f .svn/entries ]] && return 1 [[ -f CVS/Entries ]] && return 2 return 0 } function set_vcs_ops { local i=${1?} local vcs_opt=${VCS_OPS_TABLE[i]} eval vcs_get_banner=\${$vcs_opt[0]} eval vcs_get_repository=\${$vcs_opt[1]} eval vcs_get_project_path=\${$vcs_opt[2]} eval vcs_get_working_revision=\${$vcs_opt[3]} eval vcs_get_active_list=\${$vcs_opt[4]} eval vcs_get_diff=\${$vcs_opt[5]} eval vcs_get_diff_opt=\${$vcs_opt[6]} } # VCS Operations: # get_banner - print banner, return 1 if not supported # get_repository - print repository # get_project_path - print project path without repository # get_working_revision pathname ... - print working revision # get_active_list pathname ... - print active file list # get_diff [diff_opt] pathname ... - get diffs for active files # get_diff_opt - print diff option and args # Unknown ops just defined here, others see libxxx.sh # UNKNOWN_OPS=( unknown_get_banner : : : : : : ) function unknown_get_banner { echo "unknown" return 1 } VCS_OPS_TABLE=( UNKNOWN_OPS SVN_OPS CVS_OPS ) . $BINDIR/libsvn.sh || exit 1 . $BINDIR/libcvs.sh || exit 1 # Detect VCS (Version Control System) and set handler # detect_vcs set_vcs_ops $? #################### VCS Operations End #################### # Main Proc # while getopts "hr:w:" op; do case $op in h) help; exit 0 ;; r) REV_ARG="$OPTARG" ;; w) CODEDIFF_OPT="-w $OPTARG" ;; ?) help; exit 1 ;; esac done shift $((OPTIND - 1)) PATHNAME="${@:-.}" BANNER=$($vcs_get_banner) || { echo "Unsupported version control system ($BANNER)." >&2 exit 1 } echo "Version control system \"$BANNER\" detected." # Retrive information # echo "Retriving information ..." PROJ_PATH=$($vcs_get_project_path) WS_NAME=$(basename $PROJ_PATH) WS_REV=$($vcs_get_working_revision $PATHNAME) echo "Repository : $($vcs_get_repository)" echo "Project path : $PROJ_PATH" echo "Working revision : $WS_REV" # Prepare file list and base source # TMPDIR=$(mktemp -d /tmp/coderev.XXXXXX) || exit 1 LIST="$TMPDIR/activelist" DIFF="$TMPDIR/diffs" BASE_SRC="$TMPDIR/$WS_NAME-base" $vcs_get_active_list $PATHNAME > $LIST || exit 1 echo "========== Active file list ==========" cat $LIST echo "========================================" # Generate $BASE_SRC # mkdir -p $BASE_SRC || exit 1 tar -cf - $(cat $LIST) | tar -C $BASE_SRC -xf - || exit 1 echo "Retriving diffs ..." VCS_REV_OPT="" [[ -n $REV_ARG ]] && VCS_REV_OPT="$($vcs_get_diff_opt $REV_ARG)" $vcs_get_diff $VCS_REV_OPT $(cat $LIST) > $DIFF || exit 1 patch -NER -p0 -d $BASE_SRC < $DIFF || exit 1 # Generate coderev # echo "Generating code review ..." CODEREV=$TMPDIR/${WS_NAME}-r${WS_REV}-diff $CODEDIFF $CODEDIFF_OPT -o $CODEREV -y -f- $BASE_SRC . < $LIST || exit 1 echo "Coderev pages generated at $CODEREV" echo # Cleanup # rm -rf $LIST $DIFF $BASE_SRC # Copy to web host # [[ -r ~/.coderevrc ]] || { echo "[*] Hint: if you want to copy coderev pages to a remote host" echo " automatically, see coderevrc.sample" echo exit 0 } . ~/.coderevrc || { echo "Reading ~/.coderevrc failed." >&2 exit 1 } : ${WEB_HOST?"WEB_HOST not defined."} : ${SSH_USER?"SSH_USER not defined."} : ${HOST_DIR?"HOST_DIR not defined."} : ${WEB_URL?"WEB_URL not defined."} scp -r $CODEREV ${SSH_USER}@${WEB_HOST}:$HOST_DIR/ || exit 1 echo echo "Coderev link:" echo "$WEB_URL/$(basename $CODEREV)" echo exit 0