diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 6269b83915..cf9b700f6e 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -15,7 +15,14 @@ # buildifier: disable=module-docstring load("//rust/private:common.bzl", "rust_common") load("//rust/private:rustc.bzl", "rustc_compile_action") -load("//rust/private:utils.bzl", "crate_name_from_attr", "determine_output_hash", "expand_locations", "find_toolchain") +load( + "//rust/private:utils.bzl", + "crate_name_from_attr", + "dedent", + "determine_output_hash", + "expand_locations", + "find_toolchain", +) # TODO(marco): Separate each rule into its own file. @@ -512,45 +519,16 @@ def _rust_benchmark_impl(ctx): ), ] -def _tidy(doc_string): - """Tidy excess whitespace in docstrings to not break index.md - - Args: - doc_string (str): A docstring style string - - Returns: - str: A string optimized for stardoc rendering - """ - lines = doc_string.splitlines() - if not lines: - return doc_string - - # If the first line is empty, use the second line - first_line = lines[0] - if not first_line: - first_line = lines[1] - - # Detect how much space prepends the first line and subtract that from all lines - space_count = len(first_line) - len(first_line.lstrip()) - - # If there are no leading spaces, do not alter the docstring - if space_count == 0: - return doc_string - else: - # Remove the leading block of spaces from the current line - block = " " * space_count - return "\n".join([line.replace(block, "", 1).rstrip() for line in lines]) - _common_attrs = { "aliases": attr.label_keyed_string_dict( - doc = _tidy("""\ + doc = dedent("""\ Remap crates to a new name or moniker for linkage to this target These are other `rust_library` targets and will be presented as the new name given. """), ), "compile_data": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ List of files used by this rule at compile time. This attribute can be used to specify any data files that are embedded into @@ -561,7 +539,7 @@ _common_attrs = { allow_files = True, ), "crate_features": attr.string_list( - doc = _tidy("""\ + doc = dedent("""\ List of features to enable for this crate. Features are defined in the code using the `#[cfg(feature = "foo")]` @@ -570,7 +548,7 @@ _common_attrs = { """), ), "crate_name": attr.string( - doc = _tidy("""\ + doc = dedent("""\ Crate name to use for this target. This must be a valid Rust identifier, i.e. it may contain only alphanumeric characters and underscores. @@ -578,7 +556,7 @@ _common_attrs = { """), ), "crate_root": attr.label( - doc = _tidy("""\ + doc = dedent("""\ The file that will be passed to `rustc` to be used for building this crate. If `crate_root` is not set, then this rule will look for a `lib.rs` file (or `main.rs` for rust_binary) @@ -587,7 +565,7 @@ _common_attrs = { allow_single_file = [".rs"], ), "data": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ List of files used by this rule at compile time and runtime. If including data at compile time with include_str!() and similar, @@ -597,7 +575,7 @@ _common_attrs = { allow_files = True, ), "deps": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ List of other libraries to be linked to this library target. These can be either other `rust_library` targets or `cc_library` targets if @@ -612,14 +590,14 @@ _common_attrs = { # This fails for remote execution, which needs cfg="exec", and there isn't anything like # `@local_config_platform//:exec` exposed. "proc_macro_deps": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ List of `rust_library` targets with kind `proc-macro` used to help build this library target. """), cfg = "exec", providers = [rust_common.crate_info], ), "rustc_env": attr.string_dict( - doc = _tidy("""\ + doc = dedent("""\ Dictionary of additional `"key": "value"` environment variables to set for rustc. rust_test()/rust_binary() rules can use $(rootpath //package:target) to pass in the @@ -630,7 +608,7 @@ _common_attrs = { """), ), "rustc_env_files": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ Files containing additional environment variables to set for rustc. These files should contain a single variable per line, of format @@ -649,7 +627,7 @@ _common_attrs = { # doc = "This name will also be used as the name of the crate built by this rule.", # `), "srcs": attr.label_list( - doc = _tidy("""\ + doc = dedent("""\ List of Rust `.rs` source files used to build the library. If `srcs` contains more than one file, then there must be a file either @@ -677,7 +655,7 @@ _common_attrs = { _rust_test_attrs = { "crate": attr.label( mandatory = False, - doc = _tidy("""\ + doc = dedent("""\ Target inline tests declared in the given crate These tests are typically those that would be held out under @@ -686,7 +664,7 @@ _rust_test_attrs = { ), "env": attr.string_dict( mandatory = False, - doc = _tidy("""\ + doc = dedent("""\ Specifies additional environment variables to set when the test is executed by bazel test. Values are subject to `$(execpath)` and ["Make variable"](https://docs.bazel.build/versions/master/be/make-variables.html) substitution. @@ -695,7 +673,7 @@ _rust_test_attrs = { "use_libtest_harness": attr.bool( mandatory = False, default = True, - doc = _tidy("""\ + doc = dedent("""\ Whether to use libtest. """), ), @@ -703,7 +681,7 @@ _rust_test_attrs = { executable = True, default = Label("//util/launcher:launcher"), cfg = "exec", - doc = _tidy("""\ + doc = dedent("""\ A launcher executable for loading environment and argument files passed in via the `env` attribute and ensuring the variables are set for the underlying test executable. """), @@ -727,7 +705,7 @@ rust_library = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust library crate. Example: @@ -804,7 +782,7 @@ rust_static_library = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust static library. This static library will contain all transitively reachable crates and native objects. @@ -828,7 +806,7 @@ rust_shared_library = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust shared library. This shared library will contain all transitively reachable crates and native objects. @@ -852,14 +830,14 @@ rust_proc_macro = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust proc-macro crate. """), ) _rust_binary_attrs = { "crate_type": attr.string( - doc = _tidy("""\ + doc = dedent("""\ Crate type that will be passed to `rustc` to be used for building this crate. This option is a temporary workaround and should be used only when building @@ -868,7 +846,7 @@ _rust_binary_attrs = { default = "bin", ), "linker_script": attr.label( - doc = _tidy("""\ + doc = dedent("""\ Link script to forward into linker via rustc options. """), cfg = "exec", @@ -889,7 +867,7 @@ rust_binary = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust binary crate. Example: @@ -989,7 +967,7 @@ rust_test = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust test crate. Examples: @@ -1139,7 +1117,7 @@ rust_test_binary = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust test binary, without marking this rule as a Bazel test. **Warning**: This rule is currently experimental. @@ -1238,7 +1216,7 @@ rust_benchmark = rule( "@bazel_tools//tools/cpp:toolchain_type", ], incompatible_use_toolchain_transition = True, - doc = _tidy("""\ + doc = dedent("""\ Builds a Rust benchmark test. **Warning**: This rule is currently experimental. [Rust Benchmark tests][rust-bench] \ diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index ac455848a5..9a70c51416 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -241,3 +241,32 @@ def crate_name_from_attr(attr): "Consider adding a crate_name attribute to set a valid crate name", ) return crate_name + +def dedent(doc_string): + """Tidy excess whitespace in docstrings to not break index.md + + Args: + doc_string (str): A docstring style string + + Returns: + str: A string optimized for stardoc rendering + """ + lines = doc_string.splitlines() + if not lines: + return doc_string + + # If the first line is empty, use the second line + first_line = lines[0] + if not first_line: + first_line = lines[1] + + # Detect how much space prepends the first line and subtract that from all lines + space_count = len(first_line) - len(first_line.lstrip()) + + # If there are no leading spaces, do not alter the docstring + if space_count == 0: + return doc_string + else: + # Remove the leading block of spaces from the current line + block = " " * space_count + return "\n".join([line.replace(block, "", 1).rstrip() for line in lines])