Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: third_party/logilab/common/shellutils.py

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/logilab/common/registry.py ('k') | third_party/logilab/common/table.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3 # 3 #
4 # This file is part of logilab-common. 4 # This file is part of logilab-common.
5 # 5 #
6 # logilab-common is free software: you can redistribute it and/or modify it unde r 6 # logilab-common is free software: you can redistribute it and/or modify it unde r
7 # the terms of the GNU Lesser General Public License as published by the Free 7 # the terms of the GNU Lesser General Public License as published by the Free
8 # Software Foundation, either version 2.1 of the License, or (at your option) an y 8 # Software Foundation, either version 2.1 of the License, or (at your option) an y
9 # later version. 9 # later version.
10 # 10 #
11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT 11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 # details. 14 # details.
15 # 15 #
16 # You should have received a copy of the GNU Lesser General Public License along 16 # You should have received a copy of the GNU Lesser General Public License along
17 # with logilab-common. If not, see <http://www.gnu.org/licenses/>. 17 # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
18 """shell/term utilities, useful to write some python scripts instead of shell 18 """shell/term utilities, useful to write some python scripts instead of shell
19 scripts. 19 scripts.
20 """ 20 """
21
22 from __future__ import print_function
23
24 __docformat__ = "restructuredtext en" 21 __docformat__ = "restructuredtext en"
25 22
26 import os 23 import os
27 import glob 24 import glob
28 import shutil 25 import shutil
29 import stat 26 import stat
30 import sys 27 import sys
31 import tempfile 28 import tempfile
32 import time 29 import time
33 import fnmatch 30 import fnmatch
34 import errno 31 import errno
35 import string 32 import string
36 import random 33 import random
37 import subprocess
38 from os.path import exists, isdir, islink, basename, join 34 from os.path import exists, isdir, islink, basename, join
39 35
40 from six import string_types
41 from six.moves import range, input as raw_input
42
43 from logilab.common import STD_BLACKLIST, _handle_blacklist 36 from logilab.common import STD_BLACKLIST, _handle_blacklist
37 from logilab.common.compat import raw_input
44 from logilab.common.compat import str_to_bytes 38 from logilab.common.compat import str_to_bytes
45 from logilab.common.deprecation import deprecated
46 39
47 try: 40 try:
48 from logilab.common.proc import ProcInfo, NoSuchProcess 41 from logilab.common.proc import ProcInfo, NoSuchProcess
49 except ImportError: 42 except ImportError:
50 # windows platform 43 # windows platform
51 class NoSuchProcess(Exception): pass 44 class NoSuchProcess(Exception): pass
52 45
53 def ProcInfo(pid): 46 def ProcInfo(pid):
54 raise NoSuchProcess() 47 raise NoSuchProcess()
55 48
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 _action(filename, join(destination, basename(filename))) 106 _action(filename, join(destination, basename(filename)))
114 else: 107 else:
115 try: 108 try:
116 source = sources[0] 109 source = sources[0]
117 except IndexError: 110 except IndexError:
118 raise OSError('No file matching %s' % source) 111 raise OSError('No file matching %s' % source)
119 if isdir(destination) and exists(destination): 112 if isdir(destination) and exists(destination):
120 destination = join(destination, basename(source)) 113 destination = join(destination, basename(source))
121 try: 114 try:
122 _action(source, destination) 115 _action(source, destination)
123 except OSError as ex: 116 except OSError, ex:
124 raise OSError('Unable to move %r to %r (%s)' % ( 117 raise OSError('Unable to move %r to %r (%s)' % (
125 source, destination, ex)) 118 source, destination, ex))
126 119
127 def rm(*files): 120 def rm(*files):
128 """A shell-like rm, supporting wildcards. 121 """A shell-like rm, supporting wildcards.
129 """ 122 """
130 for wfile in files: 123 for wfile in files:
131 for filename in glob.glob(wfile): 124 for filename in glob.glob(wfile):
132 if islink(filename): 125 if islink(filename):
133 os.remove(filename) 126 os.remove(filename)
(...skipping 25 matching lines...) Expand all
159 152
160 :type blacklist: list or tuple 153 :type blacklist: list or tuple
161 :param blacklist: 154 :param blacklist:
162 optional list of files or directory to ignore, default to the value of 155 optional list of files or directory to ignore, default to the value of
163 `logilab.common.STD_BLACKLIST` 156 `logilab.common.STD_BLACKLIST`
164 157
165 :rtype: list 158 :rtype: list
166 :return: 159 :return:
167 the list of all matching files 160 the list of all matching files
168 """ 161 """
169 if isinstance(exts, string_types): 162 if isinstance(exts, basestring):
170 exts = (exts,) 163 exts = (exts,)
171 if exclude: 164 if exclude:
172 def match(filename, exts): 165 def match(filename, exts):
173 for ext in exts: 166 for ext in exts:
174 if filename.endswith(ext): 167 if filename.endswith(ext):
175 return False 168 return False
176 return True 169 return True
177 else: 170 else:
178 def match(filename, exts): 171 def match(filename, exts):
179 for ext in exts: 172 for ext in exts:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 os.mkdir(destdir) 217 os.mkdir(destdir)
225 zfobj = zipfile.ZipFile(archive) 218 zfobj = zipfile.ZipFile(archive)
226 for name in zfobj.namelist(): 219 for name in zfobj.namelist():
227 if name.endswith('/'): 220 if name.endswith('/'):
228 os.mkdir(join(destdir, name)) 221 os.mkdir(join(destdir, name))
229 else: 222 else:
230 outfile = open(join(destdir, name), 'wb') 223 outfile = open(join(destdir, name), 'wb')
231 outfile.write(zfobj.read(name)) 224 outfile.write(zfobj.read(name))
232 outfile.close() 225 outfile.close()
233 226
234
235 class Execute: 227 class Execute:
236 """This is a deadlock safe version of popen2 (no stdin), that returns 228 """This is a deadlock safe version of popen2 (no stdin), that returns
237 an object with errorlevel, out and err. 229 an object with errorlevel, out and err.
238 """ 230 """
239 231
240 def __init__(self, command): 232 def __init__(self, command):
241 cmd = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stde rr=subprocess.PIPE) 233 outfile = tempfile.mktemp()
242 self.out, self.err = cmd.communicate() 234 errfile = tempfile.mktemp()
243 self.status = os.WEXITSTATUS(cmd.returncode) 235 self.status = os.system("( %s ) >%s 2>%s" %
244 236 (command, outfile, errfile)) >> 8
245 Execute = deprecated('Use subprocess.Popen instead')(Execute) 237 self.out = open(outfile, "r").read()
246 238 self.err = open(errfile, "r").read()
239 os.remove(outfile)
240 os.remove(errfile)
247 241
248 def acquire_lock(lock_file, max_try=10, delay=10, max_delay=3600): 242 def acquire_lock(lock_file, max_try=10, delay=10, max_delay=3600):
249 """Acquire a lock represented by a file on the file system 243 """Acquire a lock represented by a file on the file system
250 244
251 If the process written in lock file doesn't exist anymore, we remove the 245 If the process written in lock file doesn't exist anymore, we remove the
252 lock file immediately 246 lock file immediately
253 If age of the lock_file is greater than max_delay, then we raise a UserWarni ng 247 If age of the lock_file is greater than max_delay, then we raise a UserWarni ng
254 """ 248 """
255 count = abs(max_try) 249 count = abs(max_try)
256 while count: 250 while count:
257 try: 251 try:
258 fd = os.open(lock_file, os.O_EXCL | os.O_RDWR | os.O_CREAT) 252 fd = os.open(lock_file, os.O_EXCL | os.O_RDWR | os.O_CREAT)
259 os.write(fd, str_to_bytes(str(os.getpid())) ) 253 os.write(fd, str_to_bytes(str(os.getpid())) )
260 os.close(fd) 254 os.close(fd)
261 return True 255 return True
262 except OSError as e: 256 except OSError, e:
263 if e.errno == errno.EEXIST: 257 if e.errno == errno.EEXIST:
264 try: 258 try:
265 fd = open(lock_file, "r") 259 fd = open(lock_file, "r")
266 pid = int(fd.readline()) 260 pid = int(fd.readline())
267 pi = ProcInfo(pid) 261 pi = ProcInfo(pid)
268 age = (time.time() - os.stat(lock_file)[stat.ST_MTIME]) 262 age = (time.time() - os.stat(lock_file)[stat.ST_MTIME])
269 if age / max_delay > 1 : 263 if age / max_delay > 1 :
270 raise UserWarning("Command '%s' (pid %s) has locked the " 264 raise UserWarning("Command '%s' (pid %s) has locked the "
271 "file '%s' for %s minutes" 265 "file '%s' for %s minutes"
272 % (pi.name(), pid, lock_file, age/60)) 266 % (pi.name(), pid, lock_file, age/60))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 def _set_text(self, text=None): 308 def _set_text(self, text=None):
315 if text != self._current_text: 309 if text != self._current_text:
316 self._current_text = text 310 self._current_text = text
317 self.refresh() 311 self.refresh()
318 312
319 def _del_text(self): 313 def _del_text(self):
320 self.text = None 314 self.text = None
321 315
322 text = property(_get_text, _set_text, _del_text) 316 text = property(_get_text, _set_text, _del_text)
323 317
324 def update(self, offset=1, exact=False): 318 def update(self):
325 """Move FORWARD to new cursor position (cursor will never go backward). 319 """Update the progression bar."""
326 320 self._current += 1
327 :offset: fraction of ``size``
328
329 :exact:
330
331 - False: offset relative to current cursor position if True
332 - True: offset as an asbsolute position
333
334 """
335 if exact:
336 self._current = offset
337 else:
338 self._current += offset
339
340 progress = int((float(self._current)/float(self._total))*self._size) 321 progress = int((float(self._current)/float(self._total))*self._size)
341 if progress > self._progress: 322 if progress > self._progress:
342 self._progress = progress 323 self._progress = progress
343 self.refresh() 324 self.refresh()
344 325
345 def refresh(self): 326 def refresh(self):
346 """Refresh the progression bar display.""" 327 """Refresh the progression bar display."""
347 self._stream.write(self._fstr % ('=' * min(self._progress, self._size)) ) 328 self._stream.write(self._fstr % ('.' * min(self._progress, self._size)) )
348 if self._last_text_write_size or self._current_text: 329 if self._last_text_write_size or self._current_text:
349 template = ' %%-%is' % (self._last_text_write_size) 330 template = ' %%-%is' % (self._last_text_write_size)
350 text = self._current_text 331 text = self._current_text
351 if text is None: 332 if text is None:
352 text = '' 333 text = ''
353 self._stream.write(template % text) 334 self._stream.write(template % text)
354 self._last_text_write_size = len(text.rstrip()) 335 self._last_text_write_size = len(text.rstrip())
355 self._stream.flush() 336 self._stream.flush()
356 337
357 def finish(self): 338 def finish(self):
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 if len(possible) == 1: 405 if len(possible) == 1:
425 return possible[0] 406 return possible[0]
426 elif len(possible) == 0: 407 elif len(possible) == 0:
427 msg = '%s is not an option.' % answer 408 msg = '%s is not an option.' % answer
428 else: 409 else:
429 msg = ('%s is an ambiguous answer, do you mean %s ?' % ( 410 msg = ('%s is an ambiguous answer, do you mean %s ?' % (
430 answer, ' or '.join(possible))) 411 answer, ' or '.join(possible)))
431 if self._print: 412 if self._print:
432 self._print(msg) 413 self._print(msg)
433 else: 414 else:
434 print(msg) 415 print msg
435 tries -= 1 416 tries -= 1
436 raise Exception('unable to get a sensible answer') 417 raise Exception('unable to get a sensible answer')
437 418
438 def confirm(self, question, default_is_yes=True): 419 def confirm(self, question, default_is_yes=True):
439 default = default_is_yes and 'y' or 'n' 420 default = default_is_yes and 'y' or 'n'
440 answer = self.ask(question, ('y', 'n'), default) 421 answer = self.ask(question, ('y', 'n'), default)
441 return answer == 'y' 422 return answer == 'y'
442 423
443 ASK = RawInput() 424 ASK = RawInput()
444 425
445 426
446 def getlogin(): 427 def getlogin():
447 """avoid using os.getlogin() because of strange tty / stdin problems 428 """avoid using os.getlogin() because of strange tty / stdin problems
448 (man 3 getlogin) 429 (man 3 getlogin)
449 Another solution would be to use $LOGNAME, $USER or $USERNAME 430 Another solution would be to use $LOGNAME, $USER or $USERNAME
450 """ 431 """
451 if sys.platform != 'win32': 432 if sys.platform != 'win32':
452 import pwd # Platforms: Unix 433 import pwd # Platforms: Unix
453 return pwd.getpwuid(os.getuid())[0] 434 return pwd.getpwuid(os.getuid())[0]
454 else: 435 else:
455 return os.environ['USERNAME'] 436 return os.environ['USERNAME']
456 437
457 def generate_password(length=8, vocab=string.ascii_letters + string.digits): 438 def generate_password(length=8, vocab=string.ascii_letters + string.digits):
458 """dumb password generation function""" 439 """dumb password generation function"""
459 pwd = '' 440 pwd = ''
460 for i in range(length): 441 for i in xrange(length):
461 pwd += random.choice(vocab) 442 pwd += random.choice(vocab)
462 return pwd 443 return pwd
OLDNEW
« no previous file with comments | « third_party/logilab/common/registry.py ('k') | third_party/logilab/common/table.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698