diff --git a/.bazeliskrc b/.bazeliskrc deleted file mode 100644 index a28c887..0000000 --- a/.bazeliskrc +++ /dev/null @@ -1,2 +0,0 @@ -BAZELISK_BASE_URL=https://github.com/aspect-build/aspect-cli/releases/download -USE_BAZEL_VERSION=aspect/5.7.2 diff --git a/docs/copy_directory.md b/docs/copy_directory.md index 407124b..1adafd4 100644 --- a/docs/copy_directory.md +++ b/docs/copy_directory.md @@ -5,6 +5,10 @@ A rule that copies a directory to another place. The rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command on Windows (no Bash is required). +NB: See notes on [copy_file](./copy_file.md#choosing-execution-requirements) +regarding `execution_requirements` settings for remote execution. +These settings apply to the rules below as well. + @@ -42,7 +46,8 @@ for more context. ## copy_directory_bin_action
-copy_directory_bin_action(ctx, src, dst, copy_directory_bin, hardlink, verbose) +copy_directory_bin_action(ctx, src, dst, copy_directory_bin, hardlink, verbose, + override_execution_requirements)Factory function that creates an action to copy a directory from src to dst using a tool binary. @@ -65,5 +70,6 @@ within other rule implementations. | copy_directory_bin | Copy to directory tool binary. | none | | hardlink | Controls when to use hardlinks to files instead of making copies.
"auto"
|
| verbose | If true, prints out verbose logs to stdout | False
|
+| override_execution_requirements | specify execution_requirements for this action | None
|
diff --git a/docs/copy_file.md b/docs/copy_file.md
index 56d11f3..517795d 100644
--- a/docs/copy_file.md
+++ b/docs/copy_file.md
@@ -11,6 +11,40 @@ on Windows (no Bash is required).
This fork of bazel-skylib's copy_file adds DirectoryPathInfo support and allows multiple
copy_file in the same package.
+Choosing execution requirements
+-------------------------------
+
+Copy actions can be very numerous, especially when used on third-party dependency packages.
+
+By default, we set the `execution_requirements` of actions we spawn to be non-sandboxed and run
+locally, not reading or writing to a remote cache. For the typical user this is the fastest, because
+it avoids the overhead of creating a sandbox and making network calls for every file being copied.
+
+If you use Remote Execution and Build-without-the-bytes, then you'll want the copy action to
+occur on the remote machine instead, since the inputs and outputs stay in the cloud and don't need
+to be brought to the local machine where Bazel runs.
+
+Other reasons to allow copy actions to run remotely:
+- Bazel prints an annoying warning "[action] uses implicit fallback from sandbox to local, which is deprecated because it is not hermetic"
+- When the host and exec platforms have different architectures, toolchain resolution runs the wrong binary locally,
+ see https://github.com/aspect-build/bazel-lib/issues/466
+
+To disable our `copy_use_local_execution` flag, put this in your `.bazelrc` file:
+
+```
+# with Bazel 6.4 or greater:
+
+# Disable default for execution_requirements of copy actions
+common --@aspect_bazel_lib//lib:copy_use_local_execution=false
+
+# with Bazel 6.3 or earlier:
+
+# Disable default for execution_requirements of copy actions
+build --@aspect_bazel_lib//lib:copy_use_local_execution=false
+fetch --@aspect_bazel_lib//lib:copy_use_local_execution=false
+query --@aspect_bazel_lib//lib:copy_use_local_execution=false
+```
+
diff --git a/docs/copy_to_directory.md b/docs/copy_to_directory.md
index 36e23bd..db4f3a5 100644
--- a/docs/copy_to_directory.md
+++ b/docs/copy_to_directory.md
@@ -2,6 +2,10 @@
Copy files and directories to an output directory.
+NB: See notes on [copy_file](./copy_file.md#choosing-execution-requirements)
+regarding `execution_requirements` settings for remote execution.
+These settings apply to the rules below as well.
+
@@ -73,7 +77,8 @@ for more information on supported globbing patterns.
copy_to_directory_bin_action(ctx, name, dst, copy_to_directory_bin, files, targets, root_paths,
include_external_repositories, include_srcs_packages,
exclude_srcs_packages, include_srcs_patterns, exclude_srcs_patterns,
- replace_prefixes, allow_overwrites, hardlink, verbose)
+ replace_prefixes, allow_overwrites, hardlink, verbose,
+ override_execution_requirements)
Factory function to copy files to a directory using a tool binary.
@@ -106,6 +111,7 @@ other rule implementations where additional_files can also be passed in.
| allow_overwrites | If True, allow files to be overwritten if the same output file is copied to twice.False
|
| hardlink | Controls when to use hardlinks to files instead of making copies."auto"
|
| verbose | If true, prints out verbose logs to stdout | False
|
+| override_execution_requirements | specify execution_requirements for this action | None
|
diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel
index 3f1b134..5f3de32 100644
--- a/lib/BUILD.bazel
+++ b/lib/BUILD.bazel
@@ -1,6 +1,7 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("//lib:utils.bzl", "is_bzlmod_enabled")
+load("//lib/private:copy_common.bzl", "copy_options")
load("//lib/private:stamping.bzl", "stamp_build_setting")
# Ensure that users building their own rules can dep on our bzl_library targets for their stardoc
@@ -31,6 +32,29 @@ bool_flag(
build_setting_default = True if is_bzlmod_enabled() else False,
)
+# Users may set this flag with
+bool_flag(
+ name = "copy_use_local_execution",
+ build_setting_default = True,
+ visibility = ["//visibility:public"],
+)
+
+config_setting(
+ name = "copy_use_local_execution_setting",
+ flag_values = {
+ ":copy_use_local_execution": "true",
+ },
+)
+
+# Used in rules which spawn actions that copy files
+copy_options(
+ name = "copy_options",
+ copy_use_local_execution = select({
+ ":copy_use_local_execution_setting": True,
+ "//conditions:default": False,
+ }),
+)
+
toolchain_type(
name = "jq_toolchain_type",
)
diff --git a/lib/copy_directory.bzl b/lib/copy_directory.bzl
index 87f384e..1e68ec1 100644
--- a/lib/copy_directory.bzl
+++ b/lib/copy_directory.bzl
@@ -2,6 +2,10 @@
The rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command
on Windows (no Bash is required).
+
+NB: See notes on [copy_file](./copy_file.md#choosing-execution-requirements)
+regarding `execution_requirements` settings for remote execution.
+These settings apply to the rules below as well.
"""
load(
diff --git a/lib/copy_file.bzl b/lib/copy_file.bzl
index 12d4695..1f853d8 100644
--- a/lib/copy_file.bzl
+++ b/lib/copy_file.bzl
@@ -27,6 +27,40 @@ on Windows (no Bash is required).
This fork of bazel-skylib's copy_file adds DirectoryPathInfo support and allows multiple
copy_file in the same package.
+
+Choosing execution requirements
+-------------------------------
+
+Copy actions can be very numerous, especially when used on third-party dependency packages.
+
+By default, we set the `execution_requirements` of actions we spawn to be non-sandboxed and run
+locally, not reading or writing to a remote cache. For the typical user this is the fastest, because
+it avoids the overhead of creating a sandbox and making network calls for every file being copied.
+
+If you use Remote Execution and Build-without-the-bytes, then you'll want the copy action to
+occur on the remote machine instead, since the inputs and outputs stay in the cloud and don't need
+to be brought to the local machine where Bazel runs.
+
+Other reasons to allow copy actions to run remotely:
+- Bazel prints an annoying warning "[action] uses implicit fallback from sandbox to local, which is deprecated because it is not hermetic"
+- When the host and exec platforms have different architectures, toolchain resolution runs the wrong binary locally,
+ see https://github.com/aspect-build/bazel-lib/issues/466
+
+To disable our `copy_use_local_execution` flag, put this in your `.bazelrc` file:
+
+```
+# with Bazel 6.4 or greater:
+
+# Disable default for execution_requirements of copy actions
+common --@aspect_bazel_lib//lib:copy_use_local_execution=false
+
+# with Bazel 6.3 or earlier:
+
+# Disable default for execution_requirements of copy actions
+build --@aspect_bazel_lib//lib:copy_use_local_execution=false
+fetch --@aspect_bazel_lib//lib:copy_use_local_execution=false
+query --@aspect_bazel_lib//lib:copy_use_local_execution=false
+```
"""
load(
diff --git a/lib/copy_to_directory.bzl b/lib/copy_to_directory.bzl
index ef73f6d..197720d 100644
--- a/lib/copy_to_directory.bzl
+++ b/lib/copy_to_directory.bzl
@@ -1,4 +1,8 @@
"""Copy files and directories to an output directory.
+
+NB: See notes on [copy_file](./copy_file.md#choosing-execution-requirements)
+regarding `execution_requirements` settings for remote execution.
+These settings apply to the rules below as well.
"""
load(
diff --git a/lib/private/copy_common.bzl b/lib/private/copy_common.bzl
index aedb04a..b17d86f 100644
--- a/lib/private/copy_common.bzl
+++ b/lib/private/copy_common.bzl
@@ -1,7 +1,25 @@
"Helpers for copy rules"
-# Hints for Bazel spawn strategy
-COPY_EXECUTION_REQUIREMENTS = {
+CopyOptionsInfo = provider("Options for running copy actions", fields = ["execution_requirements"])
+
+def _copy_options_impl(ctx):
+ return CopyOptionsInfo(
+ execution_requirements = COPY_EXECUTION_REQUIREMENTS_LOCAL if ctx.attr.copy_use_local_execution else {},
+ )
+
+copy_options = rule(implementation = _copy_options_impl, attrs = {"copy_use_local_execution": attr.bool()})
+
+# Helper function to be used when creating an action
+def execution_requirements_for_copy(ctx):
+ if hasattr(ctx.attr, "_options") and CopyOptionsInfo in ctx.attr._options:
+ return ctx.attr._options[CopyOptionsInfo].execution_requirements
+
+ # If the rule ctx doesn't expose the CopyOptions, the default is to run locally
+ return COPY_EXECUTION_REQUIREMENTS_LOCAL
+
+# When applied to execution_requirements of an action, these prevent the action from being
+# sandboxed or remotely cached, for performance of builds that don't rely on RBE and build-without-bytes.
+COPY_EXECUTION_REQUIREMENTS_LOCAL = {
# ----------------+-----------------------------------------------------------------------------
# no-remote | Prevents the action or test from being executed remotely or cached remotely.
# | This is equivalent to using both `no-remote-cache` and `no-remote-exec`.
diff --git a/lib/private/copy_directory.bzl b/lib/private/copy_directory.bzl
index 5d15db9..9b548d4 100644
--- a/lib/private/copy_directory.bzl
+++ b/lib/private/copy_directory.bzl
@@ -4,7 +4,7 @@ This rule copies a directory to another location using Bash (on Linux/macOS) or
cmd.exe (on Windows).
"""
-load(":copy_common.bzl", _COPY_EXECUTION_REQUIREMENTS = "COPY_EXECUTION_REQUIREMENTS", _progress_path = "progress_path")
+load(":copy_common.bzl", "execution_requirements_for_copy", _progress_path = "progress_path")
def copy_directory_bin_action(
ctx,
@@ -12,7 +12,8 @@ def copy_directory_bin_action(
dst,
copy_directory_bin,
hardlink = "auto",
- verbose = False):
+ verbose = False,
+ override_execution_requirements = None):
"""Factory function that creates an action to copy a directory from src to dst using a tool binary.
The tool binary will typically be the `@aspect_bazel_lib//tools/copy_directory` `go_binary`
@@ -35,6 +36,8 @@ def copy_directory_bin_action(
See copy_directory rule documentation for more details.
verbose: If true, prints out verbose logs to stdout
+
+ override_execution_requirements: specify execution_requirements for this action
"""
args = [
src.path,
@@ -55,7 +58,7 @@ def copy_directory_bin_action(
arguments = args,
mnemonic = "CopyDirectory",
progress_message = "Copying directory %s" % _progress_path(src),
- execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
+ execution_requirements = override_execution_requirements or execution_requirements_for_copy(ctx),
)
def _copy_directory_impl(ctx):
@@ -93,6 +96,7 @@ _copy_directory = rule(
default = "auto",
),
"verbose": attr.bool(),
+ "_options": attr.label(default = "//lib:copy_options"),
# use '_tool' attribute for development only; do not commit with this attribute active since it
# propagates a dependency on rules_go which would be breaking for users
# "_tool": attr.label(
diff --git a/lib/private/copy_file.bzl b/lib/private/copy_file.bzl
index f474744..1b3355c 100644
--- a/lib/private/copy_file.bzl
+++ b/lib/private/copy_file.bzl
@@ -24,11 +24,11 @@ cmd.exe (on Windows). `_copy_xfile` marks the resulting file executable,
`_copy_file` does not.
"""
-load(":copy_common.bzl", _COPY_EXECUTION_REQUIREMENTS = "COPY_EXECUTION_REQUIREMENTS", _progress_path = "progress_path")
+load(":copy_common.bzl", "execution_requirements_for_copy", _progress_path = "progress_path")
load(":directory_path.bzl", "DirectoryPathInfo")
load(":platform_utils.bzl", _platform_utils = "platform_utils")
-def _copy_cmd(ctx, src, src_path, dst):
+def _copy_cmd(ctx, src, src_path, dst, override_execution_requirements = None):
# Most Windows binaries built with MSVC use a certain argument quoting
# scheme. Bazel uses that scheme too to quote arguments. However,
# cmd.exe uses different semantics, so Bazel's quoting is wrong here.
@@ -65,10 +65,10 @@ def _copy_cmd(ctx, src, src_path, dst):
mnemonic = mnemonic,
progress_message = progress_message,
use_default_shell_env = True,
- execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
+ execution_requirements = override_execution_requirements or execution_requirements_for_copy(ctx),
)
-def _copy_bash(ctx, src, src_path, dst):
+def _copy_bash(ctx, src, src_path, dst, override_execution_requirements = None):
cmd_tmpl = "cp -f \"$1\" \"$2\""
mnemonic = "CopyFile"
progress_message = "Copying file %s" % _progress_path(src)
@@ -81,7 +81,7 @@ def _copy_bash(ctx, src, src_path, dst):
mnemonic = mnemonic,
progress_message = progress_message,
use_default_shell_env = True,
- execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
+ execution_requirements = override_execution_requirements or execution_requirements_for_copy(ctx),
)
def copy_file_action(ctx, src, dst, dir_path = None):
@@ -154,6 +154,7 @@ _ATTRS = {
"is_executable": attr.bool(mandatory = True),
"allow_symlink": attr.bool(mandatory = True),
"out": attr.output(mandatory = True),
+ "_options": attr.label(default = "//lib:copy_options"),
}
_copy_file = rule(
diff --git a/lib/private/copy_to_directory.bzl b/lib/private/copy_to_directory.bzl
index 1bb265a..4a623cd 100644
--- a/lib/private/copy_to_directory.bzl
+++ b/lib/private/copy_to_directory.bzl
@@ -1,6 +1,6 @@
"copy_to_directory implementation"
-load(":copy_common.bzl", _COPY_EXECUTION_REQUIREMENTS = "COPY_EXECUTION_REQUIREMENTS", _progress_path = "progress_path")
+load(":copy_common.bzl", "execution_requirements_for_copy", _progress_path = "progress_path")
load(":directory_path.bzl", "DirectoryPathInfo")
load(":paths.bzl", "paths")
@@ -254,6 +254,7 @@ _copy_to_directory_attr = {
"verbose": attr.bool(
doc = _copy_to_directory_attr_doc["verbose"],
),
+ "_options": attr.label(default = "//lib:copy_options"),
# use '_tool' attribute for development only; do not commit with this attribute active since it
# propagates a dependency on rules_go which would be breaking for users
# "_tool": attr.label(
@@ -324,7 +325,8 @@ def copy_to_directory_bin_action(
replace_prefixes = {},
allow_overwrites = False,
hardlink = "auto",
- verbose = False):
+ verbose = False,
+ override_execution_requirements = None):
"""Factory function to copy files to a directory using a tool binary.
The tool binary will typically be the `@aspect_bazel_lib//tools/copy_to_directory` `go_binary`
@@ -383,6 +385,8 @@ def copy_to_directory_bin_action(
See copy_to_directory rule documentation for more details.
verbose: If true, prints out verbose logs to stdout
+
+ override_execution_requirements: specify execution_requirements for this action
"""
# Replace "." in root_paths with the package name of the target
@@ -491,7 +495,7 @@ def copy_to_directory_bin_action(
arguments = [config_file.path],
mnemonic = "CopyToDirectory",
progress_message = "Copying files to directory %s" % _progress_path(dst),
- execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
+ execution_requirements = override_execution_requirements or execution_requirements_for_copy(ctx),
)
copy_to_directory_lib = struct(