blob: bcbad19afb37ec623b5cbbe1b3767dda88edd4da [file] [log] [blame]
"""A helper module solving for complex select statements in rendered cargo-bazel modules"""
def select_with_or(input_dict, no_match_error = ""):
"""Drop-in replacement for `select()` that supports ORed keys.
This is notably different from [@bazel_skylib//lib:selects.bzl%selects.with_or][swo] in that
the input dict must have a list as it's values and they keys will continue to expand for each
entry instead of failing on duplicates.
Example:
```starlark
deps = selects.with_or({
"//configs:one": [":dep1"],
("//configs:two", "//configs:three"): [":dep2or3"],
"//configs:four": [":dep4"],
"//conditions:default": [":default"]
})
```
Key labels may appear at most once anywhere in the input.
This macro eturns a native `select` that expands `("//configs:two", "//configs:three"): [":dep2or3"]` to
```starlark
"//configs:two": [":dep2or3"],
"//configs:three": [":dep2or3"],
```
[swo]: https://github.com/bazelbuild/bazel-skylib/blob/1.1.1/docs/selects_doc.md#selectswith_or
Args:
input_dict: The same dictionary `select()` takes, except keys may take
either the usual form `"//foo:config1"` or
`("//foo:config1", "//foo:config2", ...)` to signify
`//foo:config1` OR `//foo:config2` OR `...`.
no_match_error: Optional custom error to report if no condition matches.
Returns:
A native `select()`
"""
output_dict = {}
for (key, value) in input_dict.items():
if type(key) == type(()):
for config_setting in key:
if config_setting in output_dict:
output_dict[config_setting].extend(value)
else:
output_dict[config_setting] = list(value)
elif key in output_dict:
output_dict[key].extend(value)
else:
output_dict[key] = list(value)
# return a dict with deduped lists
return select(
{key: depset(value).to_list() for key, value in output_dict.items()},
no_match_error = no_match_error,
)