diff --git a/rules/files.bzl b/rules/files.bzl index 9be958095ef2f..2262fb3dce107 100644 --- a/rules/files.bzl +++ b/rules/files.bzl @@ -67,6 +67,17 @@ def _copy_files(ctx): files.append(file) out_file = ctx.actions.declare_file(ctx.label.name + ".bash") + + relative_to_path = ctx.file.relative_to.short_path + if relative_to_path.startswith("../"): + runfile_path = relative_to_path[3:] + else: + workspace_name = ctx.workspace_name + if workspace_name: + runfile_path = workspace_name + "/" + relative_to_path + else: + runfile_path = relative_to_path + substitutions = { # This is maybe a bit naughty: we rely on the fact that the `package` # portion of the `relative_to` label looks just like the dirname @@ -75,6 +86,7 @@ def _copy_files(ctx): "__DEST__": ctx.attr.relative_to.label.package, "__FILES__": " ".join([f.path for f in files]), "__WORKSPACE__": ctx.attr.workspace_env, + "__RELATIVE_TO_RUNFILE__": runfile_path, } ctx.actions.expand_template( template = ctx.file._runner, @@ -84,7 +96,7 @@ def _copy_files(ctx): ) return [DefaultInfo( - runfiles = ctx.runfiles(files = files), + runfiles = ctx.runfiles(files = files + [ctx.file.relative_to]), executable = out_file, )] diff --git a/rules/scripts/copy_files.template.sh b/rules/scripts/copy_files.template.sh index c81afea02d8cd..7460267e9c1fb 100644 --- a/rules/scripts/copy_files.template.sh +++ b/rules/scripts/copy_files.template.sh @@ -7,29 +7,43 @@ DEST="__DEST__" FILES=(__FILES__) -# Change directory into the root of the project. -if [[ ! -z "${BUILD_WORKSPACE_DIRECTORY+is_set}" ]]; then - cd ${BUILD_WORKSPACE_DIRECTORY} || exit 1 +if [[ ! -z "${RUNFILES_DIR+is_set}" ]]; then + true +elif [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" else - echo "BUILD_WORKSPACE_DIRECTORY was not set." - echo "This rule should be executable and invoked with 'bazel run'." + echo "Could not find runfiles directory." exit 1 fi -# Since we may be building resources in an externally attached workspace, -# determine the real path to that workspace. -if [[ -z "${__WORKSPACE__+is_set}" ]]; then - echo "__WORKSPACE__ was not set." +RUNFILES_DIR="$(realpath "$RUNFILES_DIR")" + +RELATIVE_TO_RUNFILE="__RELATIVE_TO_RUNFILE__" +RELATIVE_TO_PATH="$RUNFILES_DIR/$RELATIVE_TO_RUNFILE" + +if [[ ! -f "$RELATIVE_TO_PATH" ]]; then + echo "Could not find relative_to file in runfiles: $RELATIVE_TO_PATH" exit 1 fi -WORKSPACE="$(realpath "${__WORKSPACE__}")" -if [[ ! -d "$WORKSPACE" ]]; then - echo "$WORKSPACE isn't a directory." +RESOLVED_PATH="$(realpath "$RELATIVE_TO_PATH")" +DEST_DIR="$(dirname "$RESOLVED_PATH")" + +if [[ ! -d "$DEST_DIR" ]]; then + echo "Destination directory does not exist: $DEST_DIR" + exit 1 +fi + +# Change directory into the root of the project. +if [[ ! -z "${BUILD_WORKSPACE_DIRECTORY+is_set}" ]]; then + cd ${BUILD_WORKSPACE_DIRECTORY} || exit 1 +else + echo "BUILD_WORKSPACE_DIRECTORY was not set." + echo "This rule should be executable and invoked with 'bazel run'." exit 1 fi # Copy the files from the source (e.g. bazel-out) to the destination. for f in "${FILES[@]}"; do - cp --no-preserve=mode "$f" "$WORKSPACE/$DEST" + cp --no-preserve=mode "$f" "$DEST_DIR" done