| #!/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 |