bazel-skylib/lib/selects.bzl

83 lines
2.6 KiB
Python
Raw Normal View History

2017-10-10 14:59:31 +00:00
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Skylib module containing convenience interfaces for select()."""
def _with_or(input_dict, no_match_error = ""):
"""Drop-in replacement for `select()` that supports ORed keys.
2017-10-10 14:59:31 +00:00
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.
2017-10-10 14:59:31 +00:00
Example:
2017-10-10 14:59:31 +00:00
```build
deps = selects.with_or({
"//configs:one": [":dep1"],
("//configs:two", "//configs:three"): [":dep2or3"],
"//configs:four": [":dep4"],
"//conditions:default": [":default"]
})
```
2017-10-10 14:59:31 +00:00
Key labels may appear at most once anywhere in the input.
2017-10-10 14:59:31 +00:00
Returns:
A native `select()` that expands
2017-10-10 14:59:31 +00:00
`("//configs:two", "//configs:three"): [":dep2or3"]`
2017-10-10 14:59:31 +00:00
to
2017-10-10 14:59:31 +00:00
```build
"//configs:two": [":dep2or3"],
"//configs:three": [":dep2or3"],
```
"""
return select(_with_or_dict(input_dict), no_match_error = no_match_error)
2017-10-10 14:59:31 +00:00
def _with_or_dict(input_dict):
"""Variation of `with_or` that returns the dict of the `select()`.
Unlike `select()`, the contents of the dict can be inspected by Starlark
macros.
Args:
input_dict: Same as `with_or`.
Returns:
A dictionary usable by 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.keys():
fail("key %s appears multiple times" % config_setting)
output_dict[config_setting] = value
else:
if key in output_dict.keys():
fail("key %s appears multiple times" % key)
output_dict[key] = value
return output_dict
2017-10-10 14:59:31 +00:00
selects = struct(
with_or = _with_or,
with_or_dict = _with_or_dict,
2017-10-10 14:59:31 +00:00
)