xref: /aosp_15_r20/external/grpc-grpc/tools/run_tests/sanity/check_package_name.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1#!/usr/bin/env python3
2
3# Copyright 2021 gRPC authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import os
18import sys
19
20os.chdir(os.path.join(os.path.dirname(sys.argv[0]), "../../.."))
21
22# Allowance for overrides for specific files
23EXPECTED_NAMES = {
24    "src/proto/grpc/channelz": "channelz",
25    "src/proto/grpc/status": "status",
26    "src/proto/grpc/testing": "testing",
27    "src/proto/grpc/testing/duplicate": "duplicate",
28    "src/proto/grpc/lb/v1": "lb",
29    "src/proto/grpc/testing/xds": "xds",
30    "src/proto/grpc/testing/xds/v3": "xds_v3",
31    "src/proto/grpc/core": "core",
32    "src/proto/grpc/health/v1": "health",
33    "src/proto/grpc/reflection/v1alpha": "reflection",
34    "src/proto/grpc/reflection/v1": "reflection_v1",
35}
36
37errors = 0
38for root, dirs, files in os.walk("."):
39    if root.startswith("./"):
40        root = root[len("./") :]
41    # don't check third party
42    if root.startswith("third_party/"):
43        continue
44    # only check BUILD files
45    if "BUILD" not in files:
46        continue
47    text = open("%s/BUILD" % root).read()
48    # find a grpc_package clause
49    pkg_start = text.find("grpc_package(")
50    if pkg_start == -1:
51        continue
52    # parse it, taking into account nested parens
53    pkg_end = pkg_start + len("grpc_package(")
54    level = 1
55    while level == 1:
56        if text[pkg_end] == ")":
57            level -= 1
58        elif text[pkg_end] == "(":
59            level += 1
60        pkg_end += 1
61    # it's a python statement, so evaluate it to pull out the name of the package
62    name = eval(
63        text[pkg_start:pkg_end], {"grpc_package": lambda name, **kwargs: name}
64    )
65    # the name should be the path within the source tree, excepting some special
66    # BUILD files (really we should normalize them too at some point)
67    # TODO(ctiller): normalize all package names
68    expected_name = EXPECTED_NAMES.get(root, root)
69    if name != expected_name:
70        print(
71            "%s/BUILD should define a grpc_package with name=%r, not %r"
72            % (root, expected_name, name)
73        )
74        errors += 1
75
76if errors != 0:
77    sys.exit(1)
78