diff --git a/sunrise-commit b/sunrise-commit index 6b33a7e..77281e9 100755 --- a/sunrise-commit +++ b/sunrise-commit @@ -1,35 +1,45 @@ #!/bin/sh -# sunrise-commit -- a helper script for Sunrise commiters. +# sunrise-commit -- commit changes to the Sunrise overlay. # (c) 2010 Michał Górny # Released under the terms of the 3-clause BSD license. -# Few output helpers. +# -- output helpers -- + +# Output the message to STDERR. say() { echo "${@}" >&2 } +# Output the error message and abort the script with non-zero status. die() { say "${RED}${@}${RESET}" exit 1 } +# Output the debug message if --verbose was used. sayv() { [ -n "${SC_VERBOSE}" ] && say "${GREEN}${@}${RESET}" } +# Execute the command and die with simple error message if it fails. req() { - "$@" || die "$@ failed." + "$@" || die "'$@' failed." } -# POSIX compat. +# -- POSIX compat -- + +# Check whether 'local' is supported. local_supported() { - local test 2>/dev/null + PATH= local test 2>/dev/null } +# If it is not, declare dummy local() function unsetting the variables. local_supported || eval 'local() { - unset ${@} + unset "${@}" }' +# -- 'look around' functions -- + # See if we're in a repo, and what VCS are we using. find_repo() { svn info >/dev/null 2>&1 @@ -55,6 +65,8 @@ find_repo() { sayv "Ok, we're in the ${SC_VCS} working tree. Let's see what I can do around here..." } +# Check whether a particular directory has been completely removed +# from the repo. is_whole_dir_removed() { if [ ${SC_VCS} = svn ]; then local flist @@ -93,7 +105,7 @@ is_package_removal() { return 0 } -# Look around for ebuilds. +# Look around for ebuilds; determine the scenario we're working on. find_ebuilds() { # POSIX is fun -- look for ebuilds in the current directory. if [ -n "$(find \( -name '*.ebuild' -print -o ! -name '.' -prune \))" ]; then @@ -143,7 +155,10 @@ find_ebuilds() { fi } -# VCS helpers. +# -- VCS helpers -- + +# Check whether a particular locations have changed, ignoring ChangeLog +# changes. check_for_changes() { local output @@ -158,16 +173,18 @@ check_for_changes() { echo "${output}" | grep -v ChangeLog >/dev/null } +# Discard any changes to a particular set of files. vcs_reset() { if [ ${SC_VCS%-svn} = git ]; then - req git reset -q HEAD "${1}" - git checkout -f "${1}" 2>/dev/null || req rm -f ChangeLog + req git reset -q HEAD "${@}" + git checkout -f "${@}" 2>/dev/null || req rm -f "${@}" elif [ ${SC_VCS} = svn ]; then - req rm -f ChangeLog - svn up ChangeLog >/dev/null 2>&1 + req rm -f "${@}" + svn up "${@}" >/dev/null 2>&1 fi } +# Request VCS to provide a verbose status report. vcs_status() { if [ ${SC_VCS%-svn} = git ]; then git status -s ${1-.} "${@}" @@ -176,10 +193,13 @@ vcs_status() { fi } +# Add particular files to the repository. vcs_add() { ${SC_VCS%-svn} add "$@" } +# Commit the specified objects using the commit message provided +# as the first argument. Does not return. vcs_commit() { local msg msg=${1} @@ -192,6 +212,7 @@ vcs_commit() { fi } +# Call VCS to update the working copy to HEAD revision. vcs_update() { # Unlike svn, git doesn't push the changes to origin immediately, # and that's why we don't force update to it right here. @@ -200,6 +221,7 @@ vcs_update() { fi } +# Print the help message. print_help() { cat <<_EOH_ Synopsis: @@ -220,6 +242,7 @@ Options: _EOH_ } +# Request confirmation before committing. Abort if it is not granted. confirm() { while true; do local answ @@ -245,6 +268,7 @@ main() { local commitmsg force monochrome noprepend noupdate trivial unset SC_VERBOSE + # Command-line parsing. while [ ${#} -gt 0 ]; do case "${1}" in --help|-\?|-h) @@ -295,6 +319,7 @@ main() { shift done + # Initialize colors. if [ -n "${monochrome}" ]; then RESET= RED= @@ -316,10 +341,13 @@ main() { [ -n "${commitmsg}" ] || die 'No commit message provided.' + # Look around. find_repo find_ebuilds case ${SC_SCENARIO} in + # Committing changes within the ebuild directory. + # This includes committing new ebuilds. ebuild-commit) check_for_changes || die 'No changes found to commit.' @@ -366,7 +394,23 @@ main() { vcs_status echo - # Do we have repoman new enough? + # Since commit 32264c3, repoman supports '--ask' option, + # which requests user confirmation before the commit. + # We like that, because it does it in the right place. + # + # If user is using earlier repoman version, we need to + # request that confirmation ourselves. As we would like + # the user to see 'repoman full' results first, we need + # to call it ourselves. Moreover, it requires Manifest to be + # up-to-date, so we need to call 'repoman manifest' too. + # + # That's pretty sad, because it means we're wasting time + # calling the same repoman functions twice (once manually, + # then within 'repoman commit'). That's why we would be + # happy if user updated his/her Portage, and we'd like to + # encourage him/her to do so -- but we'll have to delay that + # until a new Portage version is released. + local old_repoman repoman --version -a >/dev/null 2>&1 if [ $? -eq 2 ]; then @@ -389,6 +433,8 @@ main() { sayv "Now, let's let repoman do its job..." exec repoman commit ${old_repoman--a} ${force+-f} -m "${noprepend-${SC_CP}: }${commitmsg}" ;; + + # Clean removal of a package set. package-removal) vcs_status ${SC_CHANGE_LIST} echo @@ -401,6 +447,8 @@ main() { vcs_update ${SC_CHANGE_LIST} fi + # XXX: a consistency check on *DEPENDs, package.mask + vcs_commit "${noprepend-${SC_CP}: }${commitmsg}" ${SC_CHANGE_LIST} ;; esac