blob: 8d25015d899582434b35557bf54370f43dc21016 [file] [log] [blame]
#!/usr/bin/env bash
#########################################################################
##
## Buck wrapper script to invoke okbuck when needed, before running buck
##
## Created by OkBuck Gradle Plugin on : Tue May 30 14:39:04 PDT 2017
##
#########################################################################
WORKING_DIR=$(pwd)
red=`tput setab 1 2>/dev/null || true`
yellow=`tput setab 3 2>/dev/null || true`
green=`tput setab 2 2>/dev/null || true`
blue=`tput setab 4 2>/dev/null || true`
reset=`tput sgr0 2>/dev/null || true`
bold=`tput bold 2>/dev/null || true`
die ( ) {
echo
echo "${bold}${red} $* ${reset}"
echo
exit 1
}
info ( ) {
echo "${bold}${blue} $* ${reset}"
}
warn ( ) {
echo "${bold}${yellow} $* ${reset}"
}
success ( ) {
echo
echo "${bold}${green} $* ${reset}"
echo
}
ensure ( ) {
command -v $1 >/dev/null 2>&1 || die "ERROR: '$1' could be found in your PATH. Please install $1. $2"
}
jsonq() {
python -c "import sys,json; obj=json.load(sys.stdin); print($1)"
}
ensure python 'https://www.python.org'
ensure ant 'http://ant.apache.org/'
INSTALLED_WATCHMAN=`command -v watchman`
DEFAULT_BUCK_REPO="https://github.com/facebook/buck.git"
DEFAULT_BUCK_INSTALL_DIR="$HOME/.gradle/caches/okbuck/buck"
CUSTOM_BUCK_REPO=""
CUSTOM_REMOTE_NAME="custom"
OKBUCK_SUCCESS="$WORKING_DIR/build/okbuck.success"
OKBUCK_DIR="$WORKING_DIR/.okbuck"
MAX_DISPLAY_CHANGES=10
ensureWatch ( ) {
watchman watch-project $WORKING_DIR >/dev/null 2>&1
}
getChanges ( ) {
ensureWatch
WATCHED_CHANGES=`watchman --output-encoding=json --no-pretty -j 2>&1 <<-EOT
["query", "$WORKING_DIR", {
"since": "n:okbuck_trig",
"expression": ["allof",
["type", "f"],
["anyof",
["suffix", "gradle"],
["name", ["gradle-wrapper.properties", "lint.xml"]],
["match", "**/src/**/AndroidManifest.xml", "wholename"]
],
["not",
["dirname", ".okbuck"]
]
],
"fields": ["name"]
}]
EOT`
SOURCE_ROOTS=`watchman --output-encoding=json --no-pretty -j 2>&1 <<-EOT
["query", "$WORKING_DIR", {
"since": "n:okbuck_source_roots",
"expression": ["allof",
["type", "d"],
["anyof",
["match", "**/src/**/java", "wholename"],
["match", "**/src/**/res", "wholename"],
["match", "**/src/**/resources", "wholename"]
],
["not",
["dirname", ".okbuck"]
]
],
"fields": ["new", "exists", "name"]
}]
EOT`
}
updateOkBuckSuccess ( ) {
OKBUCK_SUCCESS_DIR=`dirname $OKBUCK_SUCCESS`
mkdir -p $OKBUCK_SUCCESS_DIR
touch "$OKBUCK_SUCCESS"
}
runOkBuck ( ) {
info "RUNNING OKBUCK..."
echo
rm -f $OKBUCK_SUCCESS
( $WORKING_DIR/gradlew -p $WORKING_DIR okbuck -Dokbuck.wrapper=true $EXTRA_OKBUCK_ARGS &&
updateOkBuckSuccess && success "PROCEEDING WITH BUCK" ) || die "OKBUCK FAILED"
}
watchmanWorkflow ( ) {
# Get list of changed files since last time by querying watchman
getChanges
# Format list for simpler output
CHANGES=$(echo $WATCHED_CHANGES | jsonq '" ".join(obj["files"])')
NEW_OR_DELETED_SOURCE_ROOTS=$(echo $SOURCE_ROOTS | jsonq '" ".join([f["name"] for f in obj["files"] if (not f["exists"] or f["new"])])')
NUM_CHANGES=$(echo $CHANGES $NEW_OR_DELETED_SOURCE_ROOTS | wc -w)
if [[ $NUM_CHANGES -gt 0 ]]; then
info "CHANGES DETECTED IN:"
echo $CHANGES $NEW_OR_DELETED_SOURCE_ROOTS | tr ' ' '\n' | head -n $MAX_DISPLAY_CHANGES
if [[ $NUM_CHANGES -gt $MAX_DISPLAY_CHANGES ]]; then
DIFF=`expr $NUM_CHANGES - $MAX_DISPLAY_CHANGES`
echo "...and $DIFF more"
fi
echo
runOkBuck
fi
}
setupBuckBinary ( ) {
# If no explicit buck binary is set
if [[ -z "$BUCK_BINARY" ]] ; then
# If no buck installation directory is set
if [[ -z "$BUCK_HOME" ]]; then
BUCK_HOME=$DEFAULT_BUCK_INSTALL_DIR
fi
# Install buck from source if not already available
if [[ ! -d "$BUCK_HOME" ]]; then
warn "BUCK NOT FOUND IN '$BUCK_HOME'. INSTALLING BUCK..."
git clone $DEFAULT_BUCK_REPO $BUCK_HOME
fi
# Add custom buck remote
if [[ ! -z $CUSTOM_BUCK_REPO ]]; then
cd $BUCK_HOME
REMOTE_EXISTS=$(git remote -v | grep "$CUSTOM_REMOTE_NAME")
if [[ -z "$REMOTE_EXISTS" ]]; then
git remote add $CUSTOM_REMOTE_NAME $CUSTOM_BUCK_REPO
fi
cd -
fi
BUCK_BINARY="$BUCK_HOME/bin/buck"
fi
}
# Run tasks before buck command
setupBuckRun ( ) {
if [[ ! -z "$SKIP_OKBUCK" ]]; then
:
elif [[ ! -z "$FORCE_OKBUCK" ]]; then
runOkBuck
elif [[ ! -f "$OKBUCK_SUCCESS" ]] || [[ ! -d "$OKBUCK_DIR" ]]; then
warn "NO PREVIOUS SUCCESSFUL OKBUCK RUN"
if [[ ! -z "$INSTALLED_WATCHMAN" ]]; then
getChanges # Prevent watchman from running after this run, since changes would already be accounted for
fi
runOkBuck
elif [[ ! -z "$INSTALLED_WATCHMAN" ]]; then
watchmanWorkflow
else
warn 'ALWAYS RUNNING OKBUCK SINCE WATCHMAN IS NOT INSTALLED'
warn 'INSTALL WATCHMAN FOR FASTER BUILDS'
warn 'https://facebook.github.io/watchman'
echo
runOkBuck
fi
setupBuckBinary
}
# Handle parameters and flags
handleParams ( ) {
# Go directly to kill. Do not run okbuck.
if [[ "kill" == $1 ]]; then
SKIP_OKBUCK=true
fi
}
handleParams "$@"
setupBuckRun
# Invoke buck binary with arguments
exec "$BUCK_BINARY" "$@"