#!/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 "${@}" exit 1 } sayv() { [ -n "${SC_VERBOSE}" ] && say "${@}" } 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), -v, --verbose enable verbose output. _EOH_ } # Guess what! main() { local commitmsg 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. ;; -v|--verbose) SC_VERBOSE=1 ;; --) shift commitmsg="${commitmsg+${commitmsg} }${@}" break ;; *) commitmsg="${commitmsg+${commitmsg} }${1}" ;; esac shift done [ -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. [ ! -f ChangeLog -a -z "${bns}" ] && die 'Please supply the bug number in the initial commit message!' sayv '...and appending to it.' req echangelog "${commitmsg}" if [ -n "${bns}" ]; then echo local bn for bn in ${bns}; do wget -q http://bugs.gentoo.org/show_bug.cgi?id=${bn} -O - \ | sed -e 's; *Gentoo Bug \([0-9]*\) - \(.*\);Bug \1: \2;p' \ -e "s; *Gentoo \(Invalid Bug ID\);Bug ${bn}: !! \1;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 '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'." say while true; do local answ printf '%s' 'Commit changes? [Yes/No] ' >&2 read answ 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 "${@}"