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

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

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