...
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
15load("@bazel_features//:features.bzl", "bazel_features")
16
17visibility([
18 "//tests/bzlmod/...",
19])
20
21# structs have certain built-in methods or attributes that should not
22# be overwritten. Load these by calling `dir` on an empty struct.
23# e.g. ["to_proto", "to_json"]
24_STRUCT_PROTECTED_ATTRIBUTES = dir(struct())
25
26def drop_nones(dict):
27 """Drop entries with None values from a dictionary.
28
29 Args:
30 dict: A dictionary.
31
32 Returns:
33 A new dictionary with the same keys as dict, but with entries with
34 None values removed.
35 """
36 return {k: v for k, v in dict.items() if v != None}
37
38def format_rule_call(_kind, **attrs):
39 """Format a rule call.
40
41 Args:
42 _kind: The kind of the rule.
43 attrs: The attributes of the rule. The attributes are sorted by name,
44 except for the "name" attribute, which is always first. None
45 values are ignored.
46
47 Returns:
48 A string representing the rule call.
49 """
50
51 lines = [_kind + "("]
52 for attr, value in sorted(attrs.items(), key = _attrs_sort_key):
53 if value == None:
54 continue
55 lines.append(" {} = {},".format(attr, repr(value)))
56 lines.append(")")
57
58 return "\n".join(lines)
59
60def _attrs_sort_key(entry):
61 """Sort key for attributes.
62
63 Attributes are sorted by name, except for the "name" attribute, which is
64 always first.
65
66 Args:
67 entry: A tuple of (attribute name, attribute value).
68
69 Returns:
70 An opaque sort key.
71 """
72 attr, _ = entry
73 if attr == "name":
74 # Sort "name" first.
75 return ""
76 return attr
77
78def get_directive_value(directives, key):
79 """Get the value of a directive.
80
81 Args:
82 directives: A list of directives.
83 key: The key of the directive.
84
85 Returns:
86 The value of the last directive, or None if the directive is not
87 present.
88 """
89 prefix = "gazelle:" + key + " "
90
91 value = None
92 for directive in directives:
93 if directive.startswith(prefix):
94 # Treat "gazelle:key value" the same as "gazelle:key value".
95 value = directive[len(prefix):].lstrip()
96
97 return value
98
99def with_replaced_or_new_fields(_struct, **replacements):
100 """Provides a shallow copy of a structure with replacements and/or new fields
101
102 Args:
103 _struct: structure to shallow copy.
104 **replacements: kwargs for fields to either replace or add to the new struct.
105
106 Returns:
107 The resulting updated structure.
108 """
109
110 new_struct_assignments = {
111 key: getattr(_struct, key)
112 for key in dir(_struct)
113 if key not in _STRUCT_PROTECTED_ATTRIBUTES
114 }
115
116 # Overwrite existing fields and add new ones.
117 for key, value in replacements.items():
118 new_struct_assignments[key] = value
119
120 return struct(**new_struct_assignments)
121
122def extension_metadata(
123 module_ctx,
124 *,
125 root_module_direct_deps = None,
126 root_module_direct_dev_deps = None,
127 reproducible = False):
128 if not hasattr(module_ctx, "extension_metadata"):
129 return None
130 metadata_kwargs = {}
131 if bazel_features.external_deps.extension_metadata_has_reproducible:
132 metadata_kwargs["reproducible"] = reproducible
133 return module_ctx.extension_metadata(
134 root_module_direct_deps = root_module_direct_deps,
135 root_module_direct_dev_deps = root_module_direct_dev_deps,
136 **metadata_kwargs
137 )
View as plain text