#!/bin/sh # sunrise-commit -- a helper script for Sunrise commiters. # (c) 2010 Michał Górny # Released under the terms of the 3-clause BSD license. # Few output helpers. say() { echo "${@}" >&2 } die() { say "${RED}${@}${RESET}" exit 1 } sayv() { [ -n "${SC_VERBOSE}" ] && say "${GREEN}${@}${RESET}" } req() { "$@" || die "$@ failed." } # POSIX compat. local_supported() { local test 2>/dev/null } local_supported || eval 'local() { unset ${@} }' # See if we're in a repo, and what VCS are we using. find_repo() { svn info >/dev/null 2>&1 if [ ${?} -eq 0 ]; then SC_VCS=svn else local remotes remotes=$(git branch -r 2>/dev/null) if [ ${?} -ne 127 -a ${?} -ne 128 ]; then echo "${remotes}" | grep git-svn >/dev/null 2>&1 if [ ${?} -eq 0 ]; then SC_VCS=git-svn else SC_VCS=git fi else die 'Unable to find any familiar repository type (are you inside the repo?).' fi fi if [ ${SC_VCS} = svn ]; then die 'Native subversion repositories are not supported at the moment.' fi sayv "Ok, we're in ${SC_VCS} working tree. Let's see what I can do around here..." } # Look around for ebuilds. find_ebuilds() { # POSIX is fun -- look for ebuilds in the current directory. if [ -n "$(find \( -name '*.ebuild' -print -o ! -name '.' -prune \))" ]; then local stripped # Get CATEGORY and PN. stripped=${PWD%/*} stripped=${stripped%/*} SC_CP=${PWD#${stripped}/} SC_SCENARIO=ebuild-commit sayv "We have some ebuilds for ${SC_CP} here." else die 'No familar situation found -- no ebuilds here.' fi } # VCS helpers. check_for_changes() { local output if [ ${SC_VCS%-svn} = git ]; then output=$(git diff-index --name-only --relative HEAD) fi # We do not care about user mangling ChangeLog, we will reset it anyway. echo "${output}" | grep -v ChangeLog >/dev/null } vcs_reset() { if [ ${SC_VCS%-svn} = git ]; then req git reset -q HEAD "${1}" req git checkout -f "${1}" fi } vcs_status() { if [ ${SC_VCS%-svn} = git ]; then git status -s . fi } print_help() { cat <<_EOH_ Synopsis: sunrise-commit [options] [--] Options: -?, -h, --help print this message, -V, --version print version string, -c, --changelog backwards compat (ignored), -C, --nocolor disable colorful output, -t, --trivial trivial changes (do not add a ChangeLog entry), -v, --verbose enable verbose output. _EOH_ } # Guess what! main() { local commitmsg monochrome trivial unset SC_VERBOSE while [ ${#} -gt 0 ]; do case "${1}" in --help|-\?|-h) print_help exit 0 ;; --version|-V) echo 'sunrise-commit 1.0' exit 0 ;; -c|--changelog) # Now changelog entries are implicit -- backwards compat. ;; -C|--nocolor) monochrome=1 ;; -t|--trivial) trivial=1 ;; -v|--verbose) SC_VERBOSE=1 ;; --) shift commitmsg=${commitmsg+${commitmsg} }${@} break ;; *) commitmsg=${commitmsg+${commitmsg} }${1} ;; esac shift done if [ -n "${monochrome}" ]; then RESET= RED= GREEN= BGREEN= YELLOW= WHITE= else local esc esc=$(printf '\033[') RESET=${esc}0m RED="${esc}1;31m" GREEN=${esc}32m BGREEN="${esc}1;32m" YELLOW="${esc}1;33m" WHITE="${esc}1;37m" fi [ -n "${commitmsg}" ] || die 'No commit message provided.' find_repo find_ebuilds case ${SC_SCENARIO} in ebuild-commit) check_for_changes || die 'No changes found to commit.' # With native git repos, we do not do ChangeLogs by default... # ...at least unless they're already there. if [ ${SC_VCS} != git -o -f ChangeLog ]; then sayv 'Cleaning up the ChangeLog...' vcs_reset ChangeLog local bns # Let's take a lucky guess bugnumbers consist of 4+ digits. bns=$(echo "${commitmsg}" | grep -o -E '[0-9]{4,}') # Creating a new ChangeLog? Let's take a look at the commit message. if [ ! -f ChangeLog ]; then [ -n "${trivial}" ] && die "Trivial change for an initial commit? You're joking, right?" [ -z "${bns}" ] && die 'Please supply the bug number in the initial commit message!' fi if [ -z "${trivial}" ]; then sayv '...and appending to it.' req echangelog "${commitmsg}" echo fi if [ -n "${bns}" ]; then local bn cbn for bn in ${bns}; do cbn=#${WHITE}${bn}${NORMAL} wget -q http://bugs.gentoo.org/show_bug.cgi?id=${bn} -O - \ | sed -e "s, *Gentoo Bug \([0-9]*\) - \(.*\),Bug ${cbn}: ${BGREEN}\2${RESET},p" \ -e "s, *Gentoo \(Invalid Bug ID\),Bug ${cbn}: ${YELLOW}!! \1${RESET},p" -e d done echo fi fi vcs_status echo # Do we have repoman new enough? local old_repoman repoman --version -a >/dev/null 2>&1 if [ $? -eq 2 ]; then old_repoman= say "${GREEN}Please update portage to newer version in order to have repoman supporting" say "--ask option and thus delay the following question until after 'repoman full'.${RESET}" say while true; do local answ printf '%s' "${WHITE}Commit changes?${RESET} [${BGREEN}Yes${RESET}/${RED}No${RESET}] ${GREEN}" >&2 read answ printf '%s' "${RESET}" case "${answ}" in [yY]|[yY][eE]|[yY][eE][sS]) break ;; [nN]|[nN][oO]) die 'Aborting.' ;; *) say "Response '${answ}' not understood, try again." esac done fi sayv "Now, let's let repoman do its job..." exec repoman commit ${old_repoman--a} -m "${SC_CP}: ${commitmsg}" ;; esac } main "${@}"