@@ -60,6 +60,20 @@ CONTAINER_EXE_EXTRA_ARGS = {
60
60
}
61
61
62
62
63
+ def get_container_exe ():
64
+ container_exe = None
65
+ for ce in CONTAINER_EXES :
66
+ if shutil .which (ce ) is not None :
67
+ container_exe = ce
68
+ break
69
+
70
+ if container_exe is None :
71
+ print ('Cannot find {} in $PATH' .format (' or ' .join (CONTAINER_EXES )))
72
+ return sys .exit (1 )
73
+
74
+ return container_exe
75
+
76
+
63
77
def fetch_python (snekdir , version ):
64
78
realver = PYVERS [version ]
65
79
if version in ('1.0' , '1.1' ):
@@ -142,6 +156,35 @@ def acquire_python(snekdir, version):
142
156
return pyexe
143
157
144
158
159
+ def build_python_container (snekdir , version ):
160
+ realver = PYVERS [version ]
161
+ snek = 'Python-{}' .format (realver )
162
+ builddir = os .path .join (snekdir , snek )
163
+ container_exe = get_container_exe ()
164
+ py_container_tag = 'python:{}' .format (realver )
165
+
166
+ if subprocess .call ([container_exe , 'image' , 'inspect' , py_container_tag ],
167
+ stdout = subprocess .DEVNULL ,
168
+ stderr = subprocess .DEVNULL ) == 0 :
169
+ return
170
+
171
+ fetch_python (snekdir , version )
172
+
173
+ print ('Building Python {} container...' .format (realver ))
174
+ logfile = os .path .join (snekdir , '{}.build.log' .format (snek ))
175
+ install_target = 'fullinstall' if version == '3.0' else 'install'
176
+ with open (logfile , 'wb' ) as log :
177
+ if subprocess .call ([container_exe , 'build' ,
178
+ '--build-arg' , 'python_version={}' .format (realver ),
179
+ '--build-arg' , 'install_target={}' .format (install_target ),
180
+ '-f' , os .path .join (snekdir , 'Dockerfile.pybuild' ),
181
+ '-t' , py_container_tag , snekdir ], stdout = log , stderr = log ) != 0 :
182
+ print ('...Container build failed. See {} for details' .format (logfile ))
183
+ sys .exit (1 )
184
+
185
+ shutil .rmtree (builddir )
186
+
187
+
145
188
def local_compile (snekdir , ver , infile ):
146
189
pyexe = acquire_python (snekdir , ver )
147
190
proc = subprocess .Popen ([pyexe , '-c' , 'import sys; print(sys.version)' ],
@@ -194,24 +237,14 @@ def local_compile(snekdir, ver, infile):
194
237
return outfile
195
238
196
239
197
- def container_compile (ver , infile ):
240
+ def container_compile (snekdir , ver , infile ):
198
241
if ver not in PYVER_CONTAINERS :
199
- print ('Container compilation not supported for version {}' .format (ver ))
200
- return None
201
-
202
- container_exe = None
203
- for ce in CONTAINER_EXES :
204
- if shutil .which (ce ) is not None :
205
- container_exe = ce
206
- break
207
-
208
- if container_exe is None :
209
- print ('Cannot find {} in $PATH' .format (' or ' .join (CONTAINER_EXES )))
210
- return None
242
+ build_python_container (snekdir , ver )
211
243
244
+ container_exe = get_container_exe ()
212
245
fullver = PYVERS [ver ]
213
-
214
246
indir = os .path .dirname (os .path .abspath (infile ))
247
+ infile_full_path = infile
215
248
infile = os .path .basename (infile )
216
249
217
250
if infile .endswith ('.py' ):
@@ -223,14 +256,38 @@ def container_compile(ver, infile):
223
256
os .unlink (outfile )
224
257
225
258
print ('*** Compiling for Python {}' .format (fullver ))
226
- proc = subprocess .Popen ([container_exe , 'run' ] + CONTAINER_EXE_EXTRA_ARGS [container_exe ] +
227
- ['--rm' , '--name' , '{}' .format (outfile ),
228
- '-v' , '{}:/indir:Z' .format (indir ),
229
- '-v' , '{}:/outdir:Z' .format (os .getcwd ()), '-w' , '/outdir' ,
230
- 'python:{}' .format (fullver ),
231
- 'python' , '-c' ,
232
- "import py_compile; py_compile.compile('/indir/{}', '{}')" .format (infile , outfile )])
233
- proc .communicate ()
259
+ if ver in {'1.0' , '1.1' , '1.2' , '1.3' , '1.4' }:
260
+ # The hard way -- hope your code is safe...
261
+ comptmp = os .path .join (indir , 'pymc_temp.py' )
262
+ if os .path .exists (comptmp ):
263
+ os .unlink (comptmp )
264
+ shutil .copyfile (infile_full_path , comptmp )
265
+ proc = subprocess .Popen ([container_exe , 'run' ] + CONTAINER_EXE_EXTRA_ARGS [container_exe ] +
266
+ ['--rm' , '--name' , outfile ,
267
+ '-v' , '{}:/indir:Z' .format (indir ),
268
+ '-v' , '{}:/outdir:Z' .format (os .getcwd ()), '-w' , '/outdir' ,
269
+ '-w' , '/indir' ,
270
+ 'python:{}' .format (fullver ),
271
+ 'python' , '-c' ,
272
+ "import pymc_temp" ])
273
+ proc .communicate ()
274
+ if os .path .exists (comptmp + 'o' ):
275
+ shutil .copyfile (comptmp + 'o' , outfile )
276
+ os .unlink (comptmp + 'o' )
277
+ elif os .path .exists (comptmp + 'c' ):
278
+ shutil .copyfile (comptmp + 'c' , outfile )
279
+ os .unlink (comptmp + 'c' )
280
+ os .unlink (comptmp )
281
+ else :
282
+ # The easy way
283
+ proc = subprocess .Popen ([container_exe , 'run' ] + CONTAINER_EXE_EXTRA_ARGS [container_exe ] +
284
+ ['--rm' , '--name' , outfile ,
285
+ '-v' , '{}:/indir:Z' .format (indir ),
286
+ '-v' , '{}:/outdir:Z' .format (os .getcwd ()), '-w' , '/outdir' ,
287
+ 'python:{}' .format (fullver ),
288
+ 'python' , '-c' ,
289
+ "import py_compile; py_compile.compile('/indir/{}', '{}')" .format (infile , outfile )])
290
+ proc .communicate ()
234
291
235
292
return outfile
236
293
@@ -282,12 +339,11 @@ result = 0
282
339
for ver in pythons :
283
340
compile_with_container = use_containers
284
341
if use_containers and ver not in PYVER_CONTAINERS :
285
- print ('Warning: No supported container for {} - using local build' .format (ver ))
286
- compile_with_container = False
342
+ print ('Warning: No officially supported container for {} - using locally built one' .format (ver ))
287
343
288
344
outfile = None
289
345
if compile_with_container :
290
- outfile = container_compile (ver , infile )
346
+ outfile = container_compile (snekdir , ver , infile )
291
347
else :
292
348
outfile = local_compile (snekdir , ver , infile )
293
349
0 commit comments