#!/bin/bash helper functions for bash # # usage: # invoke this script from your .bashrc to set up helper functions for working # with subversion on openlaszlo. # If $SVNCHANGES is not set before invoking this command, we will create a # directory svnchanges in your home directory. # See README.txt in this directory. # # author: benjamin shine / p t withington # last modified: 2007-03-18 by ptw # Copyright 2006, 2007, 2008 Laszlo Systems, Inc. export EDITOR=${EDITOR:-"vim"} export SVNCHANGES=${SVNCHANGES:-$HOME/svnchanges} # Make sure the changes directory exists if ! [ -d $SVNCHANGES ]; then mkdir $SVNCHANGES fi export CYGWIN_BROWSER=${CYGWIN_BROWSER:-"/cygdrive/c/Program Files/Mozilla Firefox/firefox.exe"} function empty-change-description() { echo "empty-change-description is deprecated. Use svn-newchange instead." echo "See $LZ_TOOLS_ROOT/svn/README.txt for usage details." } function svn-makechangepackage() { echo "svn-makechangepackage is deprecated. Use svn-review instead." echo "See $LZ_TOOLS_ROOT/svn/README.txt for usage details." } # Start the process off with an empty change description file. # A temporary file will be created in $SVNCHANGES if set, or the current # directory. function svn-newchange() { CREATEDATE=`date +"%Y%m%d"` OL_CHANGE_DIR=`mktemp -d $SVNCHANGES/${CREATEDATE}-${USER}-X` CHANGE_DESCRIPTION=${OL_CHANGE_DIR}/change.txt export OL_CHANGE_NAME=`basename $OL_CHANGE_DIR` echo -n "Change ${OL_CHANGE_NAME} by ${USER}@${HOSTNAME} " > $CHANGE_DESCRIPTION echo `date +' on %F %T %Z'` >> $CHANGE_DESCRIPTION echo " in ${PWD}" >> $CHANGE_DESCRIPTION svn info | sed -n -e '/^URL: /s/^URL: \(.*\)$/ for \1/p' >> $CHANGE_DESCRIPTION echo "" >> $CHANGE_DESCRIPTION cat $LZ_TOOLS_ROOT/svn/change-template.txt >> $CHANGE_DESCRIPTION svn status -q >> $CHANGE_DESCRIPTION echo "Created change $OL_CHANGE_NAME in $CHANGE_DESCRIPTION " } # Edit a change description # Arguments: [changename] # where changename is a directory created by empty-change-description # If no arguments are specified, it uses $OL_CHANGE_NAME if it # exists, otherwise it creates a new empty change template function svn-editchange() { changename=${1:-${OL_CHANGE_NAME}} change=${SVNCHANGES}/${changename}/change.txt if [ -w ${change} ]; then $EDITOR ${change} else svn-newchange ${*} $EDITOR ${SVNCHANGES}/${OL_CHANGE_NAME}/change.txt fi } # Update the fileset in a change description # Arguments: [changename] (defaults to $OL_CHANGE_NAME) # Updates the file list in the change to be the current set of # modified files and opens it in your editor function svn-updatechange() { changename=${1:-${OL_CHANGE_NAME}} change=${SVNCHANGES}/${changename}/change.txt if [ ${change} ] && [ -w ${change} ]; then mv ${change} ${change}~ sed -e '/^Files:/,$d' < ${change}~ > ${change} echo 'Files:' >> ${change} svn status -q >> ${change} $EDITOR ${change} else echo "Couldn't find change $changename" fi } # Make a change package, import it into perforce, # and send mail requesting a review, with a link # to te patch in svn. Must either specify a change # description by name as argument, or it will use $OL_CHANGE_NAME function svn-review() { changename=${1:-${OL_CHANGE_NAME}} change=${SVNCHANGES}/${changename}/change.txt if [ ${change} ] && [ -w ${change} ]; then # make a change tarball with a name that matches the # change description temp file PATCHDIR=${SVNCHANGES}/${changename} THEFILETAR=${PATCHDIR}/files.tar THEAPPLYSCRIPT=${PATCHDIR}/apply.sh # Create a tar of the changed and added files, don't recurse into added directories tar --preserve -cvf ${THEFILETAR} --no-recursion `sed -e '1,/^Files:/d' -e '/^D/d' -e 's/^[A-Z +]\{6\} *//' < ${change}` # Create a script which will apply the patch echo 'patch -bu -p0 <<"EOF"' > ${THEAPPLYSCRIPT} # Create a patch which exactly describes the local changes to the files svn diff --non-recursive `sed -e '1,/^Files:/d' -e 's/^[A-Z +]\{6\} *//' < ${change}` >> ${THEAPPLYSCRIPT} echo 'EOF' >> ${THEAPPLYSCRIPT} # TODO: copy added files from the files.tar into the tree # TODO: safely remove deleted files from the tree (how can this be safe?) chmod ugo+x $THEAPPLYSCRIPT THEWHOLEPATCH=${SVNCHANGES}/${changename}/${changename}.tar # Actually create the tar we're going to post tar --preserve --exclude '*~' -cf ${THEWHOLEPATCH} -C ${SVNCHANGES} ${changename} # import the change tar to svn CHANGEURL=http://svn.openlaszlo.org/openlaszlo/patches/${changename}.tar svn import -q -m "importing patch ${changename} for review" ${THEWHOLEPATCH} ${CHANGEURL} || { svn delete -q -m "remove patch ${changename}" ${CHANGEURL} && svn import -q -m "updating patch ${changename} for review" ${THEWHOLEPATCH} ${CHANGEURL}; } || { echo "Couldn't import change to svn!"; return -1; } # send mail requesting a review case `uname` in "Darwin") mailto=`cat ${change} | perl ${LZ_TOOLS_ROOT}/svn/review-mail.pl ${CHANGEURL}` # mac specific, use your platform's url opener # --- 'open $mailto' explodes on long urls, so do it this way osascript -e 'tell application "Mail"' -e "mailto(\"${mailto}\")" -e 'activate' -e 'end tell' ;; "CYGWIN_NT-5.1") mailto=`cat ${change} | perl ${LZ_TOOLS_ROOT}/svn/review-mail.pl ${CHANGEURL}` echo "Changeset: ${CHANGEURL}" "${CYGWIN_BROWSER}" "${mailto}" ;; * ) echo "Paste the following message into your mail program:" 1>&2 cat ${change} echo echo "Changeset: ${CHANGEURL}" echo 1>&2 echo "Remember to mail your reviewers and cc laszlo-dev@openlaszlo.org" 1>&2 ;; esac # Clean up the temporary patch dir rm ${THEWHOLEPATCH} else echo "Couldn't find change $changename" fi } function _svn_ci() { # last arg should be a file listing svn files, # (expecting this to be used as "_svn_ci .... --targets /.../files.txt" ) # need one of the files in files.txt to get the new revision number _lastarg=${!#} _committed_file=`head -1 < $_lastarg` svn ci "$@" && _newrev=`svn info "$_committed_file" | sed -e '/Revision: /!d' -e 's/.*: //'` && (echo "Log message from 'svn log -v -r$_newrev' follows:" && svn log -v -r$_newrev && printf "\n\n\ Remember to update any Jira entries for bugs that are fixed by your\n\ change by pasting the log message just above into Jira as the comment when\n\ resolving the bug. Also update the Fixed in Change# field with your\n\ revision number: $_newrev.\n\n") 1>&2 } # Check in a change that has been reviewed # Arguments: [changename] # If no arguments are specified, it uses $OL_CHANGE_NAME function svn-commit() { changename="${1:-${OL_CHANGE_NAME}}" if [ "${changename}" ]; then changedir="${SVNCHANGES}/${changename}" change="${changedir}/change.txt" if [ -w "${changedir}" ] && [ -r "${change}" ]; then message="${changedir}/message.txt" files="${changedir}/files.txt" sed -e '1,/^Files:/d' -e 's/^[A-Z +]\{6\} *//' < "${change}" > "${files}" sed -e '/^Files:/,$d' < "${change}" > "${message}" # If there is no SVNPASSWD, assume user has ssh privileges if [ "${USER}" != '' -a "${SVNPASSWD}" != '' ]; then _svn_ci --file "${message}" --username "${USER}" --password "${SVNPASSWD}" --targets "${files}" && \ rm -r "${changedir}" else _svn_ci --file "${message}" --targets "${files}" && \ rm -r "${changedir}" fi else echo "$changename inaccessible" return -1 fi else echo "No change specified" return -2 fi } # Describe a change, showing the diffs # Arguments: [changedescriptionfile] # If no arguments are specified, it uses $OL_CHANGE_DESCRIPTION function svn-describe() { changename=${1:-${OL_CHANGE_NAME}} change=${SVNCHANGES}/${changename}/change.txt if [ ${change} ] && [ -w ${change} ]; then files=`sed -e '1,/^Files:/d' -e 's/^[A-Z +]\{6\} *//' < ${change}` cat ${change} echo echo "Differences:" echo svn diff --non-recursive --no-diff-deleted ${files} else echo "No change specified" fi } # Lists pending changes function svn-pending() { (cd ${SVNCHANGES}; grep --with-filename 'Summary' */change.txt | sed -e 's|/change.txt:|: |') } function svn-unapplychangepackage() { patch -p0 -R -i difffile } # List the status of locally changed files function svn-changed() { svn status | grep "[:space:]*[MDACR\!-][:space:]*" } function svn-needs-update() { svn status -u | grep "[:space:]*\*[:space:]*" } function get-latest-build() { echo `ls -1trd build* | tail -1` }