|
1 | | -import fileinput |
| 1 | +import glob |
2 | 2 | import logging |
3 | 3 | import os |
4 | 4 | import pkg_resources |
| 5 | +import re |
5 | 6 | import shutil |
6 | 7 | import subprocess |
7 | 8 | import sys |
|
11 | 12 | from setuptools import setup, find_packages, Extension |
12 | 13 | from setuptools.command.build_ext import build_ext |
13 | 14 |
|
14 | | -VERSION = "2.11.2" |
| 15 | +VERSION = "2.12.0" |
15 | 16 | LIBUAST_VERSION = "v1.9.5" |
16 | 17 | SDK_VERSION = "v1.16.1" |
17 | 18 | SDK_MAJOR = SDK_VERSION.split('.')[0] |
@@ -101,8 +102,8 @@ def call(*cmd): |
101 | 102 |
|
102 | 103 |
|
103 | 104 | def create_dirs(): |
104 | | - mkdir(j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol")) |
105 | | - mkdir(j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast")) |
| 105 | + mkdir(j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol")) |
| 106 | + mkdir(j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast")) |
106 | 107 | mkdir(j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR, "protocol")) |
107 | 108 | mkdir(j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR, "uast")) |
108 | 109 | mkdir(j("bblfsh", "github", "com", "gogo", "protobuf", "gogoproto")) |
@@ -143,42 +144,80 @@ def get_libuast(): |
143 | 144 | def proto_download(): |
144 | 145 | untar_url("https://github.com/bblfsh/sdk/archive/%s.tar.gz" % SDK_VERSION) |
145 | 146 | sdkdir = "sdk-" + SDK_VERSION[1:] |
146 | | - cp(j(sdkdir, "protocol", "generated.proto"), |
147 | | - j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol", "generated.proto")) |
148 | | - cp(j(sdkdir, "uast", "generated.proto"), |
149 | | - j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast", "generated.proto")) |
| 147 | + destdir = j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}") |
| 148 | + cp(j(sdkdir, "protocol", "generated.proto"), j(destdir, "protocol", "generated.proto")) |
| 149 | + cp(j(sdkdir, "uast", "generated.proto"), j(destdir, "uast", "generated.proto")) |
150 | 150 | rimraf(sdkdir) |
151 | 151 |
|
152 | 152 |
|
153 | 153 | def proto_compile(): |
154 | 154 | sysinclude = "-I" + pkg_resources.resource_filename("grpc_tools", "_proto") |
155 | 155 | from grpc.tools import protoc as protoc_module |
156 | 156 |
|
157 | | - def protoc(python_out, proto_file, *extra, grpc=True): |
158 | | - main_args = [protoc_module.__file__, "--python_out=" + python_out] |
| 157 | + from_import_re = re.compile(r"from ((github|gopkg)\.[^ ]*) import (.*)") |
| 158 | + importlib_import_re = re.compile(r"([^ ]+) = importlib\.import_module\('(.*)") |
| 159 | + grpc_import_re = re.compile( |
| 160 | + r"from (([^ .]+\.)*in(\.[^ .]+)*) import ([^ ]+) as ([^\n]+)") |
| 161 | + |
| 162 | + def patch(file, *patchers): |
| 163 | + with open(file) as fin: |
| 164 | + code = fin.readlines() |
| 165 | + for i, line in enumerate(code): |
| 166 | + for regexp, replacer in patchers: |
| 167 | + match = regexp.match(line) |
| 168 | + if match: |
| 169 | + code[i] = replacer(match) |
| 170 | + log.info("patched import in %s: %s", file, match.groups()[0]) |
| 171 | + break |
| 172 | + if line.startswith("class") or line.startswith("DESCRIPTOR"): |
| 173 | + break |
| 174 | + with open(file, "w") as fout: |
| 175 | + fout.write("".join(code)) |
| 176 | + |
| 177 | + def protoc(proto_file, grpc=False): |
| 178 | + main_args = [protoc_module.__file__, "--python_out=bblfsh"] |
| 179 | + target_dir = j("bblfsh", *os.path.dirname(proto_file).split(".")) |
159 | 180 | if grpc: |
160 | | - main_args += ["--grpc_python_out=" + python_out] |
161 | | - main_args += extra |
162 | | - main_args += ["-I.", sysinclude, proto_file] |
163 | | - log.info("%s -m grpc.tools.protoc " + " ".join(main_args), sys.executable) |
| 181 | + # using "." creates "gopkg.in" instead of "gopkg/in" directories |
| 182 | + main_args += ["--grpc_python_out=" + target_dir] |
| 183 | + main_args += ["-Iproto", sysinclude, j("proto", proto_file)] |
| 184 | + log.info("%s -m grpc.tools.protoc " + " ".join(main_args[1:]), sys.executable) |
164 | 185 | protoc_module.main(main_args) |
165 | | - |
166 | | - sdk_root = j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR) |
167 | | - # SDK |
168 | | - protoc(j(sdk_root, "protocol"), |
169 | | - j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol", "generated.proto"), |
170 | | - "-I" + j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol")) |
171 | | - # UAST |
172 | | - protoc("bblfsh", j("github.com", "gogo", "protobuf", "gogoproto", "gogo.proto"), |
173 | | - grpc=False) |
174 | | - protoc("bblfsh", j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "uast", "generated.proto"), |
175 | | - grpc=False) |
176 | | - for line in fileinput.input([j(sdk_root, "protocol", "generated_pb2.py"), |
177 | | - j(sdk_root, "uast", "generated_pb2.py")], |
178 | | - inplace=True): |
179 | | - print(line.replace("from github.com.gogo.protobuf.gogoproto import", |
180 | | - "from bblfsh.github.com.gogo.protobuf.gogoproto import"), |
181 | | - end="") |
| 186 | + if grpc: |
| 187 | + # we need to move the file back to grpc_out |
| 188 | + grpc_garbage_dir = None |
| 189 | + target = j(target_dir, "generated_pb2_grpc.py") |
| 190 | + for root, dirnames, filenames in os.walk(target_dir): |
| 191 | + for filename in filenames: |
| 192 | + if filename == "generated_pb2_grpc.py" and grpc_garbage_dir is not None: |
| 193 | + mv(j(root, filename), target) |
| 194 | + if os.path.samefile(root, target_dir): |
| 195 | + grpc_garbage_dir = j(root, dirnames[0]) |
| 196 | + rimraf(grpc_garbage_dir) |
| 197 | + |
| 198 | + # grpc ignores "in" and we need to patch the import path |
| 199 | + def grpc_replacer(match): |
| 200 | + groups = match.groups() |
| 201 | + return 'import importlib\n%s = importlib.import_module("bblfsh.%s.%s")\n' % ( |
| 202 | + groups[-1], groups[0], groups[-2]) |
| 203 | + |
| 204 | + patch(target, (grpc_import_re, grpc_replacer)) |
| 205 | + |
| 206 | + target = glob.glob(j(target_dir, "*_pb2.py"))[0] |
| 207 | + |
| 208 | + def from_import_replacer(match): |
| 209 | + return "from bblfsh.%s import %s\n" % (match.group(1), match.group(3)) |
| 210 | + |
| 211 | + def importlib_import_replacer(match): |
| 212 | + return "%s = importlib.import_module('bblfsh.%s\n" % (match.group(1), match.group(2)) |
| 213 | + |
| 214 | + patch(target, |
| 215 | + (from_import_re, from_import_replacer), |
| 216 | + (importlib_import_re, importlib_import_replacer)) |
| 217 | + |
| 218 | + protoc(j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol", "generated.proto"), True) |
| 219 | + protoc(j("github.com", "gogo", "protobuf", "gogoproto", "gogo.proto")) |
| 220 | + protoc(j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "uast", "generated.proto")) |
182 | 221 |
|
183 | 222 |
|
184 | 223 | def do_get_deps(): |
|
0 commit comments