@ -30,16 +30,13 @@
# format entirely or simplify it to a point where it becomes self-explanatory
# format entirely or simplify it to a point where it becomes self-explanatory
# and doesn't need any detailed documentation.
# and doesn't need any detailed documentation.
from dataclasses import asdict
import collections
from dataclasses import dataclass
from dataclasses import field
import os
import os
import subprocess
import subprocess
from typing import Any , Dict , Iterable , List , Optional
from typing import Any , Dict , Iterable , List , Optional
import xml . etree . ElementTree as ET
import xml . etree . ElementTree as ET
import build_cleaner
import build_cleaner
import yaml
BuildMetadata = Dict [ str , Any ]
BuildMetadata = Dict [ str , Any ]
BuildDict = Dict [ str , BuildMetadata ]
BuildDict = Dict [ str , BuildMetadata ]
@ -50,19 +47,36 @@ BuildDict = Dict[str, BuildMetadata]
BuildYaml = Dict [ str , Any ]
BuildYaml = Dict [ str , Any ]
# This is basically a Python dict with predefined fields and types
@dataclass ( )
class ExternalProtoLibrary :
class ExternalProtoLibrary :
# The relative path of this proto library should be. Preferably, it should
""" ExternalProtoLibrary is the struct about an external proto library.
# match the submodule path.
destination : str
Fields :
# The prefix to remove in order to insure the proto import is correct. For
- destination ( int ) : The relative path of this proto library should be .
# more info, see description of https://github.com/grpc/grpc/pull/25272.
Preferably , it should match the submodule path .
proto_prefix : str
- proto_prefix ( str ) : The prefix to remove in order to insure the proto import
# Following 3 fields should be filled by build metadata from Bazel.
is correct . For more info , see description of
urls : List [ str ] = field ( default_factory = list )
https : / / github . com / grpc / grpc / pull / 25272.
hash : str = ' '
- urls ( List [ str ] ) : Following 3 fields should be filled by build metadata from
strip_prefix : str = ' '
Bazel .
- hash ( str ) : The hash of the downloaded archive
- strip_prefix ( str ) : The path to be stripped from the extracted directory , see
http_archive in Bazel .
"""
def __init__ ( self ,
destination ,
proto_prefix ,
urls = None ,
hash = " " ,
strip_prefix = " " ) :
self . destination = destination
self . proto_prefix = proto_prefix
if urls is None :
self . urls = [ ]
else :
self . urls = urls
self . hash = hash
self . strip_prefix = strip_prefix
EXTERNAL_PROTO_LIBRARIES = {
EXTERNAL_PROTO_LIBRARIES = {
@ -208,7 +222,7 @@ def _extract_sources(bazel_rule: BuildMetadata) -> List[str]:
if external_proto_library_name is not None :
if external_proto_library_name is not None :
result . append (
result . append (
src . replace (
src . replace (
f ' @ { external_proto_library_name } // ' ,
' @ %s // ' % external_proto_library_name ,
EXTERNAL_PROTO_LIBRARIES [
EXTERNAL_PROTO_LIBRARIES [
external_proto_library_name ] . proto_prefix ) .
external_proto_library_name ] . proto_prefix ) .
replace ( ' : ' , ' / ' ) )
replace ( ' : ' , ' / ' ) )
@ -790,7 +804,7 @@ def _generate_build_extra_metadata_for_tests(
return test_metadata
return test_metadata
def _parse_http_archives ( xml_tree : ET . Element ) - > List [ ExternalProtoLibrary ] :
def _parse_http_archives ( xml_tree : ET . Element ) - > ' List[ExternalProtoLibrary] ' :
""" Parse Bazel http_archive rule into ExternalProtoLibrary objects. """
""" Parse Bazel http_archive rule into ExternalProtoLibrary objects. """
result = [ ]
result = [ ]
for xml_http_archive in xml_tree :
for xml_http_archive in xml_tree :
@ -829,7 +843,7 @@ def _generate_external_proto_libraries() -> List[Dict[str, Any]]:
xml_tree = _bazel_query_xml_tree ( ' kind(http_archive, //external:*) ' )
xml_tree = _bazel_query_xml_tree ( ' kind(http_archive, //external:*) ' )
libraries = _parse_http_archives ( xml_tree )
libraries = _parse_http_archives ( xml_tree )
libraries . sort ( key = lambda x : x . destination )
libraries . sort ( key = lambda x : x . destination )
return list ( map ( as dict, libraries ) )
return list ( map ( lambda x : x . __ dict__ , libraries ) )
def _detect_and_print_issues ( build_yaml_like : BuildYaml ) - > None :
def _detect_and_print_issues ( build_yaml_like : BuildYaml ) - > None :