@@ -186,157 +186,126 @@ def _busy_spinner(evnt):
186186wait = random .randint (10 ,100 )* 0.001
187187
188188
189- def spawn (cmd_ ,out_to_screen = True ,spinner = False ,env = None ,cmpl = False , unix = False ):
189+ def spawn (cmd_ ,out_to_screen = True ,spinner = False ,env = None ,cmpl = False ):
190190if env is None :
191191env = os .environ
192192
193- if sys .platform .startswith ('win' ):
194- prompt = b'>'
195- else :
196- prompt = b'$'
197-
198193if isinstance (cmd_ [0 ],str ):
199194cmd_ = ' ' .join (cmd_ )
200195else :
201196cmd_ = ' && ' .join (' ' .join (c )for c in cmd_ )
202197
203- def read ():
204- output_buffer = b''
205- line = ''
206- r_beg = False
207- newline = False
208- last_line_len = 0
209- while p .poll ()is None :
210- o_char = p .stdout .read (1 )
211- while o_char != b'' :
212- output_buffer += o_char
213- if out_to_screen and not spinner and cmpl :
214- if o_char == b'\n ' :
215- newline = True
216- o_char = p .stdout .read (1 )
217- continue
218- elif o_char == b'[' :
219- if newline :
220- if r_beg :
221- sys .stdout .write ('\r ' )
222- sys .stdout .write (' ' * last_line_len )
223- sys .stdout .write ('\r ' )
224- sys .stdout .flush ()
225- else :
226- sys .stdout .write ('\n ' )
227- sys .stdout .flush ()
228- r_beg = True
229-
230- last_line_len = 0
231- newline = False
198+ p = subprocess .Popen (
199+ cmd_ ,
200+ stdout = subprocess .PIPE ,
201+ stderr = subprocess .PIPE ,
202+ shell = True ,
203+ env = env
204+ )
232205
233- else :
234- r_beg = False
235-
236- if newline :
237- last_line_len = 0
238- newline = False
239- sys .stdout .write ('\n ' )
240- sys .stdout .flush ()
241- r_beg = False
242-
243- last_line_len += 1
244- try :
245- sys .stdout .write (o_char .decode ('utf-8' ))
246- except UnicodeDecodeError :
247- sys .stdout .write (str (o_char )[2 :- 1 ])
248- sys .stdout .flush ()
206+ os .set_blocking (p .stdout .fileno (),False )
207+ os .set_blocking (p .stderr .fileno (),False )
249208
250- elif out_to_screen and not cmpl :
251- try :
252- line += o_char .decode ('utf-8' )
253- except UnicodeDecodeError :
254- line += str (o_char )[2 :- 1 ]
209+ event = threading .Event ()
255210
256- if o_char == b'\n ' :
257- sys .stdout .write (line )
258- line = ''
259- sys .stdout .flush ()
211+ if spinner :
212+ t = threading .Thread (target = _busy_spinner ,args = (event ,))
213+ t .daemon = True
214+ t .start ()
215+ else :
216+ t = None
260217
261- # output_buffer+= o_char
262- o_char = p . stdout . read ( 1 )
218+ output_buffer = []
219+ last_line_len = - 1
263220
264- e_char = p .stderr .read (1 )
265- while e_char != b'' :
266- if out_to_screen and not spinner :
267- try :
268- sys .stderr .write (e_char .decode ('utf-8' ))
269- except UnicodeDecodeError :
270- sys .stderr .write (str (o_char )[2 :- 1 ])
271- sys .stderr .flush ()
272- output_buffer += e_char
273- e_char = p .stderr .read (1 )
221+ def _convert_line (lne ):
222+ try :
223+ lne = lne .decode ('utf-8' )
224+ except UnicodeDecodeError :
225+ for char in lne :
226+ if 32 <= char <= 125 or char in (b'\r ' ,b'\n ' ):
227+ continue
274228
275- if output_buffer . endswith ( prompt ):
276- break
229+ lne = lne . replace ( char , b'' )
230+ lne = lne . decode ( 'utf-8' )
277231
278- if not e_char and not o_char :
279- break
232+ return lne
280233
281- return output_buffer
234+ try :
235+ while p .poll ()is None :
236+ line = p .stdout .readline ()
237+ if line is not None and line .strip ():
238+ line = _convert_line (line .strip ())
239+ output_buffer .append (line )
240+
241+ if not spinner and out_to_screen :
242+ if cmpl and line .startswith ('[' )and last_line_len != - 1 :
243+ sys .stdout .write ('\r ' )
244+ if len (line )< last_line_len :
245+ padding = ' ' * (last_line_len - len (line ))
246+ else :
247+ padding = ''
282248
283- if unix :
284- p = subprocess .Popen (
285- cmd_ ,
286- shell = True ,
287- env = env
288- )
289- p .communicate ()
249+ sys .stdout .write (line + padding )
250+ last_line_len = len (line )
251+ else :
252+ last_line_len = - 1
253+ sys .stdout .write (line + '\n ' )
290254
291- return p .returncode ,None
292- else :
293- p = subprocess .Popen (
294- cmd_ ,
295- stdout = subprocess .PIPE ,
296- stderr = subprocess .PIPE ,
297- shell = True ,
298- env = env
299- )
255+ sys .stdout .flush ()
300256
301- if out_to_screen :
302- print (cmd_ )
257+ line = p .stderr .readline ()
258+ while line is not None and line .strip ():
259+ if not spinner and out_to_screen and cmpl and last_line_len != - 1 :
260+ sys .stdout .write ('\n ' )
261+ sys .stdout .flush ()
262+ last_line_len = - 1
303263
304- event = threading .Event ()
264+ line = _convert_line (line .strip ())
265+ output_buffer .append (line )
305266
306- if spinner :
307- t = threading .Thread (target = _busy_spinner ,args = (event ,))
308- t .daemon = True
309- t .start ()
310- else :
311- t = None
267+ if out_to_screen and not spinner :
268+ sys .stderr .write (line + '\n ' )
269+ sys .stderr .flush ()
312270
313- o_buf = read ()
271+ line = p . stderr . readline ()
314272
315- try :
316- o_buf = o_buf .decode ('utf-8' )
317- except UnicodeDecodeError :
318- for char in o_buf :
319- if 32 <= char <= 125 or char in (b'\r ' ,b'\n ' ):
320- continue
321-
322- o_buf = o_buf .replace (char ,b'' )
273+ except KeyboardInterrupt :
274+ if t is not None :
275+ event .set ()
276+ t .join ()
323277
324- o_buf = o_buf .decode ('utf-8' )
278+ print ()
279+ print (output_buffer )
325280
326281if not p .stdout .closed :
327282p .stdout .close ()
328283
329284if not p .stderr .closed :
330285p .stderr .close ()
331286
332- if t is not None :
333- event .set ()
334- t .join ()
287+ raise
288+
289+ if not p .stdout .closed :
290+ p .stdout .close ()
335291
336- if out_to_screen and spinner :
337- print (o_buf )
292+ if not p .stderr .closed :
293+ p .stderr .close ()
294+
295+ if t is not None :
296+ event .set ()
297+ t .join ()
298+
299+ output_buffer = '\n ' .join (output_buffer )
300+
301+ if out_to_screen :
302+ if spinner :
303+ print (output_buffer )
304+ elif cmpl and last_line_len != - 1 :
305+ sys .stdout .write ('\n ' )
306+ sys .stdout .flush ()
338307
339- return p .returncode ,o_buf
308+ return p .returncode ,output_buffer
340309
341310
342311def clean ():