Skip to content

Commit

Permalink
Add more examples: runfiles, mandatory provider, optional provider
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentlb committed Dec 15, 2017
1 parent 464d62a commit 5d1e5bd
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 0 deletions.
9 changes: 9 additions & 0 deletions rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ passing information from a dependency to a target.

* [default outputs](default_outputs/): Example of a rule with a declared output.

* [mandatory provider](mandatory_provider/): Example with a mandatory provider,
to access information from a dependency.

* [optional provider](optional_provider/): Example with an optional provider,
to access information from a dependency.

* [depsets](depsets/): Example of a using a depset to gather transitive
information. Each target collects data from its dependencies.

Expand All @@ -36,6 +42,9 @@ control on the behavior of the rules.

* [test rule](test_rule/): Example of a test rule.

* [runfiles](runfiles/): Example of an executable rule with runfiles (files
required at runtime).

* [computed dependencies](computed_dependencies/): Example with computed
dependencies. The set of implicit dependencies depends on the rule attributes.

Expand Down
4 changes: 4 additions & 0 deletions rules/attributes/printer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def _impl(ctx):
# A label can represent any number of files (possibly 0).
print(" files = " + str([f.path for f in d.files.to_list()]))

# For debugging, consider using `dir` to explore the existing fields.
print(dir(ctx)) # prints all the fields and methods of ctx
print(dir(ctx.attr)) # prints all the attributes of the rule

printer = rule(
implementation=_impl,
attrs={
Expand Down
19 changes: 19 additions & 0 deletions rules/mandatory_provider/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
load(":sum.bzl", "sum")

sum(
name = "n",
deps = [
":n2",
":n5",
],
)

sum(
name = "n2",
number = 2,
)

sum(
name = "n5",
number = 5,
)
28 changes: 28 additions & 0 deletions rules/mandatory_provider/sum.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Rule with a mandatory provider.
In this example, rules have a number attribute. Each rule adds its number
with the numbers of its transitive dependencies, and write the result in a
file. This shows how to transfer information from a dependency to its
dependents.
"""

NumberInfo = provider("number")

def _impl(ctx):
result = ctx.attr.number
for dep in ctx.attr.deps:
result += dep[NumberInfo].number
ctx.file_action(output=ctx.outputs.out, content=str(result))

# Return the provider with result, visible to other rules.
return [NumberInfo(number=result)]

sum = rule(
implementation=_impl,
attrs={
"number": attr.int(default=1),
# All deps must provide all listed providers.
"deps": attr.label_list(providers=[NumberInfo]),
},
outputs = {"out": "%{name}.sum"}
)
19 changes: 19 additions & 0 deletions rules/optional_provider/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
load(":sum.bzl", "sum")

sum(
name = "n",
deps = [
":n2",
":n5",
],
)

sum(
name = "n2",
number = 2,
)

sum(
name = "n5",
number = 5,
)
28 changes: 28 additions & 0 deletions rules/optional_provider/sum.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Rule with an optional provider.
In this example, rules have a number attribute. Each rule adds its number
with the numbers of its transitive dependencies, and write the result in a
file. This shows how to transfer information from a dependency to its
dependents. Dependencies are not required to provide a number.
"""

NumberInfo = provider("number")

def _impl(ctx):
result = ctx.attr.number
for dep in ctx.attr.deps:
if NumberInfo in dep:
result += dep[NumberInfo].number
ctx.file_action(output=ctx.outputs.out, content=str(result))

# Return the provider with result, visible to other rules.
return [NumberInfo(number=result)]

sum = rule(
implementation=_impl,
attrs={
"number": attr.int(default=1),
"deps": attr.label_list(),
},
outputs = {"out": "%{name}.sum"}
)
12 changes: 12 additions & 0 deletions rules/runfiles/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load(":execute.bzl", "execute")

# `bazel build //runfiles:all` will create an executable.
# `bazel run //runfiles:all` will run it.
execute(
name = "e",
# The location will be expanded to "pkg/data.txt", and it will reference
# the data.txt file in runfiles when this target is invoked as
# "bazel run //pkg:e".
command = "cat $(location :data.txt)",
data = [":data.txt"],
)
1 change: 1 addition & 0 deletions rules/runfiles/data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello world!
34 changes: 34 additions & 0 deletions rules/runfiles/execute.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Create an executable with runfiles.
Runfiles are files that are needed at runtime (when the executable in run).
This example also shows a use of `ctx.expand_location`.
"""

def _impl(ctx):
# Expand the label in the command string to a runfiles-relative path.
# The second arg is the list of labels that may be expanded.
command = ctx.expand_location(ctx.attr.command, ctx.attr.data)

# Create the output executable file with command as its content.
ctx.file_action(
output=ctx.outputs.executable,
content=command,
executable=True)

# Create runfiles from the files specified in the data attribute.
# The shell executable - the output of this rule - can use them at
# runtime. It is also possible to define data_runfiles and
# default_runfiles. However if runfiles is specified it's not possible to
# define the above ones since runfiles sets them both.
return [DefaultInfo(
runfiles=ctx.runfiles(files=ctx.files.data)
)]

execute = rule(
implementation=_impl,
executable=True,
attrs={
"command": attr.string(),
"data": attr.label_list(allow_files=True),
},
)

0 comments on commit 5d1e5bd

Please sign in to comment.