• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Functionality shared by multiple pieces of code."""
16
17load("@bazel_skylib//lib:types.bzl", "types")
18
19def copy_propagating_kwargs(from_kwargs, into_kwargs = None):
20    """Copies args that must be compatible between two targets with a dependency relationship.
21
22    This is intended for when one target depends on another, so they must have
23    compatible settings such as `testonly` and `compatible_with`. This usually
24    happens when a macro generates multiple targets, some of which depend
25    on one another, so their settings must be compatible.
26
27    Args:
28        from_kwargs: keyword args dict whose common kwarg will be copied.
29        into_kwargs: optional keyword args dict that the values from `from_kwargs`
30            will be copied into. The values in this dict will take precedence
31            over the ones in `from_kwargs` (i.e., if this has `testonly` already
32            set, then it won't be overwritten).
33            NOTE: THIS WILL BE MODIFIED IN-PLACE.
34
35    Returns:
36        Keyword args to use for the depender target derived from the dependency
37        target. If `into_kwargs` was passed in, then that same object is
38        returned; this is to facilitate easy `**` expansion.
39    """
40    if into_kwargs == None:
41        into_kwargs = {}
42
43    # Include tags because people generally expect tags to propagate.
44    for attr in ("testonly", "tags", "compatible_with", "restricted_to"):
45        if attr in from_kwargs and attr not in into_kwargs:
46            into_kwargs[attr] = from_kwargs[attr]
47    return into_kwargs
48
49# The implementation of the macros and tagging mechanism follows the example
50# set by rules_cc and rules_java.
51
52_MIGRATION_TAG = "__PYTHON_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__"
53
54def add_migration_tag(attrs):
55    """Add a special tag to `attrs` to aid migration off native rles.
56
57    Args:
58        attrs: dict of keyword args. The `tags` key will be modified in-place.
59
60    Returns:
61        The same `attrs` object, but modified.
62    """
63    add_tag(attrs, _MIGRATION_TAG)
64    return attrs
65
66def add_tag(attrs, tag):
67    """Adds `tag` to `attrs["tags"]`.
68
69    Args:
70        attrs: dict of keyword args. It is modified in place.
71        tag: str, the tag to add.
72    """
73    if "tags" in attrs and attrs["tags"] != None:
74        tags = attrs["tags"]
75
76        # Preserve the input type: this allows a test verifying the underlying
77        # rule can accept the tuple for the tags argument.
78        if types.is_tuple(tags):
79            attrs["tags"] = tags + (tag,)
80        else:
81            # List concatenation is necessary because the original value
82            # may be a frozen list.
83            attrs["tags"] = tags + [tag]
84    else:
85        attrs["tags"] = [tag]
86