#!/bin/bash # sunrise-commit - Automates the Gentoo Sunrise Overlay commit process # Released into the public domain source /sbin/functions.sh BLUE=$BRACKET BOLD=$'\e[0;01m' DARKGREEN=$'\e[32m' GREEN=$GOOD LIGHTBLUE=$HILITE RED=$BAD YELLOW=$WARN commit_category="$(pwd | awk -F/ '{ print $(NF-1) }')" commit_package="$(pwd | awk -F/ '{ print $NF }')" cwd_is_ebuild_dir=0 num_new_dirs=0 opt_changelog=0 opt_noformat=0 opt_norepoman=0 opt_noupdate=0 opt_quiet=0 opt_verbose=0 changelog_append() { if [[ "$opt_changelog" == "1" ]] ; then if [[ "$(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" echo "!!! option. To discard the pre-existing modifications run:" echo "!!! svn revert ChangeLog" exit 1 fi ebegin "Appending/creating ChangeLog" echangelog "$*" eend $? fi } create_digests() { if [[ "$cwd_is_ebuild_dir" == "1" ]] ; then ebegin "Digesting ebuilds" for i in *.ebuild ; do ebuild $i digest done eend $? fi } repoman_check() { if [[ "$opt_norepoman" == "0" ]] ; then if [[ "$cwd_is_ebuild_dir" == "1" ]] ; then ebegin "Running repoman" export PORTDIR_OVERLAY="$(dirname $(dirname $(pwd)))" repoman eend $? fi return $? fi } svn_add() { ebegin "Adding local changes to working copy" if [[ "$opt_verbose" == "1" ]] ; then svn add ../$(basename `pwd`) --force else svn add ../$(basename `pwd`) --force -q fi eend $? } svn_commit() { local commit_message="$*" 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}" fi fi for (( i=num_new_dirs ; i > 0 ; i-- )) ; do cd .. done echo echo "${DARKGREEN}The following local changes will be committed to the repository:${NORMAL}" echo svn status echo echo "${DARKGREEN}The following commit message will be used:${NORMAL}" echo echo "$commit_message" if [[ "$opt_quiet" == "0" ]] ; then echo echo -n "${BOLD}Commit changes?${NORMAL} [${GREEN}Yes${NORMAL}/${RED}No${NORMAL}] " read choice echo case "$choice" in y*|Y*|"") ;; *) echo "Quitting." echo return 1 ;; esac fi ebegin "Committing working copy to repository" svn commit -m "$commit_message" eend $? } svn_up() { 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 svn update || set $? else svn update -q || set $? fi eend ${1:-0} for (( i=num_new_dirs ; i > 0 ; i-- )) ; do 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 echo "!!!" echo "!!! file: ${filename}" echo "!!! committer: $(svn info ${filename} | sed -rn 's/Last Changed Author\: (.*)$/\1/p')" done exit 1 fi fi return ${1:-0} } usage() { cat << EOF ${BOLD}Usage:${NORMAL} ${LIGHTBLUE}sunrise-commit${NORMAL} [ ${GREEN}options${NORMAL} ] ${BLUE}message${NORMAL} ${GREEN}options${NORMAL}: ${BOLD}--changelog, -c${NORMAL} Create a ChangeLog entry using ${BLUE}message${NORMAL} ${BOLD}--help, -h${NORMAL} Show help ${BOLD}--noformat, -m${NORMAL} Disable automatic formatting of ${BLUE}message${NORMAL} ${BOLD}--norepoman, -p${NORMAL} Skip repoman check ${BOLD}--noupdate, -d${NORMAL} Don't update from repository before committing ${BOLD}--quiet, -q${NORMAL} Don't ask for confirmation ${BOLD}--verbose, -v${NORMAL} Show detailed information during commit ${BLUE}message${NORMAL}: Commit message describing changes and listing names/emails of anyone (other than the commiter) who contributed. EOF exit ${1:-0} } [[ -z "$1" ]] && usage 1 while [[ $# > 0 ]] ; do case "$1" in --changelog|-c) if [[ -z "$ECHANGELOG_USER" ]] ; then echo "!!! Error: --changelog option requires ECHANGELOG_USER to be set:" echo "!!! export ECHANGELOG_USER=\"Your Name \"" exit 1 fi opt_changelog=1 shift ;; --help|-h) usage ;; --noformat|-m) opt_noformat=1 shift ;; --norepoman|-p) opt_norepoman=1 shift ;; --noupdate|-d) opt_noupdate=1 shift ;; --quiet|-q) opt_quiet=1 shift ;; --verbose|-v) opt_verbose=1 shift ;; -*) echo "!!! Error: Unknown option ${1}. See: sunrise-commit -h" exit 1 ;; *) break ;; esac done if [[ -z "$*" ]] ; then echo "!!! Error: You must supply a commit message. See: sunrise-commit -h" exit 1 fi [[ "$(ls)" =~ '\.ebuild' ]] && cwd_is_ebuild_dir=1 pushd . >/dev/null while [[ "$(echo `svn status`)" =~ 'A.+? \.' ]] ; do (( num_new_dirs++ )) cd .. done popd >/dev/null svn_up || exit $? [[ "$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 $?