Skip to content

Instantly share code, notes, and snippets.

@evertlammerts
Last active November 21, 2016 19:37
Show Gist options
  • Save evertlammerts/733b6282fc59b95ca1ae5e107c70b0a5 to your computer and use it in GitHub Desktop.
Save evertlammerts/733b6282fc59b95ca1ae5e107c70b0a5 to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script uses Hub (https://hub.github.com/) to create pull requests for
# multiple repositories
# Print usage (doesn't exit)
usage() {
echo
echo "update -g NAME -e EXEC -r REMOTE -c CMSG -p PRMSG REPO [...]"
echo
echo "Required:"
echo "-g|--githubuser NAME: name of the user or organisation owning the repo's"
echo "-e|--execute CMD: command to execute, will be run from each repo's working dir"
echo "-r|--remote REMOTE: name of the remote used for the fork, ie github username"
echo "-c|--commitmsg CMSG: commit message"
echo "-p|--prmsg PRMSG: PR message"
echo
echo "Optional:"
echo "-h|--help: display this help and exit"
echo
}
# Prints a message to stderr and exits
error() {
>&2 echo
>&2 echo "ERROR: $@"
>&2 echo
exit 1
}
# Silent version of pushd
pshd() {
pushd $@ > /dev/null
}
# Silent version of popd
ppd() {
popd > /dev/null
}
# Make sure our tmpdir is cleaned up no matter which way we exit
cleanup() {
rm -rf $UTMPDIR $TMPSTDOUT $TMPSTDERR
}
trap cleanup EXIT
# Parse all CLI arguments (http://stackoverflow.com/a/14203146/1455774)
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-h|--help)
usage
exit
;;
-g|--githubuser)
GHUSER="${2}"
shift
;;
-e|--execute)
EXEC="${2}"
shift
;;
-r|--remote)
REMOTE="${2}"
shift
;;
-c|--commitmsg)
CMSG="${2}"
shift
;;
-p|--prmsg)
PMSG="${2}"
shift
;;
*)
break
;;
esac
shift
done
# Bail out if the required options aren't set
[ -z ${GHUSER+x} ] && usage && error "Must provide a github user- or orgname (-g)"
[ -z ${EXEC+x} ] && usage && error "Must provide a command to execute (-e)"
[ -z ${REMOTE+x} ] && usage && error "Must provide a git remote name (-r)"
[ -z ${CMSG+x} ] && usage && error "Must provide a commit message (-c)"
[ -z ${PMSG+x} ] && usage && error "Must provide a pull request message (-p)"
# Create a temp dir and files for stdout and stderr...
UTMPDIR=$( mktemp -d )
TMPSTDOUT=$( mktemp )
TMPSTDERR=$( mktemp )
# ... and make sure it worked (if tmpdir worked I believe tmpstdout & tmpstderr)
[ $? -ne 0 ] && error "Couldn't create a tempdir! Something wrong with your file system?"
# Save the repositories
REPOS="$@"
# Let's first clone the repositories
for repo in $REPOS; do
hub clone https://github.com/${GHUSER}/${repo}.git $UTMPDIR/$repo > $TMPSTDOUT 2> $TMPSTDERR
[ $? -ne 0 ] && cat $TMPSTDERR && error "Couldn't clone ${repo}"
done
# If that went well, let's try to make some changes
for repo in $REPOS; do
pshd $UTMPDIR/$repo
$EXEC
ec=$?
ppd
[ $ec -ne 0 ] && error "Something went wrong running '$EXEC' on $repo"
done
# Check which repositories are changed and remove those which aren't
MODREPOS=""
for repo in $REPOS; do
pshd $UTMPDIR/$repo
( [ -z "$(hub diff)" ] && rm -rf $UTMPDIR/$repo ) || MODREPOS="$MODREPOS $repo"
ppd
done
# Quit if not changes have been made
[ -z "${MODREPOS}" ] && echo "No changes have been made" && exit 0
# Ask the user whether we should really make PR's for the changed repo's
read -p "Should I create PR's for changes made in${MODREPOS}? [y|n]: " -r dopr
echo
if [[ $dopr =~ ^[Yy]$ ]]; then
PRS=''
FAILED=''
echo '============== COMMIT, FORK, PUSH, PR ================'
for repo in $MODREPOS; do
echo
echo '+++++++++++++++++++' $repo '++++++++++++++++++++'
echo
pshd $UTMPDIR/$repo
hub commit -am "$CMSG" > $TMPSTDOUT 2> $TMPSTDERR
[ $? -ne 0 ] && FAILED="$FAILED $repo" && cat $TMPSTDERR && continue
hub fork > $TMPSTDOUT 2> $TMPSTDERR
[ $? -ne 0 ] && FAILED="$FAILED $repo" && cat $TMPSTDERR && continue
hub push ${REMOTE} master > $TMPSTDOUT 2> $TMPSTDERR
[ $? -ne 0 ] && FAILED="$FAILED $repo" && cat $TMPSTDERR && continue
PRS="$PRS $( hub pull-request -m "$PMSG" 2> $TMPSTDERR )"
[ $? -ne 0 ] && FAILED="$FAILED $repo" && cat $TMPSTDERR && continue
done
echo
echo '================= DONE ====================='
echo
echo "Created PR's:"
for pr in $PRS; do
echo $pr
done
echo
if [ -n "$FAILED" ]; then
echo "FAILED (SEE LOGS ABOVE):"
echo $FAILED
echo
fi
exit
fi
echo 'Cancelled'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment