Date: Mon, 20 Aug 2012 20:42:24 +0000 (UTC) From: Matthias Andree <mandree@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r302830 - head/Tools/scripts Message-ID: <201208202042.q7KKgOrZ090134@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mandree Date: Mon Aug 20 20:42:24 2012 New Revision: 302830 URL: http://svn.freebsd.org/changeset/ports/302830 Log: Changes over original script: - FIX: all progress and error output goes to fd#2 (stderr) - FIX: at top level, properly detect commands if preceded by options - FIX: in checkstatus(), handle ~ (obstructed versioned item) - FIX: support blanks, leading dashes, and shell meta characters: + in file names, so as not to choke the script on difficult file names + in command line arguments, so that svn commit -m "commit message" works, rather than complaining about an unversioned file "message". - FIX: in checkstatus(), keep leading spaces from svn status - FIX: in setprop(), detect egrep errors, rather than assuming "no match" - ADD: die if "check" psvn-specific command has trailing arguments - CHANGE: replace `...` by more concise $(...) notation - CHANGE: take maintainership, offered by beat@. - SPEEDUP: in checkstatus(), use shell built-ins, rather than commands - SPEEDUP: when checking files, run svn only once, rather than for each file - SPEEDUP: when skipping "svn rm"-ed files, use ! -e rather than head|awk - TODO: handle long options for svn commit - TODO: do not stomp over svn:mime-type if it's already set (binary files!) Approved by: beat@ (maintainer) Modified: head/Tools/scripts/psvn Modified: head/Tools/scripts/psvn ============================================================================== --- head/Tools/scripts/psvn Mon Aug 20 20:40:29 2012 (r302829) +++ head/Tools/scripts/psvn Mon Aug 20 20:42:24 2012 (r302830) @@ -1,4 +1,4 @@ -#!/bin/sh -e +#!/bin/sh -eu # # psvn - Wrapper to set Subversion properties automatically # @@ -27,52 +27,62 @@ # # $FreeBSD$ # -# MAINTAINER= beat@FreeBSD.org +# MAINTAINER= mandree@FreeBSD.org +# beat@ has implicit approval to change this script. # # # The psvn wrapper checkes from replaced, conflicting, missing or -# untracked files. When committing it adds the needed Subversion +# untracked files. When committing it adds the needed Subversion # properties and removes unneeded ones. # There is also adds a check subcommand which just executes the # checks. -# +# PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:${PATH} export PATH -SVN=`which svn` +SVN="$(which svn)" +LF="$(printf '\nX')" +LF="${LF%X}" -VERSION=`${SVN} --version --quiet | sed -e 's,^\(.*\)\.\(.*\)\..*,\1\2,'` +VERSION=$("${SVN}" --version --quiet | sed -e 's,^\(.*\)\.\(.*\)\..*,\1\2,') if [ ${VERSION} -lt 17 ] ; then - echo "===> Please consider upgrading to Subversion 1.7" + echo "===> Please consider upgrading to Subversion 1.7 (or newer)" fi checkstatus () { + local IFS _error _file _status _statusline - _error=0 - - _files="${@}" + eval "set -- $@" + IFS="$LF" + set -- $("${SVN}" status -- "$@") - for _file in `echo ${_files}` + for _statusline do - _status=`${SVN} status ${_file} | awk '{ print $1 }'` + _status="$(printf '%.7s' "${_statusline}")" + _file="${_statusline##????????}" case "${_status}" in - R?|R) - echo "===> Do not replace files as this will break the CVS exporter: ${_file}" + R*) + printf >&2 '===> Do not replace files as this will break the CVS exporter: "%s"\n' "${_file}" + _error=1 + ;; + C*|?C*) + printf >&2 '===> Conflict detected: \"%s\"\n' "${_file}" _error=1 ;; - C|?C) - echo "===> Conflict detected: ${_file}" + \~*) + printf >&2 '===> Versioned item \"%s\" obstructed.\n' "${_file}" _error=1 ;; - \?) - echo "===> Untracked file. Consider svn adding or deleting this file: ${_file}" + \?*) + printf >&2 '===> Untracked new file "%s". Consider svn adding or deleting it.\n' "${_file}" _error=1 ;; - \!) - echo "===> Removed file. Consider readding or svn deleting this file: ${_file}" + \!*) + printf >&2 '===> Missing file "%s". Consider re-adding or svn deleting it.\n' "${_file}" _error=1 ;; esac @@ -85,61 +95,96 @@ checkstatus () { } setprop () { - _files="${@}" + local _file - + eval "set -- $1" - for _file in `echo ${_files}` + for _file do - if [ -d ${_file} ] ; - then - continue - fi - if [ `${SVN} status ${_file} | head -1 | awk '{ print $1 }'` = 'D' ] ; + if [ -d "${_file}" -o ! -e "${_file}" ] ; then continue fi - echo "=> Adding svn keywords to ${_file}" - if egrep '\$FreeBSD\$|\$[BDFSer]+:' ${_file} > /dev/null ; - then - ${SVN} -q propset svn:keywords "FreeBSD=%H" ${_file} - ${SVN} -q propdel fbsd:nokeywords ${_file} - else - ${SVN} -q propset fbsd:nokeywords 1 ${_file} - ${SVN} -q propdel svn:keywords ${_file} - fi - if [ `basename ${_file}` != "bsd.port.mk" ] ; - then - ${SVN} -q propset svn:eol-style native ${_file} + printf >&2 '=> Adding svn keywords to "%s"\n' "${_file}" + case $(egrep -- '\$FreeBSD\$|\$[BDFSer]+:' "${_file}" >/dev/null || echo $?) in + "") # matched pattern + "${SVN}" -q -- propset svn:keywords "FreeBSD=%H" "${_file}" + "${SVN}" -q -- propdel fbsd:nokeywords "${_file}" + ;; + 1) # no match + "${SVN}" -q -- propset fbsd:nokeywords 1 "${_file}" + "${SVN}" -q -- propdel svn:keywords "${_file}" + ;; + *) # egrep failed + exit 1 + ;; + esac + if [ "${_file##/*}" != "bsd.port.mk" ] ; then + "${SVN}" -q -- propset svn:eol-style native "${_file}" fi - ${SVN} -q propset svn:mime-type text/plain ${_file} - ${SVN} -q propdel cvs2svn:cvs-rev ${_file} + "${SVN}" -q -- propset svn:mime-type text/plain "${_file}" + "${SVN}" -q -- propdel cvs2svn:cvs-rev "${_file}" done } +# taken from "Rich's sh (POSIX shell) tricks", +# a "Programming Guide[...]" at http://www.etalabs.net/sh_tricks.html +savearray() { + for i do + printf %s\\n "$i" | sed -e "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" + done + echo " " +} + +getfilequotedarray() { + local varname IFS + varname="$1" + shift + IFS="$LF" + set -- $("${SVN}" status -- "$@" | sed 's/^....... //') + eval "$varname=\$(savearray "\$@")" +} -case "${1}" in +for opt ; do + case "${opt}" in + -*) continue ;; + esac + case "${opt}" in check) - files=`${SVN} status | awk '{ print $NF }'` + shift + if [ $# -gt 0 ] ; then + echo >&2 "===> Unsupported option before, or garbage after command" + exit 1 + fi + getfilequotedarray "files" "$@" checkstatus "${files}" exit 0 ;; ci|commit) - opts=${@} + savedargs=$(savearray "$@") shift - while getopts qm:F: opt + while getopts :qm:F: opt do case "$opt" in q) ;; m) ;; F) ;; + \?) echo >&2 "===> Unsupported option -$OPTARG encountered. Abort." + exit 1 ;; + :) echo >&2 "===> Missing argument to option -$OPTARG. Abort." + exit 1 ;; esac done - shift `expr $OPTIND - 1` - files=`${SVN} status "${@}" | awk '{ print $NF }'` + shift $(($OPTIND - 1)) + + getfilequotedarray "files" "$@" checkstatus "${files}" setprop "${files}" - ${SVN} ${opts} + + eval "set -- $savedargs" + "${SVN}" "$@" ;; *) - ${SVN} $@ + "${SVN}" "$@" ;; -esac + esac +done
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208202042.q7KKgOrZ090134>