1*60517a1eSAndroid Build Coastguard Worker# Copyright 2023 The Bazel Authors. All rights reserved. 2*60517a1eSAndroid Build Coastguard Worker# 3*60517a1eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*60517a1eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*60517a1eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*60517a1eSAndroid Build Coastguard Worker# 7*60517a1eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*60517a1eSAndroid Build Coastguard Worker# 9*60517a1eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*60517a1eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*60517a1eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*60517a1eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*60517a1eSAndroid Build Coastguard Worker# limitations under the License. 14*60517a1eSAndroid Build Coastguard Worker 15*60517a1eSAndroid Build Coastguard Worker"""Functionality shared by multiple pieces of code.""" 16*60517a1eSAndroid Build Coastguard Worker 17*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:types.bzl", "types") 18*60517a1eSAndroid Build Coastguard Worker 19*60517a1eSAndroid Build Coastguard Workerdef copy_propagating_kwargs(from_kwargs, into_kwargs = None): 20*60517a1eSAndroid Build Coastguard Worker """Copies args that must be compatible between two targets with a dependency relationship. 21*60517a1eSAndroid Build Coastguard Worker 22*60517a1eSAndroid Build Coastguard Worker This is intended for when one target depends on another, so they must have 23*60517a1eSAndroid Build Coastguard Worker compatible settings such as `testonly` and `compatible_with`. This usually 24*60517a1eSAndroid Build Coastguard Worker happens when a macro generates multiple targets, some of which depend 25*60517a1eSAndroid Build Coastguard Worker on one another, so their settings must be compatible. 26*60517a1eSAndroid Build Coastguard Worker 27*60517a1eSAndroid Build Coastguard Worker Args: 28*60517a1eSAndroid Build Coastguard Worker from_kwargs: keyword args dict whose common kwarg will be copied. 29*60517a1eSAndroid Build Coastguard Worker into_kwargs: optional keyword args dict that the values from `from_kwargs` 30*60517a1eSAndroid Build Coastguard Worker will be copied into. The values in this dict will take precedence 31*60517a1eSAndroid Build Coastguard Worker over the ones in `from_kwargs` (i.e., if this has `testonly` already 32*60517a1eSAndroid Build Coastguard Worker set, then it won't be overwritten). 33*60517a1eSAndroid Build Coastguard Worker NOTE: THIS WILL BE MODIFIED IN-PLACE. 34*60517a1eSAndroid Build Coastguard Worker 35*60517a1eSAndroid Build Coastguard Worker Returns: 36*60517a1eSAndroid Build Coastguard Worker Keyword args to use for the depender target derived from the dependency 37*60517a1eSAndroid Build Coastguard Worker target. If `into_kwargs` was passed in, then that same object is 38*60517a1eSAndroid Build Coastguard Worker returned; this is to facilitate easy `**` expansion. 39*60517a1eSAndroid Build Coastguard Worker """ 40*60517a1eSAndroid Build Coastguard Worker if into_kwargs == None: 41*60517a1eSAndroid Build Coastguard Worker into_kwargs = {} 42*60517a1eSAndroid Build Coastguard Worker 43*60517a1eSAndroid Build Coastguard Worker # Include tags because people generally expect tags to propagate. 44*60517a1eSAndroid Build Coastguard Worker for attr in ("testonly", "tags", "compatible_with", "restricted_to"): 45*60517a1eSAndroid Build Coastguard Worker if attr in from_kwargs and attr not in into_kwargs: 46*60517a1eSAndroid Build Coastguard Worker into_kwargs[attr] = from_kwargs[attr] 47*60517a1eSAndroid Build Coastguard Worker return into_kwargs 48*60517a1eSAndroid Build Coastguard Worker 49*60517a1eSAndroid Build Coastguard Worker# The implementation of the macros and tagging mechanism follows the example 50*60517a1eSAndroid Build Coastguard Worker# set by rules_cc and rules_java. 51*60517a1eSAndroid Build Coastguard Worker 52*60517a1eSAndroid Build Coastguard Worker_MIGRATION_TAG = "__PYTHON_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__" 53*60517a1eSAndroid Build Coastguard Worker 54*60517a1eSAndroid Build Coastguard Workerdef add_migration_tag(attrs): 55*60517a1eSAndroid Build Coastguard Worker """Add a special tag to `attrs` to aid migration off native rles. 56*60517a1eSAndroid Build Coastguard Worker 57*60517a1eSAndroid Build Coastguard Worker Args: 58*60517a1eSAndroid Build Coastguard Worker attrs: dict of keyword args. The `tags` key will be modified in-place. 59*60517a1eSAndroid Build Coastguard Worker 60*60517a1eSAndroid Build Coastguard Worker Returns: 61*60517a1eSAndroid Build Coastguard Worker The same `attrs` object, but modified. 62*60517a1eSAndroid Build Coastguard Worker """ 63*60517a1eSAndroid Build Coastguard Worker add_tag(attrs, _MIGRATION_TAG) 64*60517a1eSAndroid Build Coastguard Worker return attrs 65*60517a1eSAndroid Build Coastguard Worker 66*60517a1eSAndroid Build Coastguard Workerdef add_tag(attrs, tag): 67*60517a1eSAndroid Build Coastguard Worker """Adds `tag` to `attrs["tags"]`. 68*60517a1eSAndroid Build Coastguard Worker 69*60517a1eSAndroid Build Coastguard Worker Args: 70*60517a1eSAndroid Build Coastguard Worker attrs: dict of keyword args. It is modified in place. 71*60517a1eSAndroid Build Coastguard Worker tag: str, the tag to add. 72*60517a1eSAndroid Build Coastguard Worker """ 73*60517a1eSAndroid Build Coastguard Worker if "tags" in attrs and attrs["tags"] != None: 74*60517a1eSAndroid Build Coastguard Worker tags = attrs["tags"] 75*60517a1eSAndroid Build Coastguard Worker 76*60517a1eSAndroid Build Coastguard Worker # Preserve the input type: this allows a test verifying the underlying 77*60517a1eSAndroid Build Coastguard Worker # rule can accept the tuple for the tags argument. 78*60517a1eSAndroid Build Coastguard Worker if types.is_tuple(tags): 79*60517a1eSAndroid Build Coastguard Worker attrs["tags"] = tags + (tag,) 80*60517a1eSAndroid Build Coastguard Worker else: 81*60517a1eSAndroid Build Coastguard Worker # List concatenation is necessary because the original value 82*60517a1eSAndroid Build Coastguard Worker # may be a frozen list. 83*60517a1eSAndroid Build Coastguard Worker attrs["tags"] = tags + [tag] 84*60517a1eSAndroid Build Coastguard Worker else: 85*60517a1eSAndroid Build Coastguard Worker attrs["tags"] = [tag] 86*60517a1eSAndroid Build Coastguard Worker 87*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_7_OR_HIGHER = hasattr(native, "starlark_doc_extract") 88*60517a1eSAndroid Build Coastguard Worker 89*60517a1eSAndroid Build Coastguard Worker# Bazel 5.4 has a bug where every access of testing.ExecutionInfo is a 90*60517a1eSAndroid Build Coastguard Worker# different object that isn't equal to any other. This is fixed in bazel 6+. 91*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_6_OR_HIGHER = testing.ExecutionInfo == testing.ExecutionInfo 92*60517a1eSAndroid Build Coastguard Worker 93*60517a1eSAndroid Build Coastguard Worker_marker_rule_to_detect_bazel_6_4_or_higher = rule(implementation = lambda ctx: None) 94*60517a1eSAndroid Build Coastguard Worker 95*60517a1eSAndroid Build Coastguard Worker# Bazel 6.4 and higher have a bug fix where rule names show up in the str() 96*60517a1eSAndroid Build Coastguard Worker# of a rule. See 97*60517a1eSAndroid Build Coastguard Worker# https://github.com/bazelbuild/bazel/commit/002490b9a2376f0b2ea4a37102c5e94fc50a65ba 98*60517a1eSAndroid Build Coastguard Worker# https://github.com/bazelbuild/bazel/commit/443cbcb641e17f7337ccfdecdfa5e69bc16cae55 99*60517a1eSAndroid Build Coastguard Worker# This technique is done instead of using native.bazel_version because, 100*60517a1eSAndroid Build Coastguard Worker# under stardoc, the native.bazel_version attribute is entirely missing, which 101*60517a1eSAndroid Build Coastguard Worker# prevents doc generation from being able to correctly generate docs. 102*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_6_4_OR_HIGHER = "_marker_rule_to_detect_bazel_6_4_or_higher" in str( 103*60517a1eSAndroid Build Coastguard Worker _marker_rule_to_detect_bazel_6_4_or_higher, 104*60517a1eSAndroid Build Coastguard Worker) 105