1+ import logging
12import os
3+ import pkg_resources
4+ import shutil
5+ import subprocess
26import sys
7+ import tarfile
8+ from urllib .request import urlopen
39
410from setuptools import setup , find_packages , Extension
511from setuptools .command .build_ext import build_ext
814LIBUAST_VERSION = "v1.9.1"
915SDK_VERSION = "v1.8.0"
1016SDK_MAJOR = SDK_VERSION .split ('.' )[0 ]
11- PYTHON = "python3"
17+ FORMAT_ARGS = globals ()
1218
1319# For debugging libuast-client interactions, set to True in production!
1420GET_LIBUAST = True
1521if not GET_LIBUAST :
16- print (' WARNING: not retrieving libuast, using local version' )
22+ print (" WARNING: not retrieving libuast, using local version" )
1723
18- os .environ ["CC" ] = "g++"
19- os .environ ["CXX" ] = "g++"
24+ if os .getenv ("CC" ) is None :
25+ os .environ ["CC" ] = "gcc"
26+ if os .getenv ("CXX" ) is None :
27+ os .environ ["CXX" ] = "g++"
2028libraries = ['xml2' ]
21- sources = ['bblfsh/pyuast.cc' , 'bblfsh/memtracker.cc' ]
29+ sources = ["bblfsh/pyuast.cc" , "bblfsh/memtracker.cc" ]
30+ log = logging .getLogger ("setup.py" )
2231
2332
2433class CustomBuildExt (build_ext ):
@@ -27,115 +36,178 @@ def run(self):
2736 global sources
2837
2938 if "--global-uast" in sys .argv :
30- libraries .append (' uast' )
39+ libraries .append (" uast" )
3140 else :
32- sources .append (' bblfsh/libuast/uast.cc' )
33- sources .append (' bblfsh/libuast/roles.c' )
41+ sources .append (" bblfsh/libuast/uast.cc" )
42+ sources .append (" bblfsh/libuast/roles.c" )
3443
35- getLibuast ()
44+ get_libuast ()
3645 build_ext .run (self )
3746
3847
39- def runc (cmd ):
40- cmd = cmd .format (** globals ())
41- print (cmd )
42- ret = os .system (cmd )
43- if ret != 0 :
44- raise Exception ("Command failed with output %d: %s" % (ret , cmd ))
45-
46-
47- def createDirs ():
48- runc ("mkdir -p gopkg.in/bblfsh/sdk.{SDK_MAJOR}/protocol" )
49- runc ("mkdir -p gopkg.in/bblfsh/sdk.{SDK_MAJOR}/uast" )
50- runc ("mkdir -p bblfsh/gopkg/in/bblfsh/sdk/{SDK_MAJOR}/protocol" )
51- runc ("mkdir -p bblfsh/gopkg/in/bblfsh/sdk/{SDK_MAJOR}/uast" )
52- runc ("mkdir -p bblfsh/github/com/gogo/protobuf/gogoproto" )
53-
54-
55- def createInits ():
56- initFiles = [
57- "bblfsh/github/__init__.py" ,
58- "bblfsh/github/com/__init__.py" ,
59- "bblfsh/github/com/gogo/__init__.py" ,
60- "bblfsh/github/com/gogo/protobuf/__init__.py" ,
61- "bblfsh/github/com/gogo/protobuf/gogoproto/__init__.py" ,
62- "bblfsh/gopkg/__init__.py" ,
63- "bblfsh/gopkg/in/__init__.py" ,
64- "bblfsh/gopkg/in/bblfsh/__init__.py" ,
65- "bblfsh/gopkg/in/bblfsh/sdk/__init__.py" ,
66- "bblfsh/gopkg/in/bblfsh/sdk/{}/__init__.py" .format (SDK_MAJOR ),
67- "bblfsh/gopkg/in/bblfsh/sdk/{}/uast/__init__.py" .format (SDK_MAJOR ),
68- "bblfsh/gopkg/in/bblfsh/sdk/{}/protocol/__init__.py" .format (SDK_MAJOR )
69- ]
48+ def j (* paths ):
49+ return os .path .join (* paths )
7050
71- for f in initFiles :
72- open (f , 'w' ).close ()
7351
52+ def mkdir (path ):
53+ path = path .format (** FORMAT_ARGS )
54+ log .info ("mkdir -p " + path )
55+ os .makedirs (path , exist_ok = True )
7456
75- def getLibuast ():
76- if not GET_LIBUAST :
77- return
7857
79- runc ("curl -SL https://github.com/bblfsh/libuast/archive/{LIBUAST_VERSION}/"
80- "{LIBUAST_VERSION}.tar.gz | tar xz" )
81- runc ("mv {} libuast" .format ('libuast-' + LIBUAST_VERSION .replace ('v' , '' )))
82- runc ("cp -a libuast/src bblfsh/libuast" )
83- runc ("rm -rf libuast" )
58+ def rimraf (path ):
59+ path = path .format (** FORMAT_ARGS )
60+ log .info ("rm -rf " + path )
61+ shutil .rmtree (path , ignore_errors = True )
8462
8563
86- def protoDownload ( ):
87- runc ( "curl -SL https://github.com/bblfsh/sdk/archive/{SDK_VERSION}.tar.gz | tar xz" )
88- dir_ = "sdk-" + SDK_VERSION [ 1 :]
89- runc ( "cp %s/protocol/generated.proto gopkg.in/bblfsh/sdk.{SDK_MAJOR}/protocol/" % dir_ )
90- runc ( "cp %s/uast/generated.proto gopkg.in/bblfsh/sdk.{SDK_MAJOR}/uast/" % dir_ )
91- runc ( "rm -rf %s" % dir_ )
64+ def mv ( src , dst ):
65+ src = src . format ( ** FORMAT_ARGS )
66+ dst = dst . format ( ** FORMAT_ARGS )
67+ log . info ( "mv %s %s" , src , dst )
68+ shutil . rmtree ( dst , ignore_errors = True )
69+ os . rename ( src , dst )
9270
9371
94- def protoCompile ():
95- # SDK
96- runc ("{PYTHON} -m grpc.tools.protoc --python_out=bblfsh/gopkg/in/bblfsh/sdk/{SDK_MAJOR}/protocol "
97- "--grpc_python_out=bblfsh/gopkg/in/bblfsh/sdk/{SDK_MAJOR}/protocol "
98- "-I gopkg.in/bblfsh/sdk.{SDK_MAJOR}/protocol -I . "
99- "gopkg.in/bblfsh/sdk.{SDK_MAJOR}/protocol/generated.proto" )
72+ def cp (src , dst ):
73+ src = src .format (** FORMAT_ARGS )
74+ dst = dst .format (** FORMAT_ARGS )
75+ log .info ("cp -p %s %s" , src , dst )
76+ shutil .rmtree (dst , ignore_errors = True )
77+ shutil .copy2 (src , dst )
78+
79+
80+ def cpr (src , dst ):
81+ src = src .format (** FORMAT_ARGS )
82+ dst = dst .format (** FORMAT_ARGS )
83+ log .info ("cp -pr %s %s" , src , dst )
84+ shutil .rmtree (dst , ignore_errors = True )
85+ shutil .copytree (src , dst , symlinks = True )
86+
87+
88+ def untar_url (url , path = "." ):
89+ log .info ("tar xf " + url )
90+ with urlopen (url ) as response :
91+ response .tell = lambda : 0 # tarfile calls it only once in the beginning
92+ with tarfile .open (fileobj = response , mode = ("r:" + url .rsplit ("." , 1 )[- 1 ])) as tar :
93+ tar .extractall (path = path )
94+
95+
96+ def call (* cmd ):
97+ log .info (" " .join (cmd ))
98+ subprocess .check_call (cmd )
99+
100+
101+ def create_dirs ():
102+ mkdir (j ("gopkg.in" , "bblfsh" , "sdk.{SDK_MAJOR}" , "protocol" ))
103+ mkdir (j ("gopkg.in" , "bblfsh" , "sdk.{SDK_MAJOR}" , "uast" ))
104+ mkdir (j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "protocol" ))
105+ mkdir (j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "uast" ))
106+ mkdir (j ("bblfsh" , "github" , "com" , "gogo" , "protobuf" , "gogoproto" ))
100107
108+
109+ def create_inits ():
110+ init_files = [
111+ j ("bblfsh" , "github" , "__init__.py" ),
112+ j ("bblfsh" , "github" , "com" , "__init__.py" ),
113+ j ("bblfsh" , "github" , "com" , "gogo" , "__init__.py" ),
114+ j ("bblfsh" , "github" , "com" , "gogo" , "protobuf" , "__init__.py" ),
115+ j ("bblfsh" , "github" , "com" , "gogo" , "protobuf" , "gogoproto" , "__init__.py" ),
116+ j ("bblfsh" , "gopkg" , "__init__.py" ),
117+ j ("bblfsh" , "gopkg" , "in" , "__init__.py" ),
118+ j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "__init__.py" ),
119+ j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , "__init__.py" ),
120+ j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "__init__.py" ),
121+ j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "uast" , "__init__.py" ),
122+ j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "protocol" , "__init__.py" ),
123+ ]
124+
125+ for f in init_files :
126+ open (f , "w" ).close ()
127+
128+
129+ def get_libuast ():
130+ if not GET_LIBUAST :
131+ return
132+
133+ untar_url (
134+ "https://github.com/bblfsh/libuast/archive/{LIBUAST_VERSION}/{LIBUAST_VERSION}.tar.gz"
135+ .format (** FORMAT_ARGS ))
136+ mv ("libuast-" + LIBUAST_VERSION .replace ("v" , "" ), "libuast" )
137+ cpr (j ("libuast" , "src" ), j ("bblfsh" , "libuast" ))
138+ rimraf ("libuast" )
139+
140+
141+ def proto_download ():
142+ untar_url ("https://github.com/bblfsh/sdk/archive/%s.tar.gz" % SDK_VERSION )
143+ sdkdir = "sdk-" + SDK_VERSION [1 :]
144+ cp (j (sdkdir , "protocol" , "generated.proto" ),
145+ j ("gopkg.in" , "bblfsh" , "sdk.{SDK_MAJOR}" , "protocol" , "generated.proto" ))
146+ cp (j (sdkdir , "uast" , "generated.proto" ),
147+ j ("gopkg.in" , "bblfsh" , "sdk.{SDK_MAJOR}" , "uast" , "generated.proto" ))
148+ rimraf (sdkdir )
149+
150+
151+ def proto_compile ():
152+ sysinclude = "-I" + pkg_resources .resource_filename ("grpc_tools" , "_proto" )
153+ from grpc .tools import protoc as protoc_module
154+
155+ def protoc (python_out , proto_file , * extra , grpc = True ):
156+ main_args = [protoc_module .__file__ , "--python_out=" + python_out ]
157+ if grpc :
158+ main_args += ["--grpc_python_out=" + python_out ]
159+ main_args += extra
160+ main_args += ["-I." , sysinclude , proto_file ]
161+ log .info ("%s -m grpc.tools.protoc " + " " .join (main_args ), sys .executable )
162+ protoc_module .main (main_args )
163+
164+ # SDK
165+ protoc (j ("bblfsh" , "gopkg" , "in" , "bblfsh" , "sdk" , SDK_MAJOR , "protocol" ),
166+ j ("gopkg.in" , "bblfsh" , "sdk." + SDK_MAJOR , "protocol" , "generated.proto" ),
167+ "-I" + j ("gopkg.in" , "bblfsh" , "sdk." + SDK_MAJOR , "protocol" ))
101168 # UAST
102- runc ("protoc --python_out bblfsh github.com/gogo/protobuf/gogoproto/gogo.proto" )
103- runc ("protoc --python_out bblfsh gopkg.in/bblfsh/sdk.{SDK_MAJOR}/uast/generated.proto" )
169+ protoc ("bblfsh" , j ("github.com" , "gogo" , "protobuf" , "gogoproto" , "gogo.proto" ),
170+ grpc = False )
171+ protoc ("bblfsh" , j ("gopkg.in" , "bblfsh" , "sdk." + SDK_MAJOR , "uast" , "generated.proto" ),
172+ grpc = False )
104173
105174
106- def doGetDeps ():
107- getLibuast ()
108- createDirs ()
109- createInits ()
110- protoDownload ()
111- protoCompile ()
175+ def do_get_deps ():
176+ get_libuast ()
177+ create_dirs ()
178+ create_inits ()
179+ proto_download ()
180+ proto_compile ()
112181
113182
114183def clean ():
115- runc ( "rm -rf gopkg.in" )
116- runc ( "rm -rf bblfsh/ github" )
117- runc ( "rm -rf bblfsh/ gopkg" )
184+ rimraf ( " gopkg.in" )
185+ rimraf ( j ( " bblfsh" , " github") )
186+ rimraf ( j ( " bblfsh" , " gopkg") )
118187 if GET_LIBUAST :
119- runc ( "rm -rf bblfsh/ libuast" )
188+ rimraf ( j ( " bblfsh" , " libuast") )
120189
121190
122191def main ():
123192 # The --global-uast flag allows to install the python driver using the installed uast library
193+ if "--log" in sys .argv :
194+ logging .basicConfig (level = logging .INFO )
195+
124196 if "--getdeps" in sys .argv :
125- doGetDeps ()
126- sys .exit (0 )
197+ do_get_deps ()
198+ sys .exit ()
127199
128200 if "--clean" in sys .argv :
129201 clean ()
130- sys .exit (0 )
202+ sys .exit ()
131203
132204 libuast_module = Extension (
133- ' bblfsh.pyuast' ,
205+ " bblfsh.pyuast" ,
134206 libraries = libraries ,
135- library_dirs = [' /usr/lib' , ' /usr/local/lib' ],
136- extra_compile_args = [' -std=c++11' ],
137- include_dirs = [' bblfsh/ libuast/' , ' /usr/local/include' , ' /usr/local/include/libxml2' ,
138- ' /usr/include' , ' /usr/include/libxml2' ], sources = sources )
207+ library_dirs = [" /usr/lib" , " /usr/local/lib" ],
208+ extra_compile_args = [" -std=c++11" ],
209+ include_dirs = [j ( " bblfsh" , " libuast" ), " /usr/local/include" , " /usr/local/include/libxml2" ,
210+ " /usr/include" , " /usr/include/libxml2" ], sources = sources )
139211
140212 setup (
141213 cmdclass = {
@@ -148,11 +220,12 @@ def main():
148220 author = "source{d}" ,
149221 author_email = "language-analysis@sourced.tech" ,
150222 url = "https://github.com/bblfsh/client-python" ,
151- download_url = ' https://github.com/bblfsh/client-python' ,
223+ download_url = " https://github.com/bblfsh/client-python" ,
152224 packages = find_packages (),
153225 exclude = ["bblfsh/test.py" ],
154226 keywords = ["babelfish" , "uast" ],
155227 install_requires = ["grpcio==1.10.0" , "grpcio-tools==1.10.0" , "docker" , "protobuf>=3.4.0" ],
228+
156229 package_data = {"" : ["LICENSE" , "README.md" ]},
157230 ext_modules = [libuast_module ],
158231 classifiers = [
@@ -164,10 +237,11 @@ def main():
164237 "Programming Language :: Python :: 3.4" ,
165238 "Programming Language :: Python :: 3.5" ,
166239 "Programming Language :: Python :: 3.6" ,
240+ "Programming Language :: Python :: 3.7" ,
167241 "Topic :: Software Development :: Libraries"
168242 ]
169243 )
170244
171245
172- if __name__ == ' __main__' :
246+ if __name__ == " __main__" :
173247 main ()
0 commit comments