Skip to content

Commit

Permalink
Improve Gazelle launcher's runfiles discovery on Windows
Browse files Browse the repository at this point in the history
The Bash runfiles library consumes paths of the form
`repo/path/to/pkg/file` and is more reliable than the custom runfiles
discovery function.

Co-authored-by: Shashank <[email protected]>
  • Loading branch information
fmeum and shashankjpmc committed Aug 14, 2023
1 parent 18e0fd3 commit 2d5bb50
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 31 deletions.
15 changes: 10 additions & 5 deletions def.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ def _valid_env_variable_name(name):
return False
return True

def _rlocation_path(ctx, file):
if file.short_path.startswith("../"):
return file.short_path[3:]
else:
return ctx.workspace_name + "/" + file.short_path

def _gazelle_runner_impl(ctx):
args = [ctx.attr.command]
if ctx.attr.mode:
Expand All @@ -88,16 +94,14 @@ def _gazelle_runner_impl(ctx):
repo_config = ctx.file._repo_config
substitutions = {
"@@ARGS@@": shell.array_literal(args),
"@@GAZELLE_LABEL@@": shell.quote(str(ctx.attr.gazelle.label)),
"@@GAZELLE_SHORT_PATH@@": shell.quote(ctx.executable.gazelle.short_path),
"@@GAZELLE_PATH@@": shell.quote(_rlocation_path(ctx, ctx.executable.gazelle)),
"@@GENERATED_MESSAGE@@": """
# Generated by {label}
# DO NOT EDIT
""".format(label = str(ctx.label)),
"@@RUNNER_LABEL@@": shell.quote(str(ctx.label)),
"@@GOTOOL@@": shell.quote(go_tool.short_path),
"@@GOTOOL@@": shell.quote(_rlocation_path(ctx, go_tool)),
"@@ENV@@": env,
"@@REPO_CONFIG_SHORT_PATH@@": shell.quote(repo_config.short_path) if repo_config else "",
"@@REPO_CONFIG_PATH@@": shell.quote(_rlocation_path(ctx, repo_config)) if repo_config else "",
}
ctx.actions.expand_template(
template = ctx.file._template,
Expand Down Expand Up @@ -186,5 +190,6 @@ def gazelle(name, **kwargs):
srcs = [runner_name],
tags = tags,
visibility = visibility,
deps = ["@bazel_tools//tools/bash/runfiles"],
data = kwargs["data"] if "data" in kwargs else [],
)
45 changes: 19 additions & 26 deletions internal/gazelle.bash.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,34 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# --- begin runfiles.bash initialization v3 ---
# Copy-pasted from the Bazel Bash runfiles library v3.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v3 ---

@@GENERATED_MESSAGE@@

set -euo pipefail

RUNNER_LABEL=@@RUNNER_LABEL@@
GAZELLE_SHORT_PATH=@@GAZELLE_SHORT_PATH@@
GAZELLE_LABEL=@@GAZELLE_LABEL@@
GAZELLE_PATH=@@GAZELLE_PATH@@
ARGS=@@ARGS@@
GOTOOL=@@GOTOOL@@
REPO_CONFIG_SHORT_PATH=@@REPO_CONFIG_SHORT_PATH@@
REPO_CONFIG_PATH=@@REPO_CONFIG_PATH@@

@@ENV@@

# find_runfile prints the location of a runfile in the source workspace,
# either by reading the symbolic link or reading the runfiles manifest.
function find_runfile {
local runfile=$1
if [ -f "$runfile" ]; then
readlink "$runfile"
return
fi
runfile=${runfile#external/}
if grep -q "^$runfile" "$0.runfiles_manifest"; then
grep "^$runfile" "$0.runfiles_manifest" | head -n 1 | cut -d' ' -f2
return
fi
# printing nothing indicates failure
}

# set_goroot attempts to set GOROOT to the SDK used by rules_go. gazelle
# invokes tools inside the Go SDK for dependency management. It's good to
# use the SDK used by the workspace in case the Go SDK is not installed
# on the host system or is a different version.
function set_goroot {
local gotool=$(find_runfile "$GOTOOL")
local gotool=$(rlocation "$GOTOOL")
if [ -z "$gotool" ]; then
echo "$0: warning: could not locate GOROOT used by rules_go" >&2
return
Expand Down Expand Up @@ -76,8 +69,8 @@ esac
# able to find runfiles, and some extensions rely on that. Gazelle can use
# BUILD_WORKSPACE_DIRECTORY to interpret relative paths on the command line.
set_goroot
gazelle_short_path=$(find_runfile "$GAZELLE_SHORT_PATH")
if [ -z "$gazelle_short_path" ]; then
gazelle_path=$(rlocation "$GAZELLE_PATH")
if [ -z "$gazelle_path" ]; then
echo "error: could not locate gazelle binary" >&2
exit 1
fi
Expand All @@ -101,8 +94,8 @@ fi
# When running with Bzlmod, there is no WORKSPACE file for Gazelle to read
# the definitions of go_repository rules from. Instead, we pass the path to
# the repo config file as a flag.
if [[ "${is_fix_or_update:-}" == "true" ]] && [[ -n $REPO_CONFIG_SHORT_PATH ]]; then
ARGS=("${ARGS[0]}" "-repo_config" "$(find_runfile "$REPO_CONFIG_SHORT_PATH")" "${ARGS[@]:1}")
if [[ "${is_fix_or_update:-}" == "true" ]] && [[ -n $REPO_CONFIG_PATH ]]; then
ARGS=("${ARGS[0]}" "-repo_config" "$(rlocation "$REPO_CONFIG_PATH")" "${ARGS[@]:1}")
fi

"$gazelle_short_path" "${ARGS[@]}"
"$gazelle_path" "${ARGS[@]}"

0 comments on commit 2d5bb50

Please sign in to comment.