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