blob: 3ac41445d24d65d1ee5d94bc662db844a30b025f [file] [log] [blame]
#!/bin/bash
# Copyright 2017 The Bazel Authors. All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
@@GENERATED_MESSAGE@@
set -euo pipefail
RUNNER_LABEL=@@RUNNER_LABEL@@
GAZELLE_SHORT_PATH=@@GAZELLE_SHORT_PATH@@
GAZELLE_LABEL=@@GAZELLE_LABEL@@
ARGS=@@ARGS@@
# find_repo_root prints the absolute path to the repository root. This is
# discovered by locating the WORKSPACE file in a parent directory, and
# deferencing symlinks. If no WORKSPACE file is found, this function prints
# an error and exits.
function find_repo_root {
pushd . &>/dev/null
while [ $(pwd) != / -a ! -f WORKSPACE ]; do
cd ..
done
if [ ! -f WORKSPACE ]; then
echo "error: could not find WORKSPACE file in any parent directory" >&2
exit 1
fi
if [ "$is_bazel_run" = true ]; then
dirname $(readlink WORKSPACE)
else
pwd
fi
popd &>/dev/null
}
# bazel_build_get_path builds a given target and prints the absolute path
# to the generated binary. This only works for rules that produce a single file.
function bazel_build_get_path {
local build_log=$(mktemp gazelle_build.XXXX.json --tmpdir)
bazel build --build_event_json_file="$build_log" "$1"
grep "^{\"id\":{\"targetCompleted\":{\"label\":\"$1\"" "$build_log" | \
sed -e 's!^.*file://\([^"]*\).*$!\1!'
rm -f "$build_log"
}
# Check whether the script was executed by Bazel. The gazelle macro prepends
# an argument that tells us this.
is_bazel_run=false
if [ "${1-}" = "-bazel_run" ]; then
is_bazel_run=true
shift
fi
# If arguments were provided on the command line, use those instead of the
# arguments generated by the rule.
if [ $# -ne 0 ]; then
ARGS=("$@")
fi
if [ "$is_bazel_run" = true ]; then
# If the script was invoked by "bazel run", jump out of the execroot, into
# the workspace before running Gazelle.
# TODO(jayconrod): detect when a command can't be run this way.
gazelle_short_path=$(readlink "$GAZELLE_SHORT_PATH")
cd $(find_repo_root)
"$gazelle_short_path" "${ARGS[@]}"
else
# If the script was invoked directly, check whether the script is out of
# date before proceeding.
new_runner_script=$(bazel_build_get_path "$RUNNER_LABEL")
if ! diff "$new_runner_script" "$0" &>/dev/null; then
cat - >&2 <<EOF
error: $0: script is out of date. Refresh it with the command:
bazel build $RUNNER_LABEL && cp -fv "$new_runner_script" "$0"
EOF
exit 1
fi
# Rebuild and run Gazelle.
gazelle_exe=$(bazel_build_get_path "$GAZELLE_LABEL")
"$gazelle_exe" "${ARGS[@]}"
fi