Skip to content

Commit

Permalink
Added crate attribute to rustdoc rules (deprecated dep)
Browse files Browse the repository at this point in the history
  • Loading branch information
UebelAndre committed Jun 26, 2021
1 parent 678ab71 commit c52b371
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 41 deletions.
44 changes: 30 additions & 14 deletions rust/private/rustdoc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -62,34 +62,42 @@ def _rust_doc_impl(ctx):
Args:
ctx (ctx): The rule's context object
"""
if rust_common.crate_info not in ctx.attr.dep:
fail("Expected rust_library or rust_binary.", "dep")

crate = ctx.attr.dep[rust_common.crate_info]
dep_info = ctx.attr.dep[rust_common.dep_info]
if ctx.attr.crate and ctx.attr.dep:
fail("{} should only use the `crate` attribute. `dep` is deprecated".format(
ctx.label,
))

crate = ctx.attr.crate or ctx.attr.dep
if not crate:
fail("{} is missing the `crate` attribute".format(ctx.label))

crate_info = crate[rust_common.crate_info]
dep_info = crate[rust_common.dep_info]

toolchain = find_toolchain(ctx)

rustdoc_inputs = depset(
[c.output for c in dep_info.transitive_crates.to_list()] +
[toolchain.rust_doc],
transitive = [
crate.srcs,
crate_info.srcs,
toolchain.rustc_lib.files,
toolchain.rust_lib.files,
],
)

output_dir = ctx.actions.declare_directory(ctx.label.name)
args = ctx.actions.args()
args.add(crate.root.path)
args.add("--crate-name", crate.name)
args.add("--crate-type", crate.type)
if crate.type == "proc-macro":
args.add(crate_info.root.path)
args.add("--crate-name", crate_info.name)
args.add("--crate-type", crate_info.type)
args.add("--output", output_dir.path)
add_edition_flags(args, crate_info)

if crate_info.type == "proc-macro":
args.add("--extern")
args.add("proc_macro")
args.add("--output", output_dir.path)
add_edition_flags(args, crate)

# nb. rustdoc can't do anything with native link flags; we must omit them.
add_crate_link_flags(args, dep_info)
Expand All @@ -108,7 +116,10 @@ def _rust_doc_impl(ctx):
outputs = [output_dir],
arguments = [args],
mnemonic = "Rustdoc",
progress_message = "Generating rustdoc for {} ({} files)".format(crate.name, len(crate.srcs.to_list())),
progress_message = "Generating rustdoc for {} ({} files)".format(
crate_info.name,
len(crate_info.srcs.to_list()),
),
)

# This rule does nothing without a single-file output, though the directory should've sufficed.
Expand Down Expand Up @@ -139,14 +150,19 @@ rust_doc = rule(
doc = _rust_doc_doc,
implementation = _rust_doc_impl,
attrs = {
"dep": attr.label(
"crate": attr.label(
doc = (
"The label of the target to generate code documentation for.\n" +
"\n" +
"`rust_doc` can generate HTML code documentation for the source files of " +
"`rust_library` or `rust_binary` targets."
),
mandatory = True,
providers = [rust_common.crate_info],
# TODO: Make this attribute mandatory once `dep` is removed
),
"dep": attr.label(
doc = "__deprecated__: use `crate`",
providers = [rust_common.crate_info],
),
"html_after_content": attr.label(
doc = "File to add in `<body>`, after content.",
Expand Down
65 changes: 38 additions & 27 deletions rust/private/rustdoc_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,36 @@ def _rust_doc_test_impl(ctx):
Returns:
list: A list containing a DefaultInfo provider
"""
if rust_common.crate_info not in ctx.attr.dep:
fail("Expected rust library or binary.", "dep")
if ctx.attr.crate and ctx.attr.dep:
fail("{} should only use the `crate` attribute. `dep` is deprecated".format(
ctx.label,
))

crate = ctx.attr.dep[rust_common.crate_info]
crate = ctx.attr.crate or ctx.attr.dep
if not crate:
fail("{} is missing the `crate` attribute".format(ctx.label))

toolchain = find_toolchain(ctx)

dep_info = ctx.attr.dep[rust_common.dep_info]
crate_info = crate[rust_common.crate_info]
dep_info = crate[rust_common.dep_info]

# Construct rustdoc test command, which will be written to a shell script
# to be executed to run the test.
flags = _build_rustdoc_flags(dep_info, crate)
flags = _build_rustdoc_flags(dep_info, crate_info)
if toolchain.os != "windows":
rust_doc_test = _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate)
rust_doc_test = _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate_info)
else:
rust_doc_test = _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate)
rust_doc_test = _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate_info)

# The test script compiles the crate and runs it, so it needs both compile and runtime inputs.
compile_inputs = depset(
[crate.output] +
[crate_info.output] +
[toolchain.rust_doc] +
[toolchain.rustc] +
toolchain.crosstool_files,
transitive = [
crate.srcs,
crate_info.srcs,
dep_info.transitive_libs,
toolchain.rustc_lib.files,
toolchain.rust_lib.files,
Expand Down Expand Up @@ -77,12 +82,12 @@ def _dirname(path_str):
"""
return "/".join(path_str.split("/")[:-1])

def _build_rustdoc_flags(dep_info, crate):
def _build_rustdoc_flags(dep_info, crate_info):
"""Constructs the rustdoc script used to test `crate`.
Args:
dep_info (DepInfo): The DepInfo provider
crate (CrateInfo): The CrateInfo provider
crate_info (CrateInfo): The CrateInfo provider
Returns:
list: A list of rustdoc flags (str)
Expand All @@ -94,7 +99,7 @@ def _build_rustdoc_flags(dep_info, crate):
link_flags = []
link_search_flags = []

link_flags.append("--extern=" + crate.name + "=" + crate.output.short_path)
link_flags.append("--extern=" + crate_info.name + "=" + crate_info.output.short_path)
link_flags += ["--extern=" + c.name + "=" + c.dep.output.short_path for c in d.direct_crates.to_list()]
link_search_flags += ["-Ldependency={}".format(_dirname(c.output.short_path)) for c in d.transitive_crates.to_list()]

Expand All @@ -109,10 +114,10 @@ def _build_rustdoc_flags(dep_info, crate):
link_flags.append("-Lnative={}".format(_dirname(f.short_path)))
link_search_flags.append("-Lnative={}".format(_dirname(f.short_path)))

if crate.type == "proc-macro":
link_flags.extend(["--extern", "proc_macro"])
edition_flags = ["--edition={}".format(crate_info.edition)] if crate_info.edition != "2015" else []

edition_flags = ["--edition={}".format(crate.edition)] if crate.edition != "2015" else []
if crate_info.type == "proc-macro":
link_flags.extend(["--extern", "proc_macro"])

return link_search_flags + link_flags + edition_flags

Expand All @@ -127,14 +132,14 @@ set -e;
{flags}
"""

def _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate):
def _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate_info):
"""Generates a helper script for executing a rustdoc test for unix systems
Args:
ctx (ctx): The `rust_doc_test` rule's context object
toolchain (ToolchainInfo): A rustdoc toolchain
flags (list): A list of rustdoc flags (str)
crate (CrateInfo): The CrateInfo provider
crate_info (CrateInfo): The CrateInfo provider
Returns:
File: An executable containing information for a rustdoc test
Expand All @@ -146,8 +151,8 @@ def _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate):
output = rust_doc_test,
content = _rustdoc_test_bash_script.format(
rust_doc = toolchain.rust_doc.short_path,
crate_root = crate.root.path,
crate_name = crate.name,
crate_root = crate_info.root.path,
crate_name = crate_info.name,
# TODO: Should be possible to do this with ctx.actions.Args, but can't seem to get them as a str and into the template.
flags = " \\\n ".join(flags),
),
Expand All @@ -156,20 +161,22 @@ def _build_rustdoc_test_bash_script(ctx, toolchain, flags, crate):
return rust_doc_test

_rustdoc_test_batch_script = """\
@ECHO OFF
{rust_doc} --test ^
{crate_root} ^
--crate-name={crate_name} ^
{flags}
"""

def _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate):
def _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate_info):
"""Generates a helper script for executing a rustdoc test for windows systems
Args:
ctx (ctx): The `rust_doc_test` rule's context object
toolchain (ToolchainInfo): A rustdoc toolchain
flags (list): A list of rustdoc flags (str)
crate (CrateInfo): The CrateInfo provider
crate_info (CrateInfo): The CrateInfo provider
Returns:
File: An executable containing information for a rustdoc test
Expand All @@ -181,8 +188,8 @@ def _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate):
output = rust_doc_test,
content = _rustdoc_test_batch_script.format(
rust_doc = toolchain.rust_doc.short_path.replace("/", "\\"),
crate_root = crate.root.path,
crate_name = crate.name,
crate_root = crate_info.root.path,
crate_name = crate_info.name,
# TODO: Should be possible to do this with ctx.actions.Args, but can't seem to get them as a str and into the template.
flags = " ^\n ".join(flags),
),
Expand All @@ -193,14 +200,18 @@ def _build_rustdoc_test_batch_script(ctx, toolchain, flags, crate):
rust_doc_test = rule(
implementation = _rust_doc_test_impl,
attrs = {
"dep": attr.label(
"crate": attr.label(
doc = (
"The label of the target to run documentation tests for.\n" +
"The label of the target to generate code documentation for.\n" +
"\n" +
"`rust_doc_test` can run documentation tests for the source files of " +
"`rust_doc` can generate HTML code documentation for the source files of " +
"`rust_library` or `rust_binary` targets."
),
mandatory = True,
providers = [rust_common.crate_info],
# TODO: Make this attribute mandatory once `dep` is removed
),
"dep": attr.label(
doc = "__deprecated__: use `crate`",
providers = [rust_common.crate_info],
),
},
Expand Down

0 comments on commit c52b371

Please sign in to comment.