diff options
author | Alex Tarkovsky <alextarkovsky@gmail.org> | 2006-07-11 08:02:44 +0000 |
---|---|---|
committer | Alex Tarkovsky <alextarkovsky@gmail.org> | 2006-07-11 08:02:44 +0000 |
commit | 31d191b7ae8e34fccd2fa457806c2d68493c1cf6 (patch) | |
tree | 1b84d1fee69f27195ae4c824f0307a734f5980ac /scripts | |
parent | net-mail/gmail-notify: incorporated suggestions from Tristan Heaven (diff) | |
download | sunrise-31d191b7ae8e34fccd2fa457806c2d68493c1cf6.tar.gz sunrise-31d191b7ae8e34fccd2fa457806c2d68493c1cf6.tar.bz2 sunrise-31d191b7ae8e34fccd2fa457806c2d68493c1cf6.zip |
scripts/sunrise-commit: Don't 'svn add' deleted items; new intelligent parsing and handling of 'svn status' output; more accurately determine working copy base dir; minor code cleanup.
svn path=/sunrise/; revision=587
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/sunrise-commit | 186 |
1 files changed, 151 insertions, 35 deletions
diff --git a/scripts/sunrise-commit b/scripts/sunrise-commit index 06f17d98e..151abcb74 100755 --- a/scripts/sunrise-commit +++ b/scripts/sunrise-commit @@ -14,7 +14,19 @@ YELLOW=$WARN commit_category="$(pwd | awk -F/ '{ print $(NF-1) }')" commit_package="$(pwd | awk -F/ '{ print $NF }')" +current_svn_status=( ) cwd_is_ebuild_dir=0 +items_added=( ) +items_conflicted=( ) +items_deleted=( ) +items_ignored=( ) +items_missing=( ) +items_modified=( ) +items_not_modified=( ) +items_not_version_controlled=( ) +items_obstructed=( ) +items_replaced=( ) +items_used_by_externals=( ) num_new_dirs=0 opt_changelog=0 opt_noformat=0 @@ -22,10 +34,12 @@ opt_norepoman=0 opt_noupdate=0 opt_quiet=0 opt_verbose=0 +working_copy_base_dir="" changelog_append() { - if [[ "$opt_changelog" == "1" ]] ; then - if [[ "$(svn status)" =~ 'ChangeLog' ]] ; then + if [[ $opt_changelog == 1 ]] ; then + get_current_svn_status + if [[ "${current_svn_status[*]}" =~ 'ChangeLog' ]] ; then echo "!!! Error: Only one ChangeLog entry should be made per commit, and you have" echo "!!! already modified your ChangeLog locally since your last commit. To keep the" echo "!!! pre-existing modifications please run sunrise-commit again without the -c" @@ -39,8 +53,40 @@ changelog_append() { fi } +check_working_copy_base_dir() { + local num_dirs=0 + + # Ascend to nearest working copy dir in parent dirs + while ! get_current_svn_status ; do + if [[ "$(pwd)" == "$(dirs -l +1 2>&1)" ]] ; then + echo "!!! Error: No working copy found in parents of current directory." + echo "!!! sunrise-commit must be run from within a working copy tree." + exit 1 + fi + (( num_dirs++ )) + pushd .. >/dev/null + done + + # Ascend from there to nearest non-working copy dir in parent dirs + while get_current_svn_status ; do + if [[ "$(pwd)" == "$(dirs -l +1 2>&1)" ]] ; then + break + fi + (( num_dirs++ )) + pushd .. >/dev/null + done + + # Working copy base dir is previous dir on stack + popd >/dev/null && (( num_dirs-- )) + working_copy_base_dir="$(pwd)" + + for (( i=num_dirs ; i > 0 ; i-- )) ; do + popd >/dev/null + done +} + create_digests() { - if [[ "$cwd_is_ebuild_dir" == "1" ]] ; then + if [[ $cwd_is_ebuild_dir == 1 ]] ; then ebegin "Digesting ebuilds" for i in *.ebuild ; do ebuild $i digest @@ -49,36 +95,106 @@ create_digests() { fi } +# Sort current changed items into arrays based on symbols in `svn status` +# output. For now we're only concerned with the symbols in the first column of +# the output. See `svn help status` for symbol definitions. +# +# Returns with exit status 1 if the current dir isn't under version control. +get_current_svn_status() { + local IFS_SAVED="$IFS" + local item column_1 #column_2 column_3 column_4 column_5 column_6 + IFS=$'\n' + current_svn_status=( ) + items_added=( ) + items_conflicted=( ) + items_deleted=( ) + items_ignored=( ) + items_missing=( ) + items_modified=( ) + items_not_modified=( ) + items_not_version_controlled=( ) + items_obstructed=( ) + items_replaced=( ) + items_used_by_externals=( ) + for line in $(svn status 2>&1) ; do + [[ "$line" =~ 'is not a working copy' ]] && return 1 + current_svn_status[${#current_svn_status[*]}]=$line + column_1=${line:0:1} + #column_2=${line:1:1} + #column_3=${line:2:1} + #column_4=${line:3:1} + #column_5=${line:4:1} + #column_6=${line:5:1} + item=${line:7} + case $column_1 in + ' ') items_not_modified[${#items_not_modified[*]}]=$item ;; + A) items_added[${#items_added[*]}]=$item ;; + C) items_conflicted[${#items_conflicted[*]}]=$item ;; + D) items_deleted[${#items_deleted[*]}]=$item ;; + I) items_ignored[${#items_ignored[*]}]=$item ;; + M) items_modified[${#items_modified[*]}]=$item ;; + R) items_replaced[${#items_replaced[*]}]=$item ;; + X) items_used_by_externals[${#items_used_by_externals[*]}]=$item ;; + !) items_missing[${#items_missing[*]}]=$item ;; + ?) items_not_version_controlled[${#items_not_version_controlled[*]}]=$item ;; + ~) items_obstructed[${#items_obstructed[*]}]=$item ;; + esac + done + IFS="$IFS_SAVED" +} + repoman_check() { - if [[ "$opt_norepoman" == "0" ]] ; then - if [[ "$cwd_is_ebuild_dir" == "1" ]] ; then + if [[ $opt_norepoman == 0 ]] ; then + if [[ $cwd_is_ebuild_dir == 1 ]] ; then ebegin "Running repoman" - export PORTDIR_OVERLAY="$(dirname $(dirname $(pwd)))" + export PORTDIR_OVERLAY="$working_copy_base_dir" repoman eend $? fi - return $? fi } svn_add() { + local num_unversioned_dirs=0 + + while ! get_current_svn_status ; do + (( num_unversioned_dirs++ )) + pushd .. >/dev/null + done + ebegin "Adding local changes to working copy" - if [[ "$opt_verbose" == "1" ]] ; then - svn add ../$(basename `pwd`) --force - else - svn add ../$(basename `pwd`) --force -q + if [[ ${#items_not_version_controlled[*]} > 0 ]] ; then + if [[ $opt_verbose == 1 ]] ; then + svn add "${items_not_version_controlled[@]}" || set $? + else + svn add -q "${items_not_version_controlled[@]}" || set $? + fi fi - eend $? + eend ${1:-0} + + num_new_dirs=$num_unversioned_dirs + + for (( i=num_unversioned_dirs ; i > 0 ; i-- )) ; do + popd >/dev/null + done + + return ${1:-0} } svn_commit() { local commit_message="$*" - if [[ "$opt_noformat" == "0" ]] ; then - if [[ "$cwd_is_ebuild_dir" == "1" ]] ; then + get_current_svn_status + if [[ ${#current_svn_status[*]} == 0 ]] ; then + echo "!!! Error: No working copy changes found in current directory. Aborting commit." + exit 1 + fi + + if [[ $opt_noformat == 0 ]] ; then + if [[ $cwd_is_ebuild_dir == 1 ]] ; then commit_message="${commit_category}/${commit_package}: ${commit_message}" else - commit_message="${commit_package}/$(echo `svn status` | awk '{ print $2 }'): ${commit_message}" + commit_message="${commit_package}/${current_svn_status[0]:7}: ${commit_message}" fi fi @@ -89,13 +205,18 @@ svn_commit() { echo echo "${DARKGREEN}The following local changes will be committed to the repository:${NORMAL}" echo - svn status + + get_current_svn_status + for item in "${current_svn_status[@]}" ; do + echo "$item" + done + echo echo "${DARKGREEN}The following commit message will be used:${NORMAL}" echo echo "$commit_message" - if [[ "$opt_quiet" == "0" ]] ; then + if [[ $opt_quiet == 0 ]] ; then echo echo -n "${BOLD}Commit changes?${NORMAL} [${GREEN}Yes${NORMAL}/${RED}No${NORMAL}] " read choice @@ -118,14 +239,14 @@ svn_commit() { } svn_up() { - if [[ "$opt_noupdate" == "0" ]] ; then + if [[ $opt_noupdate == 0 ]] ; then for (( i=num_new_dirs ; i > 0 ; i-- )) ; do pushd .. >/dev/null done ebegin "Updating working copy to latest version from repository" - if [[ "$opt_verbose" == "1" ]] ; then + if [[ $opt_verbose == 1 ]] ; then svn update || set $? else svn update -q || set $? @@ -137,15 +258,15 @@ svn_up() { popd >/dev/null done - local conflict_files=$(svn status | sed -rn 's/^C.+ ([^ ]+)$/\1/p') - if [[ -n "$conflict_files" ]] ; then - echo "!!! Error: Some local files have changes that conflict with the latest" - echo "!!! revisions in the repository. Please contact the previous committer(s) to" - echo "!!! resolve the conflicts manually before running sunrise-commit again:" - for filename in $conflict_files ; do + get_current_svn_status + if [[ ${#items_conflicted[*]} > 0 ]] ; then + echo "!!! Error: Some local items have changes that conflict with the repository." + echo "!!! Please contact the most recent committer(s) of these items and resolve the" + echo "!!! conflicts manually before running sunrise-commit again:" + for item in "${items_conflicted[@]}" ; do echo "!!!" - echo "!!! file: ${filename}" - echo "!!! committer: $(svn info ${filename} | sed -rn 's/Last Changed Author\: (.*)$/\1/p')" + echo "!!! item: ${item}" + echo "!!! committer: $(svn info ${item} | sed -rn 's/Last Changed Author\: (.*)$/\1/p')" done exit 1 fi @@ -223,10 +344,11 @@ if [[ -z "$*" ]] ; then exit 1 fi +check_working_copy_base_dir [[ "$(ls)" =~ '\.ebuild' ]] && cwd_is_ebuild_dir=1 pushd . >/dev/null -while [[ "$(echo `svn status`)" =~ 'A.+? \.' ]] ; do +while [[ "$(echo `svn status 2>&1`)" =~ 'A.+? \.' ]] ; do (( num_new_dirs++ )) cd .. done @@ -234,16 +356,10 @@ popd >/dev/null svn_up || exit $? -[[ "$cwd_is_ebuild_dir" == "1" && ! -e metadata.xml ]] && cp ../../skel.metadata.xml metadata.xml >/dev/null 2>&1 +[[ $cwd_is_ebuild_dir == 1 && ! -e metadata.xml ]] && cp ../../skel.metadata.xml metadata.xml >/dev/null 2>&1 changelog_append "$*" || exit $? create_digests || exit $? svn_add || exit $? - -if [[ -z "$(svn status)" ]] ; then - echo "!!! Error: No changes found in current directory tree. Aborting commit." - exit 1 -fi - repoman_check || exit $? svn_commit "$*" || exit $? |