Skip to content

Commit 0308e9d

Browse files
authored
chore(librarian): add ability to parse BUILD.bazel (googleapis#14386)
Towards googleapis/librarian#1929
1 parent 506c2d4 commit 0308e9d

4 files changed

Lines changed: 211 additions & 0 deletions

File tree

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Copyright 2025 Google LLC
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+
import starlark as sl
16+
17+
18+
_PY_CALLABLES = (
19+
"py_gapic_assembly_pkg",
20+
"py_gapic_library",
21+
"py_test",
22+
"py_proto_library",
23+
"py_grpc_library",
24+
"py_import",
25+
)
26+
27+
_JAVA_CALLABLES = (
28+
"java_gapic_assembly_gradle_pkg",
29+
"java_gapic_library",
30+
"java_gapic_test",
31+
"java_grpc_library",
32+
"java_proto_library",
33+
)
34+
35+
_GO_CALLABLES = (
36+
"go_gapic_assembly_pkg",
37+
"go_gapic_library",
38+
"go_proto_library",
39+
"go_grpc_library",
40+
)
41+
42+
_PHP_CALLABLES = (
43+
"php_gapic_assembly_pkg",
44+
"php_gapic_library",
45+
"php_grpc_library",
46+
"php_proto_library",
47+
)
48+
49+
_NODEJS_CALLABLES = ("nodejs_gapic_assembly_pkg", "nodejs_gapic_library")
50+
51+
_RUBY_CALLABLES = (
52+
"ruby_ads_gapic_library",
53+
"ruby_cloud_gapic_library",
54+
"ruby_gapic_assembly_pkg",
55+
"ruby_grpc_library",
56+
"ruby_proto_library",
57+
)
58+
59+
_CSHARP_CALLABLES = (
60+
"csharp_gapic_assembly_pkg",
61+
"csharp_gapic_library",
62+
"csharp_grpc_library",
63+
"csharp_proto_library",
64+
)
65+
66+
_CC_CALLABLES = ("cc_grpc_library", "cc_gapic_library", "cc_proto_library")
67+
68+
_MISC_CALLABLES = (
69+
"moved_proto_library",
70+
"proto_library",
71+
"proto_library_with_info",
72+
"upb_c_proto_library",
73+
)
74+
75+
_CALLABLE_MAP = {
76+
"@rules_proto//proto:defs.bzl": ("proto_library",),
77+
"@com_google_googleapis_imports//:imports.bzl": (
78+
_PY_CALLABLES
79+
+ _JAVA_CALLABLES
80+
+ _GO_CALLABLES
81+
+ _PHP_CALLABLES
82+
+ _NODEJS_CALLABLES
83+
+ _RUBY_CALLABLES
84+
+ _CSHARP_CALLABLES
85+
+ _CC_CALLABLES
86+
+ _MISC_CALLABLES
87+
),
88+
}
89+
90+
_NOOP_CALLABLES = (
91+
"package",
92+
"alias",
93+
"py_test",
94+
"sh_binary",
95+
"proto_library",
96+
"java_proto_library",
97+
"genrule",
98+
)
99+
100+
101+
def parse_content(content: str) -> dict:
102+
"""Parses content from BUILD.bazel and returns a dictionary
103+
containing bazel rules and arguments.
104+
105+
Args:
106+
content(str): contents of a BUILD.bazel.
107+
108+
Returns: Dictionary containing bazel rules and arguments.
109+
110+
"""
111+
glb = sl.Globals.standard()
112+
mod = sl.Module()
113+
packages = {}
114+
115+
def bazel_target(**args):
116+
if args["name"] is not None:
117+
packages[args["name"]] = args
118+
119+
def noop_bazel_rule(**args):
120+
pass
121+
122+
for noop_callable in _NOOP_CALLABLES:
123+
mod.add_callable(noop_callable, noop_bazel_rule)
124+
125+
def load(name):
126+
mod = sl.Module()
127+
for callable_name in _CALLABLE_MAP.get(name, []):
128+
mod.add_callable(callable_name, bazel_target)
129+
return mod.freeze()
130+
131+
ast = sl.parse("BUILD.bazel", content)
132+
133+
sl.eval(mod, ast, glb, sl.FileLoader(load))
134+
135+
return packages

.generator/requirements-test.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ pytest
1616
pytest-cov
1717
pytest-mock
1818
gcp-synthtool @ git+https://github.com/googleapis/synthtool@5aa438a342707842d11fbbb302c6277fbf9e4655
19+
starlark-pyo3>=2025.1
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2025 Google LLC
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+
package(default_visibility = ["//visibility:public"])
16+
load("@rules_proto//proto:defs.bzl", "proto_library")
17+
load(
18+
"@com_google_googleapis_imports//:imports.bzl",
19+
"py_gapic_library",
20+
)
21+
22+
proto_library(
23+
name = "language_proto",
24+
)
25+
26+
py_gapic_library(
27+
name = "language_py_gapic",
28+
srcs = [":language_proto"],
29+
grpc_service_config = "language_grpc_service_config.json",
30+
rest_numeric_enums = True,
31+
service_yaml = "language_v1.yaml",
32+
transport = "grpc+rest",
33+
deps = [
34+
],
35+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2025 Google LLC
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+
16+
import parse_googleapis_content
17+
from pathlib import Path
18+
19+
GENERATOR_DIR = Path(__file__).resolve().parent
20+
BUILD_BAZEL_PATH = f"{GENERATOR_DIR}/test-resources/librarian/BUILD.bazel"
21+
22+
23+
def test_parse_build_bazel():
24+
expected_result = {
25+
"language_proto": {"name": "language_proto"},
26+
"language_py_gapic": {
27+
"deps": [],
28+
"grpc_service_config": "language_grpc_service_config.json",
29+
"name": "language_py_gapic",
30+
"rest_numeric_enums": True,
31+
"service_yaml": "language_v1.yaml",
32+
"srcs": [":language_proto"],
33+
"transport": "grpc+rest",
34+
},
35+
}
36+
with open(BUILD_BAZEL_PATH, "r") as f:
37+
content = f.read()
38+
result = parse_googleapis_content.parse_content(content)
39+
40+
assert result == expected_result

0 commit comments

Comments
 (0)