• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Macros used for represeting crates or annotations for existing crates"""
2
3load(":common_utils.bzl", "parse_alias_rule")
4
5def _workspace_member(version, sha256 = None):
6    """Define information for extra workspace members
7
8    Args:
9        version (str): The semver of the crate to download. Must be an exact version.
10        sha256 (str, optional): The sha256 checksum of the `.crate` file.
11
12    Returns:
13        string: A json encoded string of all inputs
14    """
15    return json.encode(struct(
16        version = version,
17        sha256 = sha256,
18    ))
19
20def _spec(
21        package = None,
22        version = None,
23        artifact = None,
24        lib = None,
25        default_features = True,
26        features = [],
27        git = None,
28        branch = None,
29        tag = None,
30        rev = None):
31    """A constructor for a crate dependency.
32
33    See [specifying dependencies][sd] in the Cargo book for more details.
34
35    [sd]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
36
37    Args:
38        package (str, optional): The explicit name of the package (used when attempting to alias a crate).
39        version (str, optional): The exact version of the crate. Cannot be used with `git`.
40        artifact (str, optional): Set to "bin" to pull in a binary crate as an artifact dependency. Requires a nightly Cargo.
41        lib (bool, optional): If using `artifact = "bin"`, additionally setting `lib = True` declares a dependency on both the package's library and binary, as opposed to just the binary.
42        default_features (bool, optional): Maps to the `default-features` flag.
43        features (list, optional): A list of features to use for the crate
44        git (str, optional): The Git url to use for the crate. Cannot be used with `version`.
45        branch (str, optional): The git branch of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds.
46        tag (str, optional): The git tag of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified. Specifying `rev` is recommended for fully-reproducible builds.
47        rev (str, optional): The git revision of the remote crate. Tied with the `git` param. Only one of branch, tag or rev may be specified.
48
49    Returns:
50        string: A json encoded string of all inputs
51    """
52    return json.encode({
53        k: v
54        for k, v in {
55            "artifact": artifact,
56            "branch": branch,
57            "default_features": default_features,
58            "features": features,
59            "git": git,
60            "lib": lib,
61            "package": package,
62            "rev": rev,
63            "tag": tag,
64            "version": version,
65        }.items()
66        # The `cargo_toml` crate parses unstable fields to a flattened
67        # BTreeMap<String, toml::Value> and toml::Value does not support null,
68        # so we must omit null values.
69        if v != None
70    })
71
72def _assert_absolute(label):
73    """Ensure a given label is an absolute label
74
75    Args:
76        label (Label): The label to check
77    """
78    label_str = str(label)
79    if not label_str.startswith("@"):
80        fail("The labels must be absolute. Please update '{}'".format(
81            label_str,
82        ))
83
84# This should be kept in sync crate_universe/extension.bzl.
85def _annotation(
86        version = "*",
87        additive_build_file = None,
88        additive_build_file_content = None,
89        alias_rule = None,
90        build_script_data = None,
91        build_script_tools = None,
92        build_script_data_glob = None,
93        build_script_deps = None,
94        build_script_env = None,
95        build_script_proc_macro_deps = None,
96        build_script_rundir = None,
97        build_script_rustc_env = None,
98        build_script_toolchains = None,
99        compile_data = None,
100        compile_data_glob = None,
101        crate_features = None,
102        data = None,
103        data_glob = None,
104        deps = None,
105        extra_aliased_targets = None,
106        gen_binaries = None,
107        disable_pipelining = False,
108        gen_build_script = None,
109        patch_args = None,
110        patch_tool = None,
111        patches = None,
112        proc_macro_deps = None,
113        rustc_env = None,
114        rustc_env_files = None,
115        rustc_flags = None,
116        shallow_since = None):
117    """A collection of extra attributes and settings for a particular crate
118
119    Args:
120        version (str, optional): The version or semver-conditions to match with a crate. The wildcard `*`
121            matches any version, including prerelease versions.
122        additive_build_file_content (str, optional): Extra contents to write to the bottom of generated BUILD files.
123        additive_build_file (str, optional): A file containing extra contents to write to the bottom of
124            generated BUILD files.
125        alias_rule (str, optional): Alias rule to use instead of `native.alias()`.  Overrides [render_config](#render_config)'s
126            'default_alias_rule'.
127        build_script_data (list, optional): A list of labels to add to a crate's `cargo_build_script::data` attribute.
128        build_script_tools (list, optional): A list of labels to add to a crate's `cargo_build_script::tools` attribute.
129        build_script_data_glob (list, optional): A list of glob patterns to add to a crate's `cargo_build_script::data`
130            attribute.
131        build_script_deps (list, optional): A list of labels to add to a crate's `cargo_build_script::deps` attribute.
132        build_script_env (dict, optional): Additional environment variables to set on a crate's
133            `cargo_build_script::env` attribute.
134        build_script_proc_macro_deps (list, optional): A list of labels to add to a crate's
135            `cargo_build_script::proc_macro_deps` attribute.
136        build_script_rundir (str, optional): An override for the build script's rundir attribute.
137        build_script_rustc_env (dict, optional): Additional environment variables to set on a crate's
138            `cargo_build_script::env` attribute.
139        build_script_toolchains (list, optional): A list of labels to set on a crates's `cargo_build_script::toolchains` attribute.
140        compile_data (list, optional): A list of labels to add to a crate's `rust_library::compile_data` attribute.
141        compile_data_glob (list, optional): A list of glob patterns to add to a crate's `rust_library::compile_data`
142            attribute.
143        crate_features (optional): A list of strings to add to a crate's `rust_library::crate_features`
144            attribute.
145        data (list, optional): A list of labels to add to a crate's `rust_library::data` attribute.
146        data_glob (list, optional): A list of glob patterns to add to a crate's `rust_library::data` attribute.
147        deps (list, optional): A list of labels to add to a crate's `rust_library::deps` attribute.
148        extra_aliased_targets (dict, optional): A list of targets to add to the generated aliases in the root
149            crate_universe repository.
150        gen_binaries (list or bool, optional): As a list, the subset of the crate's bins that should get `rust_binary`
151            targets produced. Or `True` to generate all, `False` to generate none.
152        disable_pipelining (bool, optional): If True, disables pipelining for library targets for this crate.
153        gen_build_script (bool, optional): An authorative flag to determine whether or not to produce
154            `cargo_build_script` targets for the current crate.
155        patch_args (list, optional): The `patch_args` attribute of a Bazel repository rule. See
156            [http_archive.patch_args](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patch_args)
157        patch_tool (string, optional): The `patch_tool` attribute of a Bazel repository rule. See
158            [http_archive.patch_tool](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patch_tool)
159        patches (list, optional): The `patches` attribute of a Bazel repository rule. See
160            [http_archive.patches](https://docs.bazel.build/versions/main/repo/http.html#http_archive-patches)
161        proc_macro_deps (list, optional): A list of labels to add to a crate's `rust_library::proc_macro_deps`
162            attribute.
163        rustc_env (dict, optional): Additional variables to set on a crate's `rust_library::rustc_env` attribute.
164        rustc_env_files (list, optional): A list of labels to set on a crate's `rust_library::rustc_env_files`
165            attribute.
166        rustc_flags (list, optional): A list of strings to set on a crate's `rust_library::rustc_flags` attribute.
167        shallow_since (str, optional): An optional timestamp used for crates originating from a git repository
168            instead of a crate registry. This flag optimizes fetching the source code.
169
170    Returns:
171        string: A json encoded string containing the specified version and separately all other inputs.
172    """
173    if additive_build_file:
174        _assert_absolute(additive_build_file)
175    if patches:
176        for patch in patches:
177            _assert_absolute(patch)
178
179    return json.encode((
180        version,
181        struct(
182            additive_build_file = _stringify_label(additive_build_file),
183            additive_build_file_content = additive_build_file_content,
184            alias_rule = parse_alias_rule(alias_rule),
185            build_script_data = _stringify_list(build_script_data),
186            build_script_tools = _stringify_list(build_script_tools),
187            build_script_data_glob = build_script_data_glob,
188            build_script_deps = _stringify_list(build_script_deps),
189            build_script_env = build_script_env,
190            build_script_proc_macro_deps = _stringify_list(build_script_proc_macro_deps),
191            build_script_rundir = build_script_rundir,
192            build_script_rustc_env = build_script_rustc_env,
193            build_script_toolchains = _stringify_list(build_script_toolchains),
194            compile_data = _stringify_list(compile_data),
195            compile_data_glob = compile_data_glob,
196            crate_features = crate_features,
197            data = _stringify_list(data),
198            data_glob = data_glob,
199            deps = _stringify_list(deps),
200            extra_aliased_targets = extra_aliased_targets,
201            gen_binaries = gen_binaries,
202            disable_pipelining = disable_pipelining,
203            gen_build_script = gen_build_script,
204            patch_args = patch_args,
205            patch_tool = patch_tool,
206            patches = _stringify_list(patches),
207            proc_macro_deps = _stringify_list(proc_macro_deps),
208            rustc_env = rustc_env,
209            rustc_env_files = _stringify_list(rustc_env_files),
210            rustc_flags = rustc_flags,
211            shallow_since = shallow_since,
212        ),
213    ))
214
215def _stringify_label(value):
216    if not value:
217        return value
218    return str(value)
219
220# In bzlmod, attributes of type `attr.label_list` end up as `Label`s not `str`,
221# and the `json` module doesn't know how to serialize `Label`s,
222# so we proactively convert them to strings before serializing.
223def _stringify_list(values):
224    if not values:
225        return values
226    return [str(x) for x in values]
227
228def _select(common, selects):
229    """A Starlark Select for `crate.annotation()`.
230
231    Args:
232        common: A value that applies to all configurations.
233        selects (dict): A dict of `target_triple` to values.
234
235    Returns:
236        struct: A struct representing the Starlark Select.
237    """
238    return struct(
239        common = common,
240        selects = selects,
241    )
242
243crate = struct(
244    spec = _spec,
245    annotation = _annotation,
246    workspace_member = _workspace_member,
247    select = _select,
248)
249