1#!/usr/bin/env python2.7 2# Copyright 2015 gRPC authors. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Generates the appropriate build.json data for all the proto files.""" 16 17import yaml 18import collections 19import os 20import re 21import sys 22 23 24def update_deps(key, proto_filename, deps, deps_external, is_trans, visited): 25 if not proto_filename in visited: 26 visited.append(proto_filename) 27 with open(proto_filename) as inp: 28 for line in inp: 29 imp = re.search(r'import "([^"]*)"', line) 30 if not imp: 31 continue 32 imp_proto = imp.group(1) 33 # This indicates an external dependency, which we should handle 34 # differently and not traverse recursively 35 if imp_proto.startswith("google/"): 36 if key not in deps_external: 37 deps_external[key] = [] 38 deps_external[key].append(imp_proto[:-6]) 39 continue 40 if imp_proto.startswith("xds/"): 41 if key not in deps_external: 42 deps_external[key] = [] 43 deps_external[key].append(imp_proto[:-3]) 44 continue 45 if imp_proto.startswith("envoy/"): 46 if key not in deps_external: 47 deps_external[key] = [] 48 deps_external[key].append(imp_proto[:-5]) 49 continue 50 # In case that the path is changed by copybara, 51 # revert the change to avoid file error. 52 if imp_proto.startswith("third_party/grpc"): 53 imp_proto = imp_proto[17:] 54 if key not in deps: 55 deps[key] = [] 56 deps[key].append(imp_proto[:-6]) 57 if is_trans: 58 update_deps( 59 key, imp_proto, deps, deps_external, is_trans, visited 60 ) 61 62 63def main(): 64 proto_dir = os.path.abspath(os.path.dirname(sys.argv[0])) 65 os.chdir(os.path.join(proto_dir, "../..")) 66 67 deps = {} 68 deps_trans = {} 69 deps_external = {} 70 deps_external_trans = {} 71 for root, dirs, files in os.walk("src/proto"): 72 for f in files: 73 if f[-6:] != ".proto": 74 continue 75 look_at = os.path.join(root, f) 76 deps_for = look_at[:-6] 77 # First level deps 78 update_deps(deps_for, look_at, deps, deps_external, False, []) 79 # Transitive deps 80 update_deps( 81 deps_for, look_at, deps_trans, deps_external_trans, True, [] 82 ) 83 84 json = { 85 "proto_deps": deps, 86 "proto_transitive_deps": deps_trans, 87 "proto_external_deps": deps_external, 88 "proto_transitive_external_deps": deps_external_trans, 89 } 90 91 print(yaml.dump(json)) 92 93 94if __name__ == "__main__": 95 main() 96