rules_cc/tests/rule_based_toolchain/subjects.bzl

243 lines
7.0 KiB
Python

# Copyright 2024 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.
"""Test subjects for cc_toolchain_info providers."""
load("@bazel_skylib//lib:structs.bzl", "structs")
load("@rules_testing//lib:truth.bzl", _subjects = "subjects")
load(
"//cc/toolchains:cc_toolchain_info.bzl",
"ActionTypeInfo",
"ActionTypeSetInfo",
"ArgsInfo",
"ArgsListInfo",
"FeatureConstraintInfo",
"FeatureInfo",
"FeatureSetInfo",
"MutuallyExclusiveCategoryInfo",
"NestedArgsInfo",
"ToolConfigInfo",
"ToolInfo",
"ToolchainConfigInfo",
)
load(":generate_factory.bzl", "ProviderDepset", "ProviderSequence", "generate_factory")
load(":generics.bzl", "dict_key_subject", "optional_subject", "result_subject", "struct_subject", _result_fn_wrapper = "result_fn_wrapper")
visibility("//tests/rule_based_toolchain/...")
# The default runfiles subject uses path instead of short_path.
# This makes it rather awkward for copybara.
runfiles_subject = lambda value, meta: _subjects.depset_file(value.files, meta = meta)
# The string type has .equals(), which is all we can really do for an unknown
# type.
unknown_subject = _subjects.str
# Directory depsets are quite complex, so just simplify them as a list of paths.
# buildifier: disable=name-conventions
_FakeDirectoryDepset = lambda value, *, meta: _subjects.collection([v.path for v in value.to_list()], meta = meta)
# buildifier: disable=name-conventions
_ActionTypeFactory = generate_factory(
ActionTypeInfo,
"ActionTypeInfo",
dict(
name = _subjects.str,
),
)
# buildifier: disable=name-conventions
_ActionTypeSetFactory = generate_factory(
ActionTypeSetInfo,
"ActionTypeInfo",
dict(
actions = ProviderDepset(_ActionTypeFactory),
),
)
# buildifier: disable=name-conventions
_MutuallyExclusiveCategoryFactory = generate_factory(
MutuallyExclusiveCategoryInfo,
"MutuallyExclusiveCategoryInfo",
dict(name = _subjects.str),
)
_FEATURE_FLAGS = dict(
name = _subjects.str,
enabled = _subjects.bool,
args = None,
implies = None,
requires_any_of = None,
mutually_exclusive = ProviderSequence(_MutuallyExclusiveCategoryFactory),
overridable = _subjects.bool,
external = _subjects.bool,
overrides = None,
allowlist_include_directories = _FakeDirectoryDepset,
)
# Break the dependency loop.
# buildifier: disable=name-conventions
_FakeFeatureFactory = generate_factory(
FeatureInfo,
"FeatureInfo",
_FEATURE_FLAGS,
)
# buildifier: disable=name-conventions
_FeatureSetFactory = generate_factory(
FeatureSetInfo,
"FeatureSetInfo",
dict(features = ProviderDepset(_FakeFeatureFactory)),
)
# buildifier: disable=name-conventions
_FeatureConstraintFactory = generate_factory(
FeatureConstraintInfo,
"FeatureConstraintInfo",
dict(
all_of = ProviderDepset(_FakeFeatureFactory),
none_of = ProviderDepset(_FakeFeatureFactory),
),
)
_NESTED_ARGS_FLAGS = dict(
nested = None,
files = _subjects.depset_file,
iterate_over = optional_subject(_subjects.str),
legacy_flag_group = unknown_subject,
requires_types = _subjects.dict,
unwrap_options = _subjects.collection,
)
# buildifier: disable=name-conventions
_FakeNestedArgsFactory = generate_factory(
NestedArgsInfo,
"NestedArgsInfo",
_NESTED_ARGS_FLAGS,
)
# buildifier: disable=name-conventions
_NestedArgsFactory = generate_factory(
NestedArgsInfo,
"NestedArgsInfo",
_NESTED_ARGS_FLAGS | dict(
nested = ProviderSequence(_FakeNestedArgsFactory),
),
)
# buildifier: disable=name-conventions
_ArgsFactory = generate_factory(
ArgsInfo,
"ArgsInfo",
dict(
actions = ProviderDepset(_ActionTypeFactory),
env = _subjects.dict,
files = _subjects.depset_file,
# Use .factory so it's not inlined.
nested = optional_subject(_NestedArgsFactory.factory),
requires_any_of = ProviderSequence(_FeatureConstraintFactory),
allowlist_include_directories = _FakeDirectoryDepset,
),
)
# buildifier: disable=name-conventions
_ArgsListFactory = generate_factory(
ArgsListInfo,
"ArgsListInfo",
dict(
args = ProviderSequence(_ArgsFactory),
by_action = lambda values, *, meta: dict_key_subject(struct_subject(
args = _subjects.collection,
files = _subjects.depset_file,
))({value.action: value for value in values}, meta = meta),
files = _subjects.depset_file,
allowlist_include_directories = _FakeDirectoryDepset,
),
)
# buildifier: disable=name-conventions
_FeatureFactory = generate_factory(
FeatureInfo,
"FeatureInfo",
_FEATURE_FLAGS | dict(
# Use .factory so it's not inlined.
args = _ArgsListFactory.factory,
implies = ProviderDepset(_FakeFeatureFactory),
requires_any_of = ProviderSequence(_FeatureSetFactory),
overrides = optional_subject(_FakeFeatureFactory.factory),
),
)
# buildifier: disable=name-conventions
_ToolFactory = generate_factory(
ToolInfo,
"ToolInfo",
dict(
exe = _subjects.file,
runfiles = runfiles_subject,
execution_requirements = _subjects.collection,
allowlist_include_directories = _FakeDirectoryDepset,
),
)
# buildifier: disable=name-conventions
_ToolConfigFactory = generate_factory(
ToolConfigInfo,
"ToolConfigInfo",
dict(
configs = dict_key_subject(_ToolFactory.factory),
),
)
# buildifier: disable=name-conventions
_ToolchainConfigFactory = generate_factory(
ToolchainConfigInfo,
"ToolchainConfigInfo",
dict(
features = ProviderDepset(_FeatureFactory),
enabled_features = _subjects.collection,
tool_map = optional_subject(_ToolConfigFactory.factory),
args = ProviderSequence(_ArgsFactory),
files = dict_key_subject(_subjects.depset_file),
allowlist_include_directories = _FakeDirectoryDepset,
),
)
FACTORIES = [
_ActionTypeFactory,
_ActionTypeSetFactory,
_NestedArgsFactory,
_ArgsFactory,
_ArgsListFactory,
_MutuallyExclusiveCategoryFactory,
_FeatureFactory,
_FeatureConstraintFactory,
_FeatureSetFactory,
_ToolFactory,
_ToolConfigFactory,
_ToolchainConfigFactory,
]
result_fn_wrapper = _result_fn_wrapper
subjects = struct(
**(structs.to_dict(_subjects) | dict(
unknown = unknown_subject,
result = result_subject,
optional = optional_subject,
struct = struct_subject,
runfiles = runfiles_subject,
dict_key = dict_key_subject,
) | {factory.name: factory.factory for factory in FACTORIES})
)