diff --git a/docs/selects_doc.md b/docs/selects_doc.md index 8e2f31b3..bf013645 100755 --- a/docs/selects_doc.md +++ b/docs/selects_doc.md @@ -79,7 +79,7 @@ A dictionary usable by a native `select()`. ## selects.config_setting_group
-selects.config_setting_group(name, match_any, match_all, visibility) +selects.config_setting_group(name, match_any, match_all, visibility, negated)Matches if all or any of its member `config_setting`s match. @@ -115,5 +115,6 @@ Example: | match_any | A list of
config_settings
. This group matches if *any* member in the list matches. If this is set, match_all
must not be set. | []
|
| match_all | A list of config_settings
. This group matches if *every* member in the list matches. If this is set, match_any
must be not set. | []
|
| visibility | Visibility of the config_setting_group. | None
|
+| negated | If set, this argument should list a subset of the targets passed to any_of
or all_of
. The targets listed here will be negated, such that groups can express things such as "match :condition1 and don't match :condition2". The special group //conditions:default
may not be negated. | []
|
diff --git a/lib/BUILD b/lib/BUILD
index 23280816..ecdc98ec 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -1,4 +1,5 @@
load("//:bzl_library.bzl", "bzl_library")
+load("//rules:common_settings.bzl", "string_setting")
licenses(["notice"])
@@ -107,3 +108,34 @@ bzl_library(
name = "old_sets",
srcs = ["old_sets.bzl"],
)
+
+# Define a hidden setting which no other modules can change.
+# No references to this setting other than the two config_setting targets below
+# should exist.
+string_setting(
+ name = "private_setting",
+ build_setting_default = "constant",
+ values = [
+ "constant",
+ "not_constant",
+ ],
+ visibility = ["//visibility:private"],
+)
+
+# Define a config setting that will always match, since nothing ever changes
+# private_setting from its default value of "constant".
+config_setting(
+ name = "always_true",
+ flag_values = {
+ ":private_setting": "constant",
+ },
+)
+
+# Define a config setting that will never match, since nothing ever changes
+# private_setting from its default value of "constant".
+config_setting(
+ name = "always_false",
+ flag_values = {
+ ":private_setting": "not_constant",
+ },
+)
diff --git a/lib/selects.bzl b/lib/selects.bzl
index c511fe5d..e3c44142 100644
--- a/lib/selects.bzl
+++ b/lib/selects.bzl
@@ -14,6 +14,14 @@
"""Skylib module containing convenience interfaces for select()."""
+# Target which will always resolve to True. Referenced through a top-level alias
+# so that it will work with WORKSPACE files in bazel.
+_TRUE_TARGET = Label("//lib:always_true")
+
+# Target which will always resolve to False. Referenced through a top-level alias
+# so that it will work with WORKSPACE files in bazel.
+_FALSE_TARGET = Label("//lib:always_false")
+
def _with_or(input_dict, no_match_error = ""):
"""Drop-in replacement for `select()` that supports ORed keys.
@@ -76,7 +84,12 @@ def _with_or_dict(input_dict):
output_dict[key] = value
return output_dict
-def _config_setting_group(name, match_any = [], match_all = [], visibility = None):
+def _config_setting_group(
+ name,
+ match_any = [],
+ match_all = [],
+ visibility = None,
+ negated = []):
"""Matches if all or any of its member `config_setting`s match.
Example:
@@ -108,23 +121,36 @@ def _config_setting_group(name, match_any = [], match_all = [], visibility = Non
member in the list matches. If this is set, `match_any` must be not
set.
visibility: Visibility of the config_setting_group.
+ negated: If set, this argument should list a subset of the targets
+ passed to `any_of` or `all_of`. The targets listed here will be
+ negated, such that groups can express things such as
+ "match :condition1 and don't match :condition2". The special group
+ `//conditions:default` may not be negated.
"""
- empty1 = not bool(len(match_any))
- empty2 = not bool(len(match_all))
- if (empty1 and empty2) or (not empty1 and not empty2):
+ any_empty = not bool(len(match_any))
+ all_empty = not bool(len(match_all))
+ if (any_empty and all_empty) or (not any_empty and not all_empty):
fail('Either "match_any" or "match_all" must be set, but not both.')
_check_duplicates(match_any)
_check_duplicates(match_all)
+ _check_negated_is_subset(
+ match = match_any if not any_empty else match_all,
+ negated = negated,
+ )
+
+ negated_dict = {n: True for n in negated}
+ if "//conditions:default" in negated_dict:
+ fail("The special target //conditions:default may not be negated.")
if ((len(match_any) == 1 and match_any[0] == "//conditions:default") or
(len(match_all) == 1 and match_all[0] == "//conditions:default")):
# If the only entry is "//conditions:default", the condition is
# automatically true.
- _config_setting_always_true(name, visibility)
- elif not empty1:
- _config_setting_or_group(name, match_any, visibility)
+ native.alias(name = name, actual = _TRUE_TARGET, visibility = visibility)
+ elif not any_empty:
+ _config_setting_or_group(name, match_any, visibility, negated_dict)
else:
- _config_setting_and_group(name, match_all, visibility)
+ _config_setting_and_group(name, match_all, visibility, negated_dict)
def _check_duplicates(settings):
"""Fails if any entry in settings appears more than once."""
@@ -134,6 +160,14 @@ def _check_duplicates(settings):
fail(setting + " appears more than once. Duplicates not allowed.")
seen[setting] = True
+def _check_negated_is_subset(match, negated):
+ """Fails if any item in negated does not appear in match."""
+ match_dict = {item: True for item in match}
+ for negated_condition in negated:
+ if negated_condition not in match_dict:
+ fail("Negated condition " + negated_condition + " not found in " +
+ "match argument.")
+
def _remove_default_condition(settings):
"""Returns settings with "//conditions:default" entries filtered out."""
new_settings = []
@@ -142,105 +176,154 @@ def _remove_default_condition(settings):
new_settings.append(setting)
return new_settings
-def _config_setting_or_group(name, settings, visibility):
+def _config_setting_or_group(name, settings, visibility, negated_dict = {}):
"""ORs multiple config_settings together (inclusively).
The core idea is to create a sequential chain of alias targets where each is
select-resolved as follows: If alias n matches config_setting n, the chain
- is true so it resolves to config_setting n. Else it resolves to alias n+1
+ is true so it resolves to the always_true target. Else it resolves to alias n+1
(which checks config_setting n+1, and so on). If none of the config_settings
- match, the final alias resolves to one of them arbitrarily, which by
- definition doesn't match.
+ match, the final alias resolves to the always_false target.
+
+ Negation of any target other than the final target is implemented by
+ swapping the select conditions. Negation on the final target is implemented
+ by constructing a not node (see _config_setting_not).
"""
# "//conditions:default" is present, the whole chain is automatically true.
if len(_remove_default_condition(settings)) < len(settings):
- _config_setting_always_true(name, visibility)
+ native.alias(name = name, actual = _TRUE_TARGET, visibility = visibility)
return
- elif len(settings) == 1: # One entry? Just alias directly to it.
- native.alias(
- name = name,
- actual = settings[0],
- visibility = visibility,
- )
- return
+ elif len(settings) == 1:
+ if not settings[0] in negated_dict:
+ # One nonnegated entry? Just alias directly to it.
+ native.alias(
+ name = name,
+ actual = settings[0],
+ visibility = visibility,
+ )
+ return
+ else:
+ # One negated config_setting input? That's just a not target.
+ _config_setting_not(name, settings[0], visibility)
+ return
# We need n-1 aliases for n settings. The first alias has no extension. The
# second alias is named name + "_2", and so on. For the first n-2 aliases,
# if they don't match they reference the next alias over. If the n-1st alias
# doesn't match, it references the final setting (which is then evaluated
# directly to determine the final value of the AND chain).
- actual = [name + "_" + str(i) for i in range(2, len(settings))]
- actual.append(settings[-1])
+ alias_names = [name + "_" + str(i) for i in range(2, len(settings))]
+
+ # The final alias isn't evaluated by a select, so if it is negated,
+ # construct a final not node to invert it.
+ final_setting = settings[-1]
+ if final_setting in negated_dict:
+ final_setting = name + "_" + str(len(settings)) + "_not"
+ _config_setting_not(final_setting, settings[-1], ["//visibility:private"])
+ alias_names.append(final_setting)
for i in range(1, len(settings)):
+ this_setting = settings[i - 1]
+ next_alias_name = alias_names[i - 1]
+ if this_setting in negated_dict:
+ select_dict = {
+ this_setting: next_alias_name,
+ "//conditions:default": _TRUE_TARGET,
+ }
+ else:
+ select_dict = {
+ this_setting: _TRUE_TARGET,
+ "//conditions:default": next_alias_name,
+ }
native.alias(
name = name if i == 1 else name + "_" + str(i),
- actual = select({
- settings[i - 1]: settings[i - 1],
- "//conditions:default": actual[i - 1],
- }),
+ actual = select(select_dict),
visibility = visibility if i == 1 else ["//visibility:private"],
)
-def _config_setting_and_group(name, settings, visibility):
+def _config_setting_and_group(name, settings, visibility, negated_dict = {}):
"""ANDs multiple config_settings together.
The core idea is to create a sequential chain of alias targets where each is
select-resolved as follows: If alias n matches config_setting n, it resolves to
alias n+1 (which evaluates config_setting n+1, and so on). Else it resolves to
- config_setting n, which doesn't match by definition. The only way to get a
- matching final result is if all config_settings match.
+ the always-false target. The only way to get a matching final result is if all
+ config_settings match.
+
+ Negation of any target other than the final target is implemented by
+ swapping the select conditions. Negation on the final target is implemented
+ by constructing a not node (see _config_setting_not).
"""
# "//conditions:default" is automatically true so doesn't need checking.
settings = _remove_default_condition(settings)
- # One config_setting input? Just alias directly to it.
if len(settings) == 1:
- native.alias(
- name = name,
- actual = settings[0],
- visibility = visibility,
- )
- return
+ if not settings[0] in negated_dict:
+ # One non-negated config_setting input? Just alias directly to it.
+ native.alias(
+ name = name,
+ actual = settings[0],
+ visibility = visibility,
+ )
+ return
+ else:
+ # One negated config_setting input? That's just the not target.
+ _config_setting_not(name, settings[0], visibility)
+ return
# We need n-1 aliases for n settings. The first alias has no extension. The
# second alias is named name + "_2", and so on. For the first n-2 aliases,
# if they match they reference the next alias over. If the n-1st alias matches,
# it references the final setting (which is then evaluated directly to determine
# the final value of the AND chain).
- actual = [name + "_" + str(i) for i in range(2, len(settings))]
- actual.append(settings[-1])
+ alias_names = [name + "_" + str(i) for i in range(2, len(settings))]
+
+ # The final alias isn't evaluated by a select, so if it is negated,
+ # construct a final not node to invert it.
+ final_setting = settings[-1]
+ if final_setting in negated_dict:
+ final_setting = name + "_" + str(len(settings)) + "_not"
+ _config_setting_not(final_setting, settings[-1], ["//visibility:private"])
+ alias_names.append(final_setting)
for i in range(1, len(settings)):
+ this_setting = settings[i - 1]
+ next_alias = alias_names[i - 1]
+ if this_setting in negated_dict:
+ select_dict = {
+ this_setting: _FALSE_TARGET,
+ "//conditions:default": next_alias,
+ }
+ else:
+ select_dict = {
+ this_setting: next_alias,
+ "//conditions:default": _FALSE_TARGET,
+ }
native.alias(
name = name if i == 1 else name + "_" + str(i),
- actual = select({
- settings[i - 1]: actual[i - 1],
- "//conditions:default": settings[i - 1],
- }),
+ actual = select(select_dict),
visibility = visibility if i == 1 else ["//visibility:private"],
)
-def _config_setting_always_true(name, visibility):
- """Returns a config_setting with the given name that's always true.
+def _config_setting_not(name, setting, visibility):
+ """Returns an alias that will match if the given setting does not match.
- This is achieved by constructing a two-entry OR chain where each
- config_setting takes opposite values of a boolean flag.
+ Args:
+ name: Name for the alias rule to define.
+ setting: The config_setting to invert.
+ visibility: The visibility to assign to the generated alias.
"""
- name_on = name + "_stamp_binary_on_check"
- name_off = name + "_stamp_binary_off_check"
- native.config_setting(
- name = name_on,
- values = {"stamp": "1"},
- )
- native.config_setting(
- name = name_off,
- values = {"stamp": "0"},
+ native.alias(
+ name = name,
+ actual = select({
+ setting: _FALSE_TARGET,
+ "//conditions:default": _TRUE_TARGET,
+ }),
+ visibility = visibility,
)
- return _config_setting_or_group(name, [":" + name_on, ":" + name_off], visibility)
selects = struct(
with_or = _with_or,
diff --git a/tests/selects_tests.bzl b/tests/selects_tests.bzl
index a7697f21..27e5f967 100644
--- a/tests/selects_tests.bzl
+++ b/tests/selects_tests.bzl
@@ -85,18 +85,48 @@ def _create_config_setting_groups():
name = "1_and_2_and_3",
match_all = [":condition1", ":condition2", ":condition3"],
)
+ selects.config_setting_group(
+ name = "not_1_and_2_and_3",
+ match_all = [":condition1", ":condition2", ":condition3"],
+ negated = [":condition1"],
+ )
+ selects.config_setting_group(
+ name = "1_and_2_and_not_3",
+ match_all = [":condition1", ":condition2", ":condition3"],
+ negated = [":condition3"],
+ )
selects.config_setting_group(
name = "1_and_nothing_else",
match_all = [":condition1"],
)
+ selects.config_setting_group(
+ name = "not_1_and_nothing_else",
+ match_all = [":condition1"],
+ negated = [":condition1"],
+ )
selects.config_setting_group(
name = "1_or_2_or_3",
match_any = [":condition1", ":condition2", ":condition3"],
)
+ selects.config_setting_group(
+ name = "1_or_not_2_or_3",
+ match_any = [":condition1", ":condition2", ":condition3"],
+ negated = [":condition2"],
+ )
+ selects.config_setting_group(
+ name = "1_or_2_or_not_3",
+ match_any = [":condition1", ":condition2", ":condition3"],
+ negated = [":condition3"],
+ )
selects.config_setting_group(
name = "1_or_nothing_else",
match_any = [":condition1"],
)
+ selects.config_setting_group(
+ name = "not_1_or_nothing_else",
+ match_any = [":condition1"],
+ negated = [":condition1"],
+ )
###################################################
# Support code for config_setting_group tests
@@ -180,6 +210,54 @@ def _and_config_setting_group_matches_test():
target_under_test = ":and_config_setting_group_matches_rule",
)
+###################################################
+# and_not_1_config_setting_group_matches_test
+###################################################
+and_not_1_config_setting_group_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = _set_conditions([False, True, True]),
+)
+
+def _and_not_1_config_setting_group_matches_test():
+ """Test verifying match on an ANDing config_setting_group with negation."""
+ boolean_attr_rule(
+ name = "and_not_1_config_setting_group_matches_rule",
+ myboolean = select(
+ {
+ ":not_1_and_2_and_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_1_config_setting_group_matches_test(
+ name = "and_not_1_config_setting_group_matches_test",
+ target_under_test = ":and_not_1_config_setting_group_matches_rule",
+ )
+
+###################################################
+# and_not_3_config_setting_group_matches_test
+###################################################
+and_not_3_config_setting_group_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = _set_conditions([True, True, False]),
+)
+
+def _and_not_3_config_setting_group_matches_test():
+ """Test verifying match on an ANDing config_setting_group with negation."""
+ boolean_attr_rule(
+ name = "and_not_3_config_setting_group_matches_rule",
+ myboolean = select(
+ {
+ ":1_and_2_and_not_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_3_config_setting_group_matches_test(
+ name = "and_not_3_config_setting_group_matches_test",
+ target_under_test = ":and_not_3_config_setting_group_matches_rule",
+ )
+
###################################################
# and_config_setting_group_first_match_fails_test
###################################################
@@ -204,6 +282,54 @@ def _and_config_setting_group_first_match_fails_test():
target_under_test = ":and_config_setting_group_first_match_fails_rule",
)
+###################################################
+# and_not_1_config_setting_group_first_match_fails_test
+###################################################
+and_not_1_config_setting_group_first_match_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([True, True, True]),
+)
+
+def _and_not_1_config_setting_group_first_match_fails_test():
+ """Test verifying first condition mismatch on an ANDing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_1_config_setting_group_first_match_fails_rule",
+ myboolean = select(
+ {
+ ":not_1_and_2_and_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_1_config_setting_group_first_match_fails_test(
+ name = "and_not_1_config_setting_group_first_match_fails_test",
+ target_under_test = ":and_not_1_config_setting_group_first_match_fails_rule",
+ )
+
+###################################################
+# and_not_3_config_setting_group_first_match_fails_test
+###################################################
+and_not_3_config_setting_group_first_match_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([False, True, False]),
+)
+
+def _and_not_3_config_setting_group_first_match_fails_test():
+ """Test verifying first condition mismatch on an ANDing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_3_config_setting_group_first_match_fails_rule",
+ myboolean = select(
+ {
+ ":1_and_2_and_not_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_3_config_setting_group_first_match_fails_test(
+ name = "and_not_3_config_setting_group_first_match_fails_test",
+ target_under_test = ":and_not_3_config_setting_group_first_match_fails_rule",
+ )
+
###################################################
# and_config_setting_group_middle_match_fails_test
###################################################
@@ -252,6 +378,54 @@ def _and_config_setting_group_last_match_fails_test():
target_under_test = ":and_config_setting_group_last_match_fails_rule",
)
+###################################################
+# and_not_1_config_setting_group_last_match_fails_test
+###################################################
+and_not_1_config_setting_group_last_match_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([False, True, False]),
+)
+
+def _and_not_1_config_setting_group_last_match_fails_test():
+ """Test verifying last condition mismatch on an ANDing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_1_config_setting_group_last_match_fails_rule",
+ myboolean = select(
+ {
+ ":not_1_and_2_and_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_1_config_setting_group_last_match_fails_test(
+ name = "and_not_1_config_setting_group_last_match_fails_test",
+ target_under_test = ":and_not_1_config_setting_group_last_match_fails_rule",
+ )
+
+###################################################
+# and_not_3_config_setting_group_last_match_fails_test
+###################################################
+and_not_3_config_setting_group_last_match_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([True, True, True]),
+)
+
+def _and_not_3_config_setting_group_last_match_fails_test():
+ """Test verifying last condition mismatch on an ANDing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_3_config_setting_group_last_match_fails_rule",
+ myboolean = select(
+ {
+ ":1_and_2_and_not_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_3_config_setting_group_last_match_fails_test(
+ name = "and_not_3_config_setting_group_last_match_fails_test",
+ target_under_test = ":and_not_3_config_setting_group_last_match_fails_rule",
+ )
+
###################################################
# and_config_setting_group_multiple_matches_fail_test
###################################################
@@ -324,6 +498,30 @@ def _and_config_setting_group_single_setting_matches_test():
target_under_test = ":and_config_setting_group_single_setting_matches_rule",
)
+###################################################
+# and_config_setting_group_single_setting_matches_test
+###################################################
+and_not_config_setting_group_single_setting_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = {"//command_line_option:cpu": "x86"},
+)
+
+def _and_not_config_setting_group_single_setting_matches_test():
+ """Test verifying match on single-entry AND-NOT-ing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_config_setting_group_single_setting_matches_rule",
+ myboolean = select(
+ {
+ ":not_1_and_nothing_else": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_config_setting_group_single_setting_matches_test(
+ name = "and_not_config_setting_group_single_setting_matches_test",
+ target_under_test = ":and_not_config_setting_group_single_setting_matches_rule",
+ )
+
###################################################
# and_config_setting_group_single_setting_fails_test
###################################################
@@ -348,6 +546,30 @@ def _and_config_setting_group_single_setting_fails_test():
target_under_test = ":and_config_setting_group_single_setting_fails_rule",
)
+###################################################
+# and_not_config_setting_group_single_setting_fails_test
+###################################################
+and_not_config_setting_group_single_setting_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = {"//command_line_option:cpu": "ppc"},
+)
+
+def _and_not_config_setting_group_single_setting_fails_test():
+ """Test verifying no match on single-entry ANDing config_setting_group."""
+ boolean_attr_rule(
+ name = "and_not_config_setting_group_single_setting_fails_rule",
+ myboolean = select(
+ {
+ ":not_1_and_nothing_else": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ and_not_config_setting_group_single_setting_fails_test(
+ name = "and_not_config_setting_group_single_setting_fails_test",
+ target_under_test = ":and_not_config_setting_group_single_setting_fails_rule",
+ )
+
###################################################
# or_config_setting_group_no_match_test
###################################################
@@ -372,6 +594,54 @@ def _or_config_setting_group_no_matches_test():
target_under_test = ":or_config_setting_group_no_matches_rule",
)
+###################################################
+# or_not_2_config_setting_group_no_match_test
+###################################################
+or_not_2_config_setting_group_no_matches_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([False, True, False]),
+)
+
+def _or_not_2_config_setting_group_no_matches_test():
+ """Test verifying no matches on an ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_2_config_setting_group_no_matches_rule",
+ myboolean = select(
+ {
+ ":1_or_not_2_or_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_2_config_setting_group_no_matches_test(
+ name = "or_not_2_config_setting_group_no_matches_test",
+ target_under_test = ":or_not_2_config_setting_group_no_matches_rule",
+ )
+
+###################################################
+# or_not_3_config_setting_group_no_match_test
+###################################################
+or_not_3_config_setting_group_no_matches_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = _set_conditions([False, False, True]),
+)
+
+def _or_not_3_config_setting_group_no_matches_test():
+ """Test verifying no matches on an ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_3_config_setting_group_no_matches_rule",
+ myboolean = select(
+ {
+ ":1_or_2_or_not_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_3_config_setting_group_no_matches_test(
+ name = "or_not_3_config_setting_group_no_matches_test",
+ target_under_test = ":or_not_3_config_setting_group_no_matches_rule",
+ )
+
###################################################
# or_config_setting_group_first_cond_matches_test
###################################################
@@ -420,6 +690,54 @@ def _or_config_setting_group_middle_cond_matches_test():
target_under_test = ":or_config_setting_group_middle_cond_matches_rule",
)
+###################################################
+# or_not_2_config_setting_group_middle_cond_matches_test
+###################################################
+or_not_2_config_setting_group_middle_cond_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = _set_conditions([False, False, False]),
+)
+
+def _or_not_2_config_setting_group_middle_cond_matches_test():
+ """Test verifying middle condition matching on an ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_2_config_setting_group_middle_cond_matches_rule",
+ myboolean = select(
+ {
+ ":1_or_not_2_or_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_2_config_setting_group_middle_cond_matches_test(
+ name = "or_not_2_config_setting_group_middle_cond_matches_test",
+ target_under_test = ":or_not_2_config_setting_group_middle_cond_matches_rule",
+ )
+
+###################################################
+# or_not_3_config_setting_group_last_cond_matches_test
+###################################################
+or_not_3_config_setting_group_last_cond_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = _set_conditions([False, False, False]),
+)
+
+def _or_not_3_config_setting_group_last_cond_matches_test():
+ """Test verifying middle condition matching on an ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_3_config_setting_group_last_cond_matches_rule",
+ myboolean = select(
+ {
+ ":1_or_2_or_not_3": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_3_config_setting_group_last_cond_matches_test(
+ name = "or_not_3_config_setting_group_last_cond_matches_test",
+ target_under_test = ":or_not_3_config_setting_group_last_cond_matches_rule",
+ )
+
###################################################
# or_config_setting_group_last_cond_matches_test
###################################################
@@ -516,6 +834,30 @@ def _or_config_setting_group_single_setting_matches_test():
target_under_test = ":or_config_setting_group_single_setting_matches_rule",
)
+###################################################
+# or_not_config_setting_group_single_setting_matches_test
+###################################################
+or_not_config_setting_group_single_setting_matches_test = analysistest.make(
+ _expect_matches,
+ config_settings = {"//command_line_option:cpu": "x86"},
+)
+
+def _or_not_config_setting_group_single_setting_matches_test():
+ """Test verifying match on single-entry ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_config_setting_group_single_setting_matches_rule",
+ myboolean = select(
+ {
+ ":not_1_or_nothing_else": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_config_setting_group_single_setting_matches_test(
+ name = "or_not_config_setting_group_single_setting_matches_test",
+ target_under_test = ":or_not_config_setting_group_single_setting_matches_rule",
+ )
+
###################################################
# or_config_setting_group_single_setting_fails_test
###################################################
@@ -540,6 +882,30 @@ def _or_config_setting_group_single_setting_fails_test():
target_under_test = ":or_config_setting_group_single_setting_fails_rule",
)
+###################################################
+# or_not_config_setting_group_single_setting_fails_test
+###################################################
+or_not_config_setting_group_single_setting_fails_test = analysistest.make(
+ _expect_doesnt_match,
+ config_settings = {"//command_line_option:cpu": "ppc"},
+)
+
+def _or_not_config_setting_group_single_setting_fails_test():
+ """Test verifying no match on single-entry ORing config_setting_group."""
+ boolean_attr_rule(
+ name = "or_not_config_setting_group_single_setting_fails_rule",
+ myboolean = select(
+ {
+ ":not_1_or_nothing_else": True,
+ "//conditions:default": False,
+ },
+ ),
+ )
+ or_not_config_setting_group_single_setting_fails_test(
+ name = "or_not_config_setting_group_single_setting_fails_test",
+ target_under_test = ":or_not_config_setting_group_single_setting_fails_rule",
+ )
+
###################################################
# always_true_match_all_test
###################################################
@@ -619,22 +985,36 @@ def selects_test_suite():
_create_config_setting_groups()
_and_config_setting_group_matches_test()
+ _and_not_1_config_setting_group_matches_test()
+ _and_not_3_config_setting_group_matches_test()
_and_config_setting_group_first_match_fails_test()
+ _and_not_1_config_setting_group_first_match_fails_test()
+ _and_not_3_config_setting_group_first_match_fails_test()
_and_config_setting_group_middle_match_fails_test()
_and_config_setting_group_last_match_fails_test()
+ _and_not_1_config_setting_group_last_match_fails_test()
+ _and_not_3_config_setting_group_last_match_fails_test()
_and_config_setting_group_multiple_matches_fail_test()
_and_config_setting_group_all_matches_fail_test()
_and_config_setting_group_single_setting_matches_test()
+ _and_not_config_setting_group_single_setting_matches_test()
_and_config_setting_group_single_setting_fails_test()
+ _and_not_config_setting_group_single_setting_fails_test()
_or_config_setting_group_no_matches_test()
+ _or_not_2_config_setting_group_no_matches_test()
+ _or_not_3_config_setting_group_no_matches_test()
_or_config_setting_group_first_cond_matches_test()
_or_config_setting_group_middle_cond_matches_test()
+ _or_not_2_config_setting_group_middle_cond_matches_test()
_or_config_setting_group_last_cond_matches_test()
+ _or_not_3_config_setting_group_last_cond_matches_test()
_or_config_setting_group_multiple_conds_match_test()
_or_config_setting_group_all_conds_match_test()
_or_config_setting_group_single_setting_matches_test()
+ _or_not_config_setting_group_single_setting_matches_test()
_or_config_setting_group_single_setting_fails_test()
+ _or_not_config_setting_group_single_setting_fails_test()
_always_true_match_all_test()
_always_true_match_any_test()