|
8 | 8 | import tempfile
|
9 | 9 | import urllib.request
|
10 | 10 | import zipfile
|
| 11 | +import re |
| 12 | +from distutils import dir_util |
11 | 13 | from distutils.command import build
|
12 | 14 |
|
13 | 15 | from setuptools import setup
|
@@ -73,56 +75,74 @@ def _gen_grpc(self):
|
73 | 75 |
|
74 | 76 | proto_root_dir = root / 'azure_functions_worker' / 'protos'
|
75 | 77 | proto_src_dir = proto_root_dir / '_src' / 'src' / 'proto'
|
76 |
| - staging_root_dir = root / 'build' / 'protos' |
| 78 | + build_dir = root / 'build' |
| 79 | + staging_root_dir = build_dir / 'protos' |
77 | 80 | staging_dir = (staging_root_dir
|
78 | 81 | / 'azure_functions_worker' / 'protos')
|
79 |
| - build_dir = staging_dir / 'azure_functions_worker' / 'protos' |
80 |
| - built_protos_dir = root / 'build' / 'built_protos' |
81 |
| - built_proto_files_dir = (built_protos_dir |
82 |
| - / 'azure_functions_worker' / 'protos') |
| 82 | + built_protos_dir = build_dir / 'built_protos' |
83 | 83 |
|
84 |
| - if os.path.exists(build_dir): |
| 84 | + if os.path.exists(staging_root_dir): |
85 | 85 | shutil.rmtree(build_dir)
|
86 | 86 |
|
87 | 87 | if os.path.exists(built_protos_dir):
|
88 | 88 | shutil.rmtree(built_protos_dir)
|
89 | 89 |
|
90 |
| - proto_files = glob.glob(str(proto_src_dir / '**' / '*.proto'), |
91 |
| - recursive=True) |
| 90 | + shutil.copytree(proto_src_dir, staging_dir) |
92 | 91 |
|
93 |
| - os.makedirs(build_dir) |
94 |
| - for proto_file in proto_files: |
95 |
| - shutil.copy(proto_file, build_dir) |
| 92 | + os.makedirs(built_protos_dir) |
96 | 93 |
|
97 |
| - protos = [os.path.basename(proto_file) for proto_file in proto_files] |
| 94 | + protos = [ |
| 95 | + os.sep.join(('shared', 'NullableTypes.proto')), |
| 96 | + os.sep.join(('identity', 'ClaimsIdentityRpc.proto')), |
| 97 | + 'FunctionRpc.proto' |
| 98 | + ] |
98 | 99 |
|
99 |
| - full_protos = [] |
100 | 100 | for proto in protos:
|
101 |
| - full_proto = os.sep.join( |
102 |
| - ('azure_functions_worker', 'protos', |
103 |
| - 'azure_functions_worker', 'protos', proto) |
104 |
| - ) |
105 |
| - full_protos.append(full_proto) |
106 |
| - |
107 |
| - os.makedirs(built_protos_dir) |
108 |
| - subprocess.run([ |
109 |
| - sys.executable, '-m', 'grpc_tools.protoc', |
110 |
| - '-I', os.sep.join(('azure_functions_worker', 'protos')), |
111 |
| - '--python_out', str(built_protos_dir), |
112 |
| - '--grpc_python_out', str(built_protos_dir), |
113 |
| - *full_protos |
114 |
| - ], check=True, stdout=sys.stdout, stderr=sys.stderr, |
115 |
| - cwd=staging_root_dir) |
116 |
| - |
117 |
| - compiled = glob.glob(str(built_proto_files_dir / '*.py')) |
118 |
| - |
119 |
| - if not compiled: |
| 101 | + subprocess.run([ |
| 102 | + sys.executable, '-m', 'grpc_tools.protoc', |
| 103 | + '-I', os.sep.join(('azure_functions_worker', 'protos')), |
| 104 | + '--python_out', str(built_protos_dir), |
| 105 | + '--grpc_python_out', str(built_protos_dir), |
| 106 | + os.sep.join(('azure_functions_worker', 'protos', proto)), |
| 107 | + ], check=True, stdout=sys.stdout, stderr=sys.stderr, |
| 108 | + cwd=staging_root_dir) |
| 109 | + |
| 110 | + compiled_files = glob.glob( |
| 111 | + str(built_protos_dir / '**' / '*.py'), |
| 112 | + recursive=True) |
| 113 | + |
| 114 | + if not compiled_files: |
120 | 115 | print('grpc_tools.protoc produced no Python files',
|
121 | 116 | file=sys.stderr)
|
122 | 117 | sys.exit(1)
|
123 | 118 |
|
124 |
| - for f in compiled: |
125 |
| - shutil.copy(f, proto_root_dir) |
| 119 | + # Needed to support absolute imports in files. See |
| 120 | + # https://github.com/protocolbuffers/protobuf/issues/1491 |
| 121 | + self.make_absolute_imports(compiled_files) |
| 122 | + |
| 123 | + dir_util.copy_tree(built_protos_dir, str(proto_root_dir)) |
| 124 | + |
| 125 | + def make_absolute_imports(self, compiled_files): |
| 126 | + for compiled in compiled_files: |
| 127 | + with open(compiled, 'r+') as f: |
| 128 | + content = f.read() |
| 129 | + f.seek(0) |
| 130 | + # Convert lines of the form: |
| 131 | + # import xxx_pb2 as xxx__pb2 to |
| 132 | + # from azure_functions_worker.protos import xxx_pb2 as.. |
| 133 | + p1 = re.sub( |
| 134 | + r'\nimport (.*?_pb2)', |
| 135 | + r'\nfrom azure_functions_worker.protos import \g<1>', |
| 136 | + content) |
| 137 | + # Convert lines of the form: |
| 138 | + # from identity import xxx_pb2 as.. to |
| 139 | + # from azure_functions_worker.protos.identity import xxx_pb2.. |
| 140 | + p2 = re.sub( |
| 141 | + r'from ([a-z]*) (import.*_pb2)', |
| 142 | + r'from azure_functions_worker.protos.\g<1> \g<2>', |
| 143 | + p1) |
| 144 | + f.write(p2) |
| 145 | + f.truncate() |
126 | 146 |
|
127 | 147 |
|
128 | 148 | class build(build.build, BuildGRPC):
|
|
0 commit comments