chore: remove legacy copy_to_directory_action (#582)
This commit is contained in:
parent
e640c0db0f
commit
dca2b1df0c
|
@ -67,50 +67,6 @@ for more information on supported globbing patterns.
|
|||
| <a id="copy_to_directory-verbose"></a>verbose | If true, prints out verbose logs to stdout | Boolean | optional | False |
|
||||
|
||||
|
||||
<a id="copy_to_directory_action"></a>
|
||||
|
||||
## copy_to_directory_action
|
||||
|
||||
<pre>
|
||||
copy_to_directory_action(<a href="#copy_to_directory_action-ctx">ctx</a>, <a href="#copy_to_directory_action-srcs">srcs</a>, <a href="#copy_to_directory_action-dst">dst</a>, <a href="#copy_to_directory_action-additional_files">additional_files</a>, <a href="#copy_to_directory_action-root_paths">root_paths</a>,
|
||||
<a href="#copy_to_directory_action-include_external_repositories">include_external_repositories</a>, <a href="#copy_to_directory_action-include_srcs_packages">include_srcs_packages</a>, <a href="#copy_to_directory_action-exclude_srcs_packages">exclude_srcs_packages</a>,
|
||||
<a href="#copy_to_directory_action-include_srcs_patterns">include_srcs_patterns</a>, <a href="#copy_to_directory_action-exclude_srcs_patterns">exclude_srcs_patterns</a>, <a href="#copy_to_directory_action-exclude_prefixes">exclude_prefixes</a>,
|
||||
<a href="#copy_to_directory_action-replace_prefixes">replace_prefixes</a>, <a href="#copy_to_directory_action-allow_overwrites">allow_overwrites</a>, <a href="#copy_to_directory_action-is_windows">is_windows</a>)
|
||||
</pre>
|
||||
|
||||
Legacy factory function to copy files to a directory.
|
||||
|
||||
This helper calculates copy paths in Starlark during analysis and performs the copies in a
|
||||
bash/bat script. For improved analysis and runtime performance, it is recommended the switch
|
||||
to `copy_to_directory_bin_action` which calculates copy paths and performs copies with a tool
|
||||
binary, typically the `@aspect_bazel_lib//tools/copy_to_directory` `go_binary` either built
|
||||
from source or provided by a toolchain.
|
||||
|
||||
This helper is used by copy_to_directory. It is exposed as a public API so it can be used within
|
||||
other rule implementations where additional_files can also be passed in.
|
||||
|
||||
|
||||
**PARAMETERS**
|
||||
|
||||
|
||||
| Name | Description | Default Value |
|
||||
| :------------- | :------------- | :------------- |
|
||||
| <a id="copy_to_directory_action-ctx"></a>ctx | The rule context. | none |
|
||||
| <a id="copy_to_directory_action-srcs"></a>srcs | Files and/or directories or targets that provide <code>DirectoryPathInfo</code> to copy into the output directory. | none |
|
||||
| <a id="copy_to_directory_action-dst"></a>dst | The directory to copy to. Must be a TreeArtifact. | none |
|
||||
| <a id="copy_to_directory_action-additional_files"></a>additional_files | List or depset of additional files to copy that are not in the <code>DefaultInfo</code> or <code>DirectoryPathInfo</code> of srcs | <code>[]</code> |
|
||||
| <a id="copy_to_directory_action-root_paths"></a>root_paths | List of paths that are roots in the output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>["."]</code> |
|
||||
| <a id="copy_to_directory_action-include_external_repositories"></a>include_external_repositories | List of external repository names to include in the output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>[]</code> |
|
||||
| <a id="copy_to_directory_action-include_srcs_packages"></a>include_srcs_packages | List of Bazel packages to include in output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>["**"]</code> |
|
||||
| <a id="copy_to_directory_action-exclude_srcs_packages"></a>exclude_srcs_packages | List of Bazel packages (with glob support) to exclude from output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>[]</code> |
|
||||
| <a id="copy_to_directory_action-include_srcs_patterns"></a>include_srcs_patterns | List of paths (with glob support) to include in output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>["**"]</code> |
|
||||
| <a id="copy_to_directory_action-exclude_srcs_patterns"></a>exclude_srcs_patterns | List of paths (with glob support) to exclude from output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>[]</code> |
|
||||
| <a id="copy_to_directory_action-exclude_prefixes"></a>exclude_prefixes | List of path prefixes to exclude from output directory.<br><br>See copy_to_directory rule documentation for more details. | <code>[]</code> |
|
||||
| <a id="copy_to_directory_action-replace_prefixes"></a>replace_prefixes | Map of paths prefixes to replace in the output directory path when copying files.<br><br>See copy_to_directory rule documentation for more details. | <code>{}</code> |
|
||||
| <a id="copy_to_directory_action-allow_overwrites"></a>allow_overwrites | If True, allow files to be overwritten if the same output file is copied to twice.<br><br>See copy_to_directory rule documentation for more details. | <code>False</code> |
|
||||
| <a id="copy_to_directory_action-is_windows"></a>is_windows | Deprecated and unused | <code>None</code> |
|
||||
|
||||
|
||||
<a id="copy_to_directory_bin_action"></a>
|
||||
|
||||
## copy_to_directory_bin_action
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
|
||||
load(
|
||||
"//lib/private:copy_to_directory.bzl",
|
||||
_copy_to_directory_action = "copy_to_directory_action",
|
||||
_copy_to_directory_bin_action = "copy_to_directory_bin_action",
|
||||
_copy_to_directory_lib = "copy_to_directory_lib",
|
||||
)
|
||||
|
||||
# export the starlark library as a public API
|
||||
copy_to_directory_lib = _copy_to_directory_lib
|
||||
copy_to_directory_action = _copy_to_directory_action
|
||||
copy_to_directory_bin_action = _copy_to_directory_bin_action
|
||||
|
||||
copy_to_directory = rule(
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
"copy_to_directory implementation"
|
||||
|
||||
load("@bazel_skylib//lib:paths.bzl", skylib_paths = "paths")
|
||||
load(":copy_common.bzl", _COPY_EXECUTION_REQUIREMENTS = "COPY_EXECUTION_REQUIREMENTS", _progress_path = "progress_path")
|
||||
load(":directory_path.bzl", "DirectoryPathInfo")
|
||||
load(":glob_match.bzl", "glob_match", "is_glob")
|
||||
load(":paths.bzl", "paths")
|
||||
load(":platform_utils.bzl", _platform_utils = "platform_utils")
|
||||
|
||||
_filter_transforms_order_docstring = """Filters and transformations are applied in the following order:
|
||||
|
||||
|
@ -286,311 +283,6 @@ _copy_to_directory_attr = {
|
|||
# ),
|
||||
}
|
||||
|
||||
def _any_globs_match(exprs, path):
|
||||
# Exit quick in the common case of having a "**".
|
||||
if "**" in exprs:
|
||||
return True
|
||||
|
||||
# Special case: support non-standard empty glob expr.
|
||||
# Only an empty expression matches an empty path.
|
||||
if path == "":
|
||||
return "" in exprs
|
||||
|
||||
for expr in exprs:
|
||||
if expr != "" and glob_match(expr, path):
|
||||
return True
|
||||
return None
|
||||
|
||||
def _longest_glob_match(expr, path):
|
||||
if not is_glob(expr):
|
||||
return expr if path.startswith(expr) else None
|
||||
|
||||
for i in range(len(path)):
|
||||
maybe_match = path[:-i] if i > 0 else path
|
||||
if glob_match(expr, maybe_match):
|
||||
# Some subpath matches
|
||||
return maybe_match
|
||||
return None
|
||||
|
||||
def _longest_globs_match(exprs, path):
|
||||
matching_expr = None
|
||||
longest_match = None
|
||||
longest_match_len = 0
|
||||
for expr in exprs:
|
||||
match = _longest_glob_match(expr, path)
|
||||
if match:
|
||||
match_len = len(match)
|
||||
if match_len > longest_match_len:
|
||||
matching_expr = expr
|
||||
longest_match = match
|
||||
longest_match_len = match_len
|
||||
return matching_expr, longest_match
|
||||
|
||||
# src can either be a File or a target with a DirectoryPathInfo
|
||||
def _copy_paths(
|
||||
src,
|
||||
root_paths,
|
||||
include_external_repositories,
|
||||
include_srcs_packages,
|
||||
exclude_srcs_packages,
|
||||
include_srcs_patterns,
|
||||
exclude_srcs_patterns,
|
||||
replace_prefixes):
|
||||
output_path_is_directory = False
|
||||
if type(src) == "File":
|
||||
src_file = src
|
||||
src_path = src_file.path
|
||||
output_path = paths.to_workspace_path(src_file)
|
||||
output_path_is_directory = src_file.is_directory
|
||||
elif DirectoryPathInfo in src:
|
||||
src_file = src[DirectoryPathInfo].directory
|
||||
src_path = "/".join([src_file.path, src[DirectoryPathInfo].path])
|
||||
output_path = "/".join([paths.to_workspace_path(src_file), src[DirectoryPathInfo].path])
|
||||
else:
|
||||
fail("Unsupported type")
|
||||
|
||||
if not src_file.owner:
|
||||
msg = "Expected an owner target label for file {} but found none".format(src_file)
|
||||
fail(msg)
|
||||
|
||||
if src_file.owner.package == None:
|
||||
msg = "Expected owner target label for file {} to have a package name but found None".format(src_file)
|
||||
fail(msg)
|
||||
|
||||
if not include_srcs_packages:
|
||||
fail("An empty 'include_srcs_packages' list will exclude all srcs and result in an empty directory")
|
||||
|
||||
if "**" in exclude_srcs_packages:
|
||||
fail("A '**' glob pattern in 'exclude_srcs_packages' will exclude all srcs and result in an empty directory")
|
||||
|
||||
if not include_srcs_patterns:
|
||||
fail("An empty 'include_srcs_patterns' list will exclude all srcs and result in an empty directory")
|
||||
|
||||
if "**" in exclude_srcs_patterns:
|
||||
fail("A '**' glob pattern in 'exclude_srcs_patterns' will exclude all srcs and result in an empty directory")
|
||||
|
||||
# Apply filters and transformations in the following order:
|
||||
#
|
||||
# - `include_external_repositories`
|
||||
# - `include_srcs_packages`
|
||||
# - `exclude_srcs_packages`
|
||||
# - `root_paths`
|
||||
# - `include_srcs_patterns`
|
||||
# - `exclude_srcs_patterns`
|
||||
# - `replace_prefixes`
|
||||
#
|
||||
# If you change this order please update the docstrings to reflect the changes.
|
||||
|
||||
# apply include_external_repositories if the file is from an external repository
|
||||
if src_file.owner.workspace_name:
|
||||
if not _any_globs_match(include_external_repositories, src_file.owner.workspace_name):
|
||||
# file is excluded as its external repository does not match any patterns in include_external_repositories
|
||||
return None, None, None
|
||||
|
||||
# apply include_srcs_packages
|
||||
if not _any_globs_match(include_srcs_packages, src_file.owner.package):
|
||||
# file is excluded as it does not match any specified include_srcs_packages
|
||||
return None, None, None
|
||||
|
||||
# apply exclude_srcs_packages
|
||||
if _any_globs_match(exclude_srcs_packages, src_file.owner.package):
|
||||
# file is excluded due to a matching exclude_srcs_packages
|
||||
return None, None, None
|
||||
|
||||
# apply root_paths
|
||||
if root_paths:
|
||||
globstar_suffix = False
|
||||
for root_path in root_paths:
|
||||
if root_path.endswith("**"):
|
||||
globstar_suffix = True
|
||||
break
|
||||
if not output_path_is_directory and globstar_suffix:
|
||||
# match against the output_path dirname and not the full output path
|
||||
# so we don't match against the filename on an ending '**' glob pattern
|
||||
output_root = skylib_paths.dirname(output_path)
|
||||
else:
|
||||
output_root = output_path
|
||||
_, longest_match = _longest_globs_match(root_paths, output_root)
|
||||
if longest_match:
|
||||
if longest_match.endswith("/"):
|
||||
longest_match = longest_match[:-1]
|
||||
if len(longest_match) == len(output_root) or output_root[len(longest_match)] == "/":
|
||||
output_path = output_path[len(longest_match) + 1:]
|
||||
|
||||
# apply include_srcs_patterns if "**" is not included in the list
|
||||
if not _any_globs_match(include_srcs_patterns, output_path):
|
||||
# file is excluded as it does not match any specified include_srcs_patterns
|
||||
return None, None, None
|
||||
|
||||
# apply exclude_srcs_patterns
|
||||
if _any_globs_match(exclude_srcs_patterns, output_path):
|
||||
# file is excluded due to a matching exclude_srcs_patterns
|
||||
return None, None, None
|
||||
|
||||
# apply replace_prefixes
|
||||
if replace_prefixes:
|
||||
for replace_prefix in replace_prefixes.keys():
|
||||
if replace_prefix.endswith("**"):
|
||||
msg = "replace_prefix '{}' must not end with '**' glob expression".format(replace_prefix)
|
||||
fail(msg)
|
||||
matching_expr, longest_match = _longest_globs_match(replace_prefixes.keys(), output_path)
|
||||
if longest_match:
|
||||
# replace the longest matching prefix in the output path
|
||||
output_path = replace_prefixes[matching_expr] + output_path[len(longest_match):]
|
||||
|
||||
return skylib_paths.normalize(src_path), skylib_paths.normalize(output_path), src_file
|
||||
|
||||
def _merge_into_copy_path(copy_paths, src_path, dst_path, src_file):
|
||||
for i, s in enumerate(copy_paths):
|
||||
_, maybe_dst_path, maybe_src_file = s
|
||||
if dst_path == maybe_dst_path:
|
||||
if src_file == maybe_src_file:
|
||||
return True
|
||||
if src_file.short_path == maybe_src_file.short_path:
|
||||
if maybe_src_file.is_source and not src_file.is_source:
|
||||
# If the files are the at the same path but one in the source tree and one in
|
||||
# the output tree, always copy the output tree file. This is also the default
|
||||
# Bazel behavior for layout out runfiles if there are files that have the same
|
||||
# path in the source tree and the output tree. This can happen, for example, if
|
||||
# the source file and a generated file that is a copy to the source file are
|
||||
# both added to the package which can happen, for example, through 'additional_files'
|
||||
# in 'copy_to_directory_action'.
|
||||
copy_paths[i] = (src_path, dst_path, src_file)
|
||||
return True
|
||||
return False
|
||||
|
||||
def _copy_to_dir_bash(ctx, copy_paths, dst_dir, allow_overwrites):
|
||||
cmds = [
|
||||
"set -o errexit -o nounset -o pipefail",
|
||||
"OUT_CAPTURE=$(mktemp)",
|
||||
"""_exit() {
|
||||
EXIT_CODE=$?;
|
||||
if [ "$EXIT_CODE" != 0 ]; then
|
||||
cat "$OUT_CAPTURE"
|
||||
fi
|
||||
exit $EXIT_CODE
|
||||
}""",
|
||||
"trap _exit EXIT",
|
||||
"mkdir -p \"%s\"" % dst_dir.path,
|
||||
]
|
||||
|
||||
inputs = []
|
||||
|
||||
for src_path, dst_path, src_file in copy_paths:
|
||||
inputs.append(src_file)
|
||||
|
||||
maybe_force = "-f " if allow_overwrites else "-n "
|
||||
maybe_chmod_file = """if [ -e "{dst}" ]; then
|
||||
chmod a+w "{dst}"
|
||||
fi
|
||||
""" if allow_overwrites else ""
|
||||
maybe_chmod_dir = """if [ -e "{dst}" ]; then
|
||||
chmod -R a+w "{dst}"
|
||||
fi
|
||||
""" if allow_overwrites else ""
|
||||
|
||||
cmds.append("""
|
||||
if [[ ! -e "{src}" ]]; then echo "file '{src}' does not exist"; exit 1; fi
|
||||
if [[ -f "{src}" ]]; then
|
||||
mkdir -p "{dst_dir}"
|
||||
{maybe_chmod_file}cp -v {maybe_force}"{src}" "{dst}" >> "$OUT_CAPTURE" 2>>"$OUT_CAPTURE"
|
||||
else
|
||||
if [[ -d "{dst}" ]]; then
|
||||
# When running outside the sandbox, then an earlier copy will create the dst folder
|
||||
# with nested read-only folders, so our copy operation will fail to write there.
|
||||
# Make sure the output folders are writeable.
|
||||
find "{dst}" -type d -print0 | xargs -0 chmod a+w
|
||||
fi
|
||||
mkdir -p "{dst}"
|
||||
{maybe_chmod_dir}cp -v -R {maybe_force}"{src}/." "{dst}" >> "$OUT_CAPTURE" 2>>"$OUT_CAPTURE"
|
||||
fi
|
||||
""".format(
|
||||
src = src_path,
|
||||
dst_dir = skylib_paths.dirname(dst_path),
|
||||
dst = dst_path,
|
||||
maybe_force = maybe_force,
|
||||
maybe_chmod_file = maybe_chmod_file,
|
||||
maybe_chmod_dir = maybe_chmod_dir,
|
||||
))
|
||||
|
||||
ctx.actions.run_shell(
|
||||
inputs = inputs,
|
||||
outputs = [dst_dir],
|
||||
command = "\n".join(cmds),
|
||||
mnemonic = "CopyToDirectory",
|
||||
progress_message = "Copying files to directory %s" % _progress_path(dst_dir),
|
||||
use_default_shell_env = True,
|
||||
execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
|
||||
)
|
||||
|
||||
def _copy_to_dir_cmd(ctx, copy_paths, dst_dir):
|
||||
# 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.
|
||||
# To fix that we write the command to a .bat file so no command line
|
||||
# quoting or escaping is required.
|
||||
# Based on skylib copy_file:
|
||||
# https://github.com/bazelbuild/bazel-skylib/blob/main/rules/private/copy_file_private.bzl#L28.
|
||||
bat = ctx.actions.declare_file(ctx.label.name + "-cmd.bat")
|
||||
|
||||
# NB: mkdir will create all subdirectories; it will exit 1
|
||||
# print an error to stderr if the directory already exists so
|
||||
# we supress both its stdout & stderr output
|
||||
cmds = ["""
|
||||
@rem @generated by @aspect_bazel_lib//lib/private:copy_to_directory.bzl
|
||||
@echo off
|
||||
mkdir "%s" >NUL 2>NUL
|
||||
""" % dst_dir.path.replace("/", "\\")]
|
||||
|
||||
inputs = []
|
||||
|
||||
for src_path, dst_path, src_file in copy_paths:
|
||||
inputs.append(src_file)
|
||||
|
||||
# copy & xcopy flags are documented at
|
||||
# https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/copy
|
||||
# https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
|
||||
cmds.append("""
|
||||
if not exist "{src}" (
|
||||
echo file "{src}" does not exist
|
||||
exit /b 1
|
||||
)
|
||||
if exist "{src}\\*" (
|
||||
mkdir "{dst}" >NUL 2>NUL
|
||||
robocopy "{src}" "{dst}" /E >NUL
|
||||
) else (
|
||||
mkdir "{dst_dir}" >NUL 2>NUL
|
||||
copy /Y "{src}" "{dst}" >NUL
|
||||
)
|
||||
""".format(
|
||||
src = src_path.replace("/", "\\"),
|
||||
dst_dir = skylib_paths.dirname(dst_path).replace("/", "\\"),
|
||||
dst = dst_path.replace("/", "\\"),
|
||||
))
|
||||
|
||||
# robocopy return non-zero exit codes on success so we must exit 0 when we are done
|
||||
cmds.append("exit 0")
|
||||
|
||||
ctx.actions.write(
|
||||
output = bat,
|
||||
# Do not use lib/shell.bzl's shell.quote() method, because that uses
|
||||
# Bash quoting syntax, which is different from cmd.exe's syntax.
|
||||
content = "\n".join(cmds),
|
||||
is_executable = True,
|
||||
)
|
||||
|
||||
ctx.actions.run(
|
||||
inputs = inputs,
|
||||
tools = [bat],
|
||||
outputs = [dst_dir],
|
||||
executable = "cmd.exe",
|
||||
arguments = ["/C", bat.path.replace("/", "\\")],
|
||||
mnemonic = "CopyToDirectory",
|
||||
progress_message = "Copying files to directory %s" % _progress_path(dst_dir),
|
||||
use_default_shell_env = True,
|
||||
execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
|
||||
)
|
||||
|
||||
def _copy_to_directory_impl(ctx):
|
||||
copy_to_directory_bin = ctx.toolchains["@aspect_bazel_lib//lib:copy_to_directory_toolchain_type"].copy_to_directory_info.bin
|
||||
|
||||
|
@ -842,162 +534,6 @@ def copy_to_directory_bin_action(
|
|||
execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
|
||||
)
|
||||
|
||||
# TODO(2.0): remove the legacy copy_to_directory_action helper
|
||||
def copy_to_directory_action(
|
||||
ctx,
|
||||
srcs,
|
||||
dst,
|
||||
additional_files = [],
|
||||
root_paths = ["."],
|
||||
include_external_repositories = [],
|
||||
include_srcs_packages = ["**"],
|
||||
exclude_srcs_packages = [],
|
||||
include_srcs_patterns = ["**"],
|
||||
exclude_srcs_patterns = [],
|
||||
exclude_prefixes = [],
|
||||
replace_prefixes = {},
|
||||
allow_overwrites = False,
|
||||
is_windows = None):
|
||||
"""Legacy factory function to copy files to a directory.
|
||||
|
||||
This helper calculates copy paths in Starlark during analysis and performs the copies in a
|
||||
bash/bat script. For improved analysis and runtime performance, it is recommended the switch
|
||||
to `copy_to_directory_bin_action` which calculates copy paths and performs copies with a tool
|
||||
binary, typically the `@aspect_bazel_lib//tools/copy_to_directory` `go_binary` either built
|
||||
from source or provided by a toolchain.
|
||||
|
||||
This helper is used by copy_to_directory. It is exposed as a public API so it can be used within
|
||||
other rule implementations where additional_files can also be passed in.
|
||||
|
||||
Args:
|
||||
ctx: The rule context.
|
||||
|
||||
srcs: Files and/or directories or targets that provide `DirectoryPathInfo` to copy into the output directory.
|
||||
|
||||
dst: The directory to copy to. Must be a TreeArtifact.
|
||||
|
||||
additional_files: List or depset of additional files to copy that are not in the `DefaultInfo` or `DirectoryPathInfo` of srcs
|
||||
|
||||
root_paths: List of paths that are roots in the output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
include_external_repositories: List of external repository names to include in the output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
include_srcs_packages: List of Bazel packages to include in output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
exclude_srcs_packages: List of Bazel packages (with glob support) to exclude from output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
include_srcs_patterns: List of paths (with glob support) to include in output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
exclude_srcs_patterns: List of paths (with glob support) to exclude from output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
exclude_prefixes: List of path prefixes to exclude from output directory.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
replace_prefixes: Map of paths prefixes to replace in the output directory path when copying files.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
allow_overwrites: If True, allow files to be overwritten if the same output file is copied to twice.
|
||||
|
||||
See copy_to_directory rule documentation for more details.
|
||||
|
||||
is_windows: Deprecated and unused
|
||||
"""
|
||||
|
||||
# TODO(2.0): remove deprecated & unused is_windows parameter
|
||||
if not srcs:
|
||||
fail("srcs must not be empty")
|
||||
|
||||
# Replace "." in root_paths with the package name of the target
|
||||
root_paths = [p if p != "." else ctx.label.package for p in root_paths]
|
||||
|
||||
# Replace a leading "." with the package name of the target in include_srcs_packages & exclude_srcs_packages
|
||||
include_srcs_packages = _expand_src_packages_patterns(include_srcs_packages, ctx.label.package)
|
||||
exclude_srcs_packages = _expand_src_packages_patterns(exclude_srcs_packages, ctx.label.package)
|
||||
|
||||
# Convert and append exclude_prefixes to exclude_srcs_patterns
|
||||
# TODO(2.0): remove exclude_prefixes this block and in a future breaking release
|
||||
for exclude_prefix in exclude_prefixes:
|
||||
if exclude_prefix.endswith("**"):
|
||||
exclude_srcs_patterns.append(exclude_prefix)
|
||||
elif exclude_prefix.endswith("*"):
|
||||
exclude_srcs_patterns.append(exclude_prefix + "/**")
|
||||
exclude_srcs_patterns.append(exclude_prefix)
|
||||
elif exclude_prefix.endswith("/"):
|
||||
exclude_srcs_patterns.append(exclude_prefix + "**")
|
||||
else:
|
||||
exclude_srcs_patterns.append(exclude_prefix + "*/**")
|
||||
exclude_srcs_patterns.append(exclude_prefix + "*")
|
||||
|
||||
# Gather a list of src_path, dst_path pairs
|
||||
found_input_paths = False
|
||||
|
||||
src_dirs = []
|
||||
src_depsets = []
|
||||
copy_paths = []
|
||||
for src in srcs:
|
||||
if DirectoryPathInfo in src:
|
||||
src_dirs.append(src)
|
||||
if DefaultInfo in src:
|
||||
src_depsets.append(src[DefaultInfo].files)
|
||||
|
||||
# Convert potentially-large arrays into slices to pass by reference
|
||||
# instead of copying when invoking _copy_paths()
|
||||
root_paths = root_paths[:]
|
||||
include_external_repositories = include_external_repositories[:]
|
||||
include_srcs_packages = include_srcs_packages[:]
|
||||
exclude_srcs_packages = exclude_srcs_packages[:]
|
||||
include_srcs_patterns = include_srcs_patterns[:]
|
||||
exclude_srcs_patterns = exclude_srcs_patterns[:]
|
||||
|
||||
if type(additional_files) == "list":
|
||||
additional_files = depset(additional_files)
|
||||
|
||||
all_srcs = src_dirs + depset(transitive = [additional_files] + src_depsets).to_list()
|
||||
for src in all_srcs:
|
||||
found_input_paths = True
|
||||
src_path, output_path, src_file = _copy_paths(
|
||||
src = src,
|
||||
root_paths = root_paths,
|
||||
include_external_repositories = include_external_repositories,
|
||||
include_srcs_packages = include_srcs_packages,
|
||||
exclude_srcs_packages = exclude_srcs_packages,
|
||||
include_srcs_patterns = include_srcs_patterns,
|
||||
exclude_srcs_patterns = exclude_srcs_patterns,
|
||||
replace_prefixes = replace_prefixes,
|
||||
)
|
||||
if src_path != None:
|
||||
dst_path = skylib_paths.normalize("/".join([dst.path, output_path]))
|
||||
if not _merge_into_copy_path(copy_paths, src_path, dst_path, src_file):
|
||||
copy_paths.append((src_path, dst_path, src_file))
|
||||
|
||||
if not found_input_paths:
|
||||
fail("No files or directories found in srcs.")
|
||||
if not copy_paths:
|
||||
fail("There are no files or directories to copy after applying filters. Are your 'include_srcs_patterns' and 'exclude_srcs_patterns' attributes correct?")
|
||||
|
||||
# Because copy actions have "local" execution requirements, we can safely assume
|
||||
# the execution is the same as the host platform and generate different actions for Windows
|
||||
# and non-Windows host platforms
|
||||
is_windows = _platform_utils.host_platform_is_windows()
|
||||
if is_windows:
|
||||
_copy_to_dir_cmd(ctx, copy_paths, dst)
|
||||
else:
|
||||
_copy_to_dir_bash(ctx, copy_paths, dst, allow_overwrites)
|
||||
|
||||
copy_to_directory_lib = struct(
|
||||
doc = _copy_to_directory_doc,
|
||||
attr_doc = _copy_to_directory_attr_doc,
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
1
|
|
@ -1 +0,0 @@
|
|||
1
|
|
@ -1,51 +0,0 @@
|
|||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load("//lib:copy_to_bin.bzl", "copy_to_bin")
|
||||
load("//lib:copy_to_directory.bzl", "copy_to_directory")
|
||||
load("//lib:diff_test.bzl", "diff_test")
|
||||
load(":lib.bzl", "lib")
|
||||
load(":pkg.bzl", "pkg")
|
||||
|
||||
copy_to_bin(
|
||||
name = "copy_1",
|
||||
srcs = ["1"],
|
||||
)
|
||||
|
||||
lib(
|
||||
name = "lib",
|
||||
srcs = ["1"],
|
||||
# intentionally dup on "1" to make sure it is gracefully handled
|
||||
others = [
|
||||
"1",
|
||||
# also pass in a copy_to_bin copy of "1" to spice things up;
|
||||
# this case is handled in the fix in https://github.com/aspect-build/bazel-lib/pull/205
|
||||
"copy_1",
|
||||
"2",
|
||||
],
|
||||
)
|
||||
|
||||
# pkg should copy DefaultInfo files and OtherInfo files
|
||||
pkg(
|
||||
name = "pkg",
|
||||
srcs = [":lib"],
|
||||
out = "pkg",
|
||||
)
|
||||
|
||||
copy_to_directory(
|
||||
name = "expected_pkg",
|
||||
srcs = [
|
||||
"1",
|
||||
"2",
|
||||
],
|
||||
)
|
||||
|
||||
diff_test(
|
||||
name = "test",
|
||||
file1 = ":pkg",
|
||||
file2 = ":expected_pkg",
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "other_info",
|
||||
srcs = ["other_info.bzl"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -1,22 +0,0 @@
|
|||
"""
|
||||
Test rule to create a lib with a DefaultInfo and a OtherInfo
|
||||
"""
|
||||
|
||||
load(":other_info.bzl", "OtherInfo")
|
||||
|
||||
_attrs = {
|
||||
"srcs": attr.label_list(allow_files = True),
|
||||
"others": attr.label_list(allow_files = True),
|
||||
}
|
||||
|
||||
def _lib_impl(ctx):
|
||||
return [
|
||||
DefaultInfo(files = depset(ctx.files.srcs)),
|
||||
OtherInfo(files = depset(ctx.files.others)),
|
||||
]
|
||||
|
||||
lib = rule(
|
||||
implementation = _lib_impl,
|
||||
attrs = _attrs,
|
||||
provides = [DefaultInfo, OtherInfo],
|
||||
)
|
|
@ -1,8 +0,0 @@
|
|||
"""For testing"""
|
||||
|
||||
OtherInfo = provider(
|
||||
doc = "For testing",
|
||||
fields = {
|
||||
"files": "A depset of files",
|
||||
},
|
||||
)
|
|
@ -1,38 +0,0 @@
|
|||
"""
|
||||
Test rule to create a pkg with DefaultInfo and OtherInfo files
|
||||
"""
|
||||
|
||||
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory_action")
|
||||
load(":other_info.bzl", "OtherInfo")
|
||||
|
||||
_attrs = {
|
||||
"srcs": attr.label_list(allow_files = True),
|
||||
"out": attr.string(mandatory = True),
|
||||
}
|
||||
|
||||
def _pkg_impl(ctx):
|
||||
dst = ctx.actions.declare_directory(ctx.attr.out)
|
||||
|
||||
additional_files_depsets = []
|
||||
|
||||
# include files from OtherInfo of srcs
|
||||
for src in ctx.attr.srcs:
|
||||
if OtherInfo in src:
|
||||
additional_files_depsets.append(src[OtherInfo].files)
|
||||
|
||||
copy_to_directory_action(
|
||||
ctx,
|
||||
srcs = ctx.attr.srcs,
|
||||
dst = dst,
|
||||
additional_files = depset(transitive = additional_files_depsets),
|
||||
)
|
||||
|
||||
return [
|
||||
DefaultInfo(files = depset([dst])),
|
||||
]
|
||||
|
||||
pkg = rule(
|
||||
implementation = _pkg_impl,
|
||||
attrs = _attrs,
|
||||
provides = [DefaultInfo],
|
||||
)
|
Loading…
Reference in New Issue