# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
# TODO(cjhopman): This was generated by scripts/hacks/rules_shim_with_docs.py,
# but should be manually edited going forward. There may be some errors in
# the generated docs, and so those should be verified to be accurate and
# well-formatted (and then delete this TODO)
load(":common.bzl", "OnDuplicateEntry", "buck", "prelude_rule", "validate_uri")
load(":genrule_common.bzl", "genrule_common")
load(":remote_common.bzl", "remote_common")
ExportFileDescriptionMode = ["reference", "copy"]
PlatformExePlatform = ["linux", "macos", "windows"]
RemoteFileType = ["data", "executable", "exploded_zip"]
TargetCpuType = ["arm", "armv7", "arm64", "x86", "x86_64", "mips"]
alias = prelude_rule(
name = "alias",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"actual": attrs.option(attrs.dep(pulls_and_pushes_plugins = plugins.All)),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
}
),
)
command_alias = prelude_rule(
name = "command_alias",
docs = """
The `command_alias` rule enables you to wrap build
rules that create binaries and to pre-apply command-line
arguments and environment variables.
Example uses include running a command written in a scripting
language with a specific interpreter, and transparently wrapping
sub-commands of a binary.
You can reference a `command_alias` target in
the `cmd` parameter of a `genrule()` by
using the `exe` macro:
```
$(exe //path/to:target)
```
""",
examples = """
```
# Combining an interpreter and a script
cxx_binary(
name = "node-js",
srcs = [
# ...
],
headers = [
# ...
],
)
export_file(
name = "scripts"
)
command_alias(
name = "server",
exe = ":node-js",
args = [
"$(location :scripts)/start-server.js",
],
)
```
```
# Exposing sub commands
export_file(
name = "yarn",
src = "yarn.sh",
)
command_alias(
name = "add",
exe = ":yarn",
args = ["add"],
)
command_alias(
name = "install",
exe = ":yarn",
args = ["install"],
)
command_alias(
name = "run",
exe = ":yarn",
args = ["run"],
)
```
```
# Platform specific commands
export_file(
name = "node-windows",
src = "windows/node.exe",
)
export_file(
name = "node-linux",
src = "linux/node",
)
export_file(
name = "node-macos",
src = "macos/node",
)
command_alias(
name = "node",
platform_exe = {
"windows": ":node-windows",
"linux": ":node-linux",
"macos": ":node-macos",
},
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
# Match `dep` before `source` so that we can support extracting the
# `RunInfo` provider of it, if one exists.
"exe": attrs.option(attrs.one_of(attrs.dep(), attrs.source()), default = None, doc = """
A `build target` for a rule that outputs
an executable, such as an `sh_binary()`,
or an executable source file.
"""),
"platform_exe": attrs.dict(key = attrs.enum(PlatformExePlatform), value = attrs.dep(), sorted = False, default = {}, doc = """
A mapping from platforms to `build target`.
enables you to override `exe` per host platform.
If present, `exe` will be used as a fallback on host platforms that are not
specified in `platform_exe`.
It is possible to omit `exe` when providing `platform_exe`.
In that case, the build will fail if the command is invoked on a platform not specified in
the mapping.
Valid platforms are all values of the [`Platform` enum](https://dev.buck.build/javadoc/com/facebook/buck/util/environment/Platform.html) :
* `FREEBSD`
* `LINUX`
* `MACOS`
* `WINDOWS`
"""),
"args": attrs.list(attrs.arg(), default = [], doc = """
A string of arguments that is passed to the executable specified by
`exe` at startup. These arguments support a subset of
Buck's `string parameter macros`
. Only the
`$(location ...)` and `$(exe ...)` macros are supported currently.
"""),
"env": attrs.dict(key = attrs.string(), value = attrs.arg(), sorted = False, default = {}, doc = """
A map of environment variables that will be passed to the executable represented
by `exe` on startup. Environment variables support the same macros as arguments.
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"resources": attrs.list(attrs.source(), default = []),
"run_using_single_arg": attrs.bool(default = False, doc = """
Ensure that the command alias can be run as a single argument (instead of
$(exe) or RunInfo potentially expanding to multiple arguments).
"""),
"_exec_os_type": buck.exec_os_type_arg(),
"_target_os_type": buck.target_os_type_arg(),
}
),
)
config_setting = prelude_rule(
name = "config_setting",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"constraint_values": attrs.list(attrs.configuration_label(), default = []),
"values": attrs.dict(key = attrs.string(), value = attrs.string(), sorted = False, default = {}),
}
),
)
configuration_alias = prelude_rule(
name = "configuration_alias",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
# configuration_alias acts like alias but for configuration rules.
# The configuration_alias itself is a configuration rule and the `actual` argument is
# expected to be a configuration rule as well.
"actual": attrs.dep(pulls_and_pushes_plugins = plugins.All),
}
),
)
configured_alias = prelude_rule(
name = "configured_alias",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
# The 'actual' attribute of configured_alias is a configured_label, which is
# currently unimplemented. Map it to dep so we can simply forward the providers.
# TODO(nga): "actual" attribute exists here only to display it in query,
# actual `actual` attribute used in rule implementation is named `configured_actual`.
# Logically this should be `attrs.configuration_label`, but `configuration_label`
# is currently an alias for `attrs.dep`, which makes non-transitioned dependency
# also a dependency along with transitioned dependency. (See D40255132).
"actual": attrs.label(),
"configured_actual": attrs.option(attrs.configured_dep(), default = None),
"fallback_actual": attrs.option(attrs.dep(), default = None),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
# We use a separate field instead of re-purposing `actual`, as we want
# to keep output format compatibility with v1.
# If `configured_actual` is `None`, fallback to this unconfigured dep.
"platform": attrs.option(attrs.configuration_label(), default = None),
"propagate_flavors": attrs.bool(default = False),
}
),
)
constraint_setting = prelude_rule(
name = "constraint_setting",
docs = "",
examples = None,
further = None,
attrs = (
{
}
),
)
constraint_value = prelude_rule(
name = "constraint_value",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"constraint_setting": attrs.configuration_label(),
}
),
)
export_file = prelude_rule(
name = "export_file",
docs = """
An `export_file()` takes a single file or folder and exposes it so other rules can
use it.
""",
examples = """
The best way to see how the `export_file()` rule works is with some examples. The
common case is:
```
export_file(
name = 'example.html',
)
# This is equivalent to
export_file(
name = 'example.html',
src = 'example.html',
out = 'example.html',
)
```
It is sometimes useful to refer to the file not by its path, but by a more logical name:
```
export_file(
name = 'example',
src = 'example.html',
)
# This is equivalent to
export_file(
name = 'example',
src = 'example.html',
out = 'example.html',
)
```
Finally, there are occasions where you want to export a file more than once but want to copy it to
a different name for each output:
```
export_file(
name = 'runner',
src = 'RemoteRunner.html',
)
export_file(
name = 'runner_hta',
src = 'RemoteRunner.html',
out = 'RemoteRunner.hta',
)
```
Using the `export_file()` rule is also simple:
```
export_file(
name = 'example',
src = 'example.html',
)
genrule(
name = 'demo',
out = 'result.html',
cmd = 'cp $(location :example) $OUT',
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
"src": attrs.option(attrs.source(allow_directory = True), default = None, doc = """
The path to the file that should be exported.
"""),
"out": attrs.option(attrs.string(), default = None, doc = """
The name which the file will be called if another rule depends on it instead of the name it
already has.
"""),
"mode": attrs.option(attrs.enum(ExportFileDescriptionMode), default = None, doc = """
How files are referenced internally in buck.
If set to 'copy', then a full copy will be made into the new location in buck-out.
If set to 'reference', the original file will be used by internal build rules in-place.
However, this mode does not work across repositories or if the 'out' property is set.
For read-only operations, 'reference' can be more performant.
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
}
),
)
external_test_runner = prelude_rule(
name = "external_test_runner",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"binary": attrs.dep(),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
}
),
)
filegroup = prelude_rule(
name = "filegroup",
docs = """
This rule provides access to a set of files.
Files are accessible to `genrule()`s by using their relative path
after a `$(location)` string parameter macro.
Other rules may handle `filegroup()` rules natively for attributes
such as resources.
""",
examples = """
In this example a target exports `.xml` files from all subdirectories
in `resources`.
```
filegroup(
name = 'example',
srcs = glob(['resources/**/*.xml']),
)
genrule(
name = 'process_xml',
out = 'processed.xml',
cmd = '$(exe //example:tool) -in $(location :example)/resources/file.xml > $OUT',
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
"srcs": attrs.named_set(attrs.source(allow_directory = True), sorted = False, default = [], doc = """
The set of files to include in this rule.
"""),
"copy": attrs.bool(default = True),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"out": attrs.option(attrs.string(), default = None, doc = """
The name of the output directory. Defaults to the rule's name.
"""),
}
),
)
genrule = prelude_rule(
name = "genrule",
docs = """
A `genrule()` is used to generate files from a shell
command. It must produce a single output file or folder.
""",
examples = """
This genrule() uses a Python script to derive a new
`AndroidManifest.xml` from an
`AndroidManifest.xml` in the source tree.
Note you don't need to prepend execution commands with
`python`: Buck knows how to execute different
kinds of binaries using `$(exe)` command.
```
genrule(
name = 'generate_manifest',
srcs = [
'AndroidManifest.xml',
],
bash = '$(exe //python/android:basic_to_full) ' \
'$SRCDIR/AndroidManifest.xml > $OUT',
cmd_exe = '$(exe //python/android:basic_to_full) ' \
'%SRCDIR%\\AndroidManifest.xml > %OUT%',
out = 'AndroidManifest.xml',
)
```
```
genrule(
name = 'generate_manifest_with_named_outputs',
srcs = [
'AndroidManifest.xml',
],
bash = '$(exe //python/android:basic_to_full) ' \
'$SRCDIR/AndroidManifest.xml > $OUT/AndroidManifest.xml',
cmd_exe = '$(exe //python/android:basic_to_full) ' \
'%SRCDIR%\\AndroidManifest.xml > %OUT%\\AndroidManifest.xml',
outs = {
"manifest": [ "AndroidManifest.xml" ],
},
default_outs = [ "AndroidManifest.xml" ],
)
```
For named outputs, build with any of the following:
```
buck build //:generate_manifest_with_named_outputs
```
```
buck build //:generate_manifest_with_named_outputs[manifest]
```
Consume in `srcs` with:
```
export_file(
name = "magic1",
src = ":generate_manifest_with_named_outputs",
out = "some_dir_to_copy_to/AndroidManifest.xml",
)
```
```
export_file(
name = "magic2",
src = ":generate_manifest_with_named_outputs[manifest]",
out = "some_dir_to_copy_to/AndroidManifest.xml",
)
```
Note that `magic1` consumes `generate_manifest_with_named_outputs`'s default
output. `magic2` consumes `generate_manifest_with_named_outputs`'s named
output "manifest," which happen to be pointing to the same output as the default output in this
case, but they do not have to point to the same output.
""",
further = None,
attrs = (
# @unsorted-dict-items
genrule_common.srcs_arg() |
genrule_common.cmd_arg() |
genrule_common.bash_arg() |
genrule_common.cmd_exe_arg() |
genrule_common.type_arg() |
genrule_common.weight_arg() |
{
"out": attrs.option(attrs.string(), default = None, doc = """
The name of the output file or directory. The complete path to this
argument is provided to the shell command through
the `OUT` environment variable. Only one of `out`
or `outs` may be present.
"""),
"outs": attrs.option(attrs.dict(key = attrs.string(), value = attrs.set(attrs.string(), sorted = False), sorted = False), default = None, doc = """
Mapping defining `named outputs`
to output paths relative to the rule's output directory. Only one of
`out` or `outs` may be present.
Example:
```
genrule(
name = "named_outputs",
outs = {
"output1": [
"out1.txt",
],
"output2": [
"out2.txt",
],
},
default_outs = [ "out1.txt" ],
cmd = "echo something> $OUT/out1.txt && echo another> $OUT/out2.txt",
)
```
Note that a maximum of one value may be present in the list in this map. For example:
```
outs = {
"output1": [
"out1.txt",
],
},
```
is valid, whereas
```
outs = {
"output1": [
"out1.txt",
"out2.txt",
],
},
```
is not.
"""),
"default_outs": attrs.option(attrs.set(attrs.string(), sorted = False), default = None, doc = """
Default output which must be present if the `outs` arg is present. Otherwise does not apply.
If a rule with `outs` is consumed without an output label, the default output is returned. The
default output does not need to be present in any of the named outputs defined in `outs`.
Note that a maximum of one value may be present in this list. For example:
```
default_outs = [ "output_one", ]
```
is valid, whereas
```
default_outs = [ "output_one", "output_two", ]
```
is not.
"""),
"executable_outs": attrs.option(attrs.set(attrs.string(), sorted = False), default = None, doc = """
Only valid if the `outs` arg is present. Dictates which of those named outputs are marked as
executable.
"""),
} |
genrule_common.env_arg() |
genrule_common.environment_expansion_separator() |
{
"enable_sandbox": attrs.option(attrs.bool(), default = None, doc = """
Whether this target should be executed in a sandbox or not.
"""),
"executable": attrs.option(attrs.bool(), default = None, doc = """
Whether the output of the genrule is itself executable. Marking an output as
executable makes `buck run` and `$(exe ...)` macro
expansion work with this target.
"""),
"remote": attrs.option(attrs.bool(), default = None, doc = """
Opts this genrule in to remote execution. Note that it is only safe to
execute a genrule remotely if it is completely hermetic and completely
and correctly describes its dependencies. Defaults to false. This parameter
is unstable. It is subject to removal, default reversal, and other arbitrary
changes in the future.
"""),
"cacheable": attrs.option(attrs.bool(), default = None),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"need_android_tools": attrs.bool(default = False),
"_exec_os_type": buck.exec_os_type_arg(),
}
),
)
http_archive = prelude_rule(
name = "http_archive",
docs = """
An `http_archive()` rule is used to download and extract archives
from the Internet to be used as dependencies for other rules. These rules are
downloaded by running `fetch`, or can be downloaded as part of
`build` by setting `.buckconfig`
""",
examples = """
Using `http_archive()`, third party packages can be downloaded from
an `https` URL and used in other library types.
```
http_archive(
name = 'thrift-archive',
urls = [
'https://internal-mirror.example.com/bin/thrift-compiler-0.1.tar.gz.badextension',
],
sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
type='tar.gz',
strip_prefix='thrift-compiler-0.1'
)
genrule(
name = 'thrift-compiler-bin',
out = 'thrift',
cmd = 'cp $(location :thrift-archive)/bin/thrift $OUT',
executable = True,
)
genrule(
name="my-thrift-lib-cpp2",
cmd="$(exe :thrift-compiler-bin) --gen cpp2 -o $OUT $(location //:thrift-file)",
out="gen-cpp2",
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
remote_common.urls_arg() |
remote_common.sha256_arg() |
remote_common.unarchive_args() |
{
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"sha1": attrs.option(attrs.string(), default = None),
"size_bytes": attrs.option(attrs.int(), default = None),
}
),
)
http_file = prelude_rule(
name = "http_file",
docs = """
An `http_file()` rule is used to download files from the Internet to be used as
dependencies for other rules. This rule only downloads single files, and can
optionally make them executable (see `http_file()executable`)
These rules are downloaded by running `fetch`, or can
be downloaded as part of `build` by setting `.buckconfig`
""",
examples = """
Using `http_file()`, third party packages can be downloaded from
an `https` URL and used in java libraries.
```
http_file(
name = 'guava-23-bin',
urls = [
'http://search.maven.org/remotecontent?filepath=com/google/guava/guava/23.0/guava-23.0.jar',
],
sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
)
http_file(
name = 'guava-23-sources',
urls = [
'http://search.maven.org/remotecontent?filepath=com/google/guava/guava/23.0/guava-23.0-sources.jar',
],
sha256 = '37fe8ba804fb3898c3c8f0cbac319cc9daa58400e5f0226a380ac94fb2c3ca14',
)
prebuilt_java_library(
name = 'guava-23',
binary_jar = ':guava-23-bin',
source_jar = ':guava-23-source',
)
```
Tooling can also be fetched with `http_file()` and used by a `genrule()`.
```
genrule(
name="my-thrift-lib-cpp2",
cmd="$(exe :thrift-compiler-bin) --gen cpp2 -o $OUT $(location //:thrift-file)",
out="gen-cpp2",
)
http_file(
name = 'thrift-compiler-bin',
url = 'https://internal-mirror.example.com/bin/thrift-compiler',
sha256 = 'c24932ccabb66fffb2d7122298f7f1f91e0b1f14e05168e3036333f84bdf58dc',
executable = True,
)
```
Here's an example of a `http_file()` using a mvn URI which uses a Maven classifier.
```
http_file(
name = 'guava-23-bin',
urls = [
'mvn:com.google.guava:guava:jar:23.0',
],
sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
remote_common.urls_arg() |
remote_common.sha256_arg() |
{
"out": attrs.option(attrs.string(), default = None, doc = """
An optional name to call the downloaded artifact. Buck will generate a default name if one is not
provided that uses the `name` of the rule.
"""),
"executable": attrs.option(attrs.bool(), default = None, doc = """
Whether or not the file should be made executable after downloading. If true,
this can also be used via `run` and the
`$(exe )` `string parameter macros`
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"sha1": attrs.option(attrs.string(), default = None),
"size_bytes": attrs.option(attrs.int(), default = None),
}
),
)
platform = prelude_rule(
name = "platform",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"constraint_values": attrs.list(attrs.configuration_label(), default = []),
"deps": attrs.list(attrs.configuration_label(), default = []),
}
),
)
remote_file = prelude_rule(
name = "remote_file",
docs = """
A `remote_file()` rule is used to download files from the Internet to be used as
dependencies for other rules. These rules are downloaded by running `fetch`, or can
be downloaded as part of `build`. See the note there about the
`.buckconfig` setting to configure that.
""",
examples = """
Here's an example of a `remote_file()` using an `https` URL.
```
remote_file(
name = 'android-ndk-r10e-darwin-x86_64',
url = 'https://dl.google.com/android/ndk/android-ndk-r10e-darwin-x86_64.bin',
sha1 = 'b57c2b9213251180dcab794352bfc9a241bf2557',
)
```
Here's an example of a `remote_file()` using a `mvn` URL being referenced
by a `prebuilt_jar()`.
```
prebuilt_jar(
name = 'jetty-all',
binary_jar = 'jetty-all-9.2.10.v20150310.jar',
source_jar = ':jetty-source',
)
remote_file(
name = 'jetty-source',
out = 'jetty-all-9.2.10.v20150310-sources.jar',
url = 'mvn:org.eclipse.jetty.aggregate:jetty-all:src:9.2.10.v20150310',
sha1 = '311da310416d2feb3de227081d7c3f48742d7075',
)
```
Here's an example of a `remote_file()` using a `mvn` URI which uses a
non-default maven repository host.
```
remote_file(
name = 'jetty-source',
out = 'jetty-all-9.2.10.v20150310-sources.jar',
url = 'mvn:https://maven-repo.com:org.eclipse.jetty.aggregate:jetty-all:src:9.2.10.v20150310',
sha1 = '311da310416d2feb3de227081d7c3f48742d7075',
)
```
Here's an example of a `remote_file()` using a `mvn` URI which uses a
Maven classifier.
```
remote_file(
name = 'groovy-groovysh-indy',
out = 'jetty-all-9.2.10.v20150310-sources.jar',
url = 'mvn:org.codehaus.groovy:groovy-groovysh:jar:indy:2.4.1',
sha1 = '1600fde728c885cc9506cb102deb1b494bd7c130',
)
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
"url": attrs.string(validate = validate_uri, doc = """
You can specify an `http`, `https`, or a `mvn` URL. If you
specify a `mvn` URL, it will be decoded as described in the
javadocs for MavenUrlDecoder See the example section below.
"""),
"vpnless_url": attrs.option(attrs.string(), default = None, doc = """
An optional additional URL from which this resource can be downloaded when
off VPN. Meta-internal only.
"""),
"sha1": attrs.string(default = "", doc = """
The [`SHA-1`](//wikipedia.org/wiki/SHA-1) hash of the downloaded artifact.
Buck verifies this is correct and fails the fetch command if it doesn't match in order to
guarantee repeatable builds.
"""),
"out": attrs.option(attrs.string(), default = None, doc = """
An optional name to call the downloaded artifact. Buck will generate a default name if one is not
provided that uses the `name` of the rule.
"""),
"type": attrs.option(attrs.enum(RemoteFileType), default = None, doc = """
An optional type of the downloaded file.
`data`
Regular data file.
`executable`
Executable file. Buck will ensure that output has appropriate permissions if applicable.
`exploded_zip`
Zip archive which will be automatically unzipped into an output directory.
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"sha256": attrs.option(attrs.string(), default = None),
}
),
)
test_suite = prelude_rule(
name = "test_suite",
docs = """
A `test_suite()` is used to create a grouping of tests that should all be run by just testing this rule.
This rule can then be given to `buck test`, and all tests that it depends on will be invoked.
Note that the test\\_suite() target is not tested itself, it just tells buck to run other
tests. It will not show up in calls to the external runner nor in the normal test output.
""",
examples = """
This test\\_suite() sets up two different sets of tests to run, 'all' tests and 'slow' tests. Note that `all_tests` can depend on `slow_tests`, and all three tests are run.
```
# instrumentation_tests/BUCK:
sh_test(
name = "instrumentation_tests",
test = "instrumentation_tests.sh",
visibility = ["PUBLIC"],
)
# integration_tests/BUCK:
sh_test(
name = "integration_tests",
test = "integration_tests.sh",
visibility = ["PUBLIC"],
)
# unit_tests/BUCK:
sh_test(
name = "unit_tests",
test = "unit_tests.sh",
visibility = ["PUBLIC"],
)
# BUCK:
test_suite(
name = "slow_tests",
tests = [
"//instrumentation_tests:instrumentation_tests",
"//integration_tests:integration_tests",
],
)
test_suite(
name = "all_tests",
tests = [
":slow_tests",
"//unit_tests:unit_tests",
],
)
```
Yields output like this when run:
```
$ buck test //:slow_tests
...
RESULTS FOR //instrumentation_tests:instrumentation_tests //integration_tests:integration_tests
PASS <100ms 1 Passed 0 Skipped 0 Failed //instrumentation_tests:instrumentation_tests
PASS <100ms 1 Passed 0 Skipped 0 Failed //integration_tests:integration_tests
TESTS PASSED
...
$ buck test //:all_tests
RESULTS FOR //instrumentation_tests:instrumentation_tests //integration_tests:integration_tests //unit_tests:unit_tests
PASS <100ms 1 Passed 0 Skipped 0 Failed //instrumentation_tests:instrumentation_tests
PASS <100ms 1 Passed 0 Skipped 0 Failed //integration_tests:integration_tests
PASS <100ms 1 Passed 0 Skipped 0 Failed //unit_tests:unit_tests
TESTS PASSED
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
# On buck1 query, tests attribute on test_suite is treated as deps, while on buck2 it is not.
# While buck2's behavior makes more sense, we want to preserve buck1 behavior on test_suite for now to make TD behavior match between buck1 and buck2.
# This diff makes the behaviors match by adding a test_deps attribute to test_suite on buck2 that is used as a deps attribute. In the macro layer, we set test_deps = tests if we are using buck2.
# For more context: https://fb.prod.workplace.com/groups/603286664133355/posts/682567096205311/?comment_id=682623719532982&reply_comment_id=682650609530293
"test_deps": attrs.list(attrs.dep(), default = []),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
}
),
)
toolchain_alias = prelude_rule(
name = "toolchain_alias",
docs = """
toolchain_alias acts like alias but for toolchain rules.
The toolchain_alias itself is a toolchain rule and the `actual` argument is
expected to be a toolchain_rule as well.
""",
examples = None,
further = None,
attrs = {
"actual": attrs.option(attrs.toolchain_dep(doc = "The actual toolchain that is being aliased. This should be a toolchain rule.")),
},
)
versioned_alias = prelude_rule(
name = "versioned_alias",
docs = "",
examples = None,
further = None,
attrs = (
# @unsorted-dict-items
{
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
"versions": attrs.dict(key = attrs.string(), value = attrs.dep(), sorted = False, default = {}),
}
),
)
worker_tool = prelude_rule(
name = "worker_tool",
docs = """
Some external tools have high startup costs. To amortize those costs over the whole build
rather than paying them for each rule invocation, use the `worker_tool()` rule
in conjunction with `genrule()`.
Buck then starts the external tool once and reuses it by communicating with it
over `stdin` and `stdout` using a simple JSON protocol.
A `worker_tool` rule can be referenced in the `cmd` parameter of
a `genrule` by using the macro:
```
$(exe //path/to:target)
```
""",
examples = """
Consider the following `build rules`:
```
#
# Buck
#
worker_tool(
name = 'ExternalToolWorker',
exe = ':ExternalTool',
args = '--arg1 --arg2'
)
sh_binary(
name = 'ExternalTool',
main = 'external_tool.sh',
)
genrule(
name = 'TransformA',
out = 'OutputA.txt',
cmd = '$(exe :ExternalToolWorker) argA',
)
genrule(
name = 'TransformB',
out = 'OutputB.txt',
cmd = '$(exe :ExternalToolWorker) argB',
)
genrule(
name = 'TransformC',
out = 'OutputC.txt',
cmd = '$(exe :ExternalToolWorker) argC',
)
```
When doing a `buck build` on all three of the above `genrules`, Buck
first creates the worker process by invoking:
```
./external_tool.sh --arg1 --arg2
```
Buck then communicates with this process using JSON over `stdin`,
starting with a handshake:
```
[
{
"id": 0,
"type": "handshake",
"protocol_version": "0",
"capabilities": []
}
```
Buck then waits for the tool to reply on `stdout`:
```
[
{
"id": 0,
"type": "handshake",
"protocol_version": "0",
"capabilities": []
}
```
Then, when building the first `genrule`, Buck writes to `stdin`:
```
,{
"id": 1,
"type": "command",
"args_path": "/tmp/1.args",
"stdout_path": "/tmp/1.out",
"stderr_path": "/tmp/1.err"
}
```
The file `/tmp/1.args` contains `argA`. The tool should
perform the necessary work for this job and then write the job's output to the files
supplied by Buck—in this case, `/tmp/1.out` and `/tmp/1.err`.
Once the job is done, the tool should reply to Buck on `stdout` with:
```
,{
"id": 1,
"type": "result",
"exit_code": 0
}
```
Once Buck hears back from the first genrule's job, it submits the second genrule's job in the
same fashion and awaits the response. When the build is all finished,
Buck closes the JSON by writing to `stdin`:
```
]
```
which signals the tool that it should exit after replying on `stdout` with:
```
]
```
In this example, Buck is guaranteed to invoke
```
./external_tool.sh --arg1 --arg2
```
only once during the build. The three jobs corresponding to the three genrules are submitted
synchronously to the single worker process.
Note that the `id` values in the messages are not necessarily increasing or sequential,
but they do have to match between the request message and the response message of a given job as
well as in the initial handshake.
If the tool receives a message type it cannot interpret it should answer with:
```
{
"id": <n>,
"type": "error",
"exit_code": 1
}
```
If the tool receives a message type it can interpret, but the other attributes of the
message are in an inconsistent state, it should answer with:
```
{
"id": <n>,
"type": "error",
"exit_code": 2
}
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
"exe": attrs.option(attrs.dep(), default = None, doc = """
A `build target` for a rule that outputs
an executable, such as an `sh_binary()`.
Buck runs this executable only once per build.
"""),
"args": attrs.one_of(attrs.arg(), attrs.list(attrs.arg()), default = [], doc = """
A string of args that is passed to the executable represented by `exe` on
initial startup.
"""),
"max_workers": attrs.option(attrs.int(), default = None, doc = """
The maximum number of workers of this type that Buck starts. Use `-1` to allow
the creation of as many workers as necessary.
"""),
"max_workers_per_thread_percent": attrs.option(attrs.int(), default = None, doc = """
The maximum ratio of workers of this type that Buck starts per
thread, specified as a positive integer percentage (1-100). Must be
greater than or equal to `1` and less than or equal to `100`.
Only one of `max_workers` and `max_workers_per_thread_percent` may be specified.
"""),
"env": attrs.dict(key = attrs.string(), value = attrs.arg(), sorted = False, default = {}, doc = """
A map of environment variables that is passed to the executable represented
by `exe` on initial startup.
"""),
"persistent": attrs.option(attrs.bool(), default = None, doc = """
If set to true, Buck does not restart the tool unless the tool itself changes. This means the
tool persists across multiple Buck commands without being shut down and may see the same
rule being built more than once. Be careful not to use this setting with tools that don't expect
to process the same input—with different contents—twice!
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
# FIXME: prelude// should be standalone (not refer to fbsource//)
"_worker_tool_runner": attrs.default_only(attrs.dep(default = "prelude//js/worker_runner:worker_tool_runner")),
}
),
)
zip_file = prelude_rule(
name = "zip_file",
docs = """
A `zip_file()` allows builds to create basic zip files in
a platform-agnostic way.
""",
examples = """
This example will create a simple zip file.
```
zip_file(
# The output will be "example.zip"
name = 'example',
srcs =
# These files will be found in the zip under "dir/"
glob(['dir/**/*']) +
[
# Imagine this generates the output
# "buck-out/gen/foo/hello.txt". This output will
# be found in the zip at "hello.txt"
'//some/other:target',
],
zip_srcs = [
# The contents of this zip will be added to the generated zip.
'amazing-library-1.0-sources.zip',
],
entries_to_exclude = [
"com/example/amazinglibrary/Source1.java",
],
)
```
If you were to examine the generated zip, the contents would look
something like (assuming the output of
"`//some/other:target`" was a file who's path ended with
`hello.txt`, the "`dir`" glob found two files,
and "`amazing-library-1.0-sources.zip`" contained two Java
source files):
```
dir/file1.txt
dir/subdir/file2.txt
hello.txt
com/example/amazinglibrary/Source2.java
```
""",
further = None,
attrs = (
# @unsorted-dict-items
{
"out": attrs.string(default = "", doc = """
The name of the zip file that should be generated. This allows
builds to use a meaningful target name coupled with a meaningful zip
file name. The default value takes the rule's `name` and
appends `.zip`.
"""),
"srcs": attrs.list(attrs.source(), default = [], doc = """
The set of files to include in the zip.
Each `src` will be added to the zip as follows:
* If the `src` is the output of another rule, the output
will be included using just the output's file name.
* If the `src` is a file relative to the rule's
declaration, it will be included in the zip with its relative file
name.
"""),
"zip_srcs": attrs.list(attrs.source(), default = [], doc = """
The set of zip files whose content to include in the output zip file.
Note that the order of files in `zip_srcs` matters because the same zip entry can be
included from multiple files. See the `on_duplicate_entry` argument to learn how to
control the behavior when there are multiple entries with the same name.
The entries from `zip_srcs` are added before files from `srcs`.
"""),
"entries_to_exclude": attrs.list(attrs.regex(), default = [], doc = """
List of regex expressions that describe entries that should not be included in the output zip file.
The regexes must be defined using `java.util.regex.Pattern` syntax.
"""),
"hardcode_permissions_for_deterministic_output": attrs.option(attrs.bool(), default = None, doc = """
If set to true, Buck hardcodes the permissions in order to ensures that all files have the same
permissions regardless of the platform on which the zip was generated.
"""),
"on_duplicate_entry": attrs.enum(OnDuplicateEntry, default = "overwrite", doc = """
Action performed when Buck detects that zip\\_file input contains multiple entries with the same
name.
The valid values are:
* `overwrite` (default): the last entry overwrites all previous entries with
the same name.
* `append`: all entries are added to the output file.
* `fail`: fail the build when duplicate entries are present.
"""),
"contacts": attrs.list(attrs.string(), default = []),
"default_host_platform": attrs.option(attrs.configuration_label(), default = None),
"labels": attrs.list(attrs.string(), default = []),
"licenses": attrs.list(attrs.source(), default = []),
}
),
)
core_rules = struct(
alias = alias,
command_alias = command_alias,
config_setting = config_setting,
configuration_alias = configuration_alias,
configured_alias = configured_alias,
constraint_setting = constraint_setting,
constraint_value = constraint_value,
export_file = export_file,
external_test_runner = external_test_runner,
filegroup = filegroup,
genrule = genrule,
http_archive = http_archive,
http_file = http_file,
platform = platform,
remote_file = remote_file,
test_suite = test_suite,
toolchain_alias = toolchain_alias,
versioned_alias = versioned_alias,
worker_tool = worker_tool,
zip_file = zip_file,
)