OLD | NEW |
1 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """SCM-specific utility classes.""" | 5 """SCM-specific utility classes.""" |
6 | 6 |
7 import cStringIO | 7 import cStringIO |
8 import glob | 8 import glob |
9 import os | 9 import os |
10 import re | 10 import re |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 # Prepend '+' to every lines. | 58 # Prepend '+' to every lines. |
59 for line in file_content: | 59 for line in file_content: |
60 data.write('+') | 60 data.write('+') |
61 data.write(line) | 61 data.write(line) |
62 result = data.getvalue() | 62 result = data.getvalue() |
63 data.close() | 63 data.close() |
64 return result | 64 return result |
65 | 65 |
66 | 66 |
67 class GIT(object): | 67 class GIT(object): |
68 COMMAND = "git" | |
69 | |
70 @staticmethod | 68 @staticmethod |
71 def Capture(args, in_directory=None, print_error=True, error_ok=False): | 69 def Capture(args, in_directory=None, print_error=True, error_ok=False): |
72 """Runs git, capturing output sent to stdout as a string. | 70 """Runs git, capturing output sent to stdout as a string. |
73 | 71 |
74 Args: | 72 Args: |
75 args: A sequence of command line parameters to be passed to git. | 73 args: A sequence of command line parameters to be passed to git. |
76 in_directory: The directory where git is to be run. | 74 in_directory: The directory where git is to be run. |
77 | 75 |
78 Returns: | 76 Returns: |
79 The output sent to stdout as a string. | 77 The output sent to stdout as a string. |
80 """ | 78 """ |
81 c = [GIT.COMMAND] | |
82 c.extend(args) | |
83 try: | 79 try: |
84 return gclient_utils.CheckCall(c, in_directory, print_error) | 80 return gclient_utils.CheckCall(['git'] + args, in_directory, print_error) |
85 except gclient_utils.CheckCallError: | 81 except gclient_utils.CheckCallError: |
86 if error_ok: | 82 if error_ok: |
87 return ('', '') | 83 return ('', '') |
88 raise | 84 raise |
89 | 85 |
90 @staticmethod | 86 @staticmethod |
91 def CaptureStatus(files, upstream_branch=None): | 87 def CaptureStatus(files, upstream_branch=None): |
92 """Returns git status. | 88 """Returns git status. |
93 | 89 |
94 @files can be a string (one file) or a list of files. | 90 @files can be a string (one file) or a list of files. |
(...skipping 15 matching lines...) Expand all Loading... |
110 results = [] | 106 results = [] |
111 if status: | 107 if status: |
112 for statusline in status.split('\n'): | 108 for statusline in status.split('\n'): |
113 m = re.match('^(\w)\t(.+)$', statusline) | 109 m = re.match('^(\w)\t(.+)$', statusline) |
114 if not m: | 110 if not m: |
115 raise Exception("status currently unsupported: %s" % statusline) | 111 raise Exception("status currently unsupported: %s" % statusline) |
116 results.append(('%s ' % m.group(1), m.group(2))) | 112 results.append(('%s ' % m.group(1), m.group(2))) |
117 return results | 113 return results |
118 | 114 |
119 @staticmethod | 115 @staticmethod |
120 def RunAndFilterOutput(args, **kwargs): | |
121 """Wrapper to gclient_utils.SubprocessCallAndFilter().""" | |
122 return gclient_utils.SubprocessCallAndFilter([GIT.COMMAND] + args, **kwargs) | |
123 | |
124 @staticmethod | |
125 def GetEmail(repo_root): | 116 def GetEmail(repo_root): |
126 """Retrieves the user email address if known.""" | 117 """Retrieves the user email address if known.""" |
127 # We could want to look at the svn cred when it has a svn remote but it | 118 # We could want to look at the svn cred when it has a svn remote but it |
128 # should be fine for now, users should simply configure their git settings. | 119 # should be fine for now, users should simply configure their git settings. |
129 return GIT.Capture(['config', 'user.email'], | 120 return GIT.Capture(['config', 'user.email'], |
130 repo_root, error_ok=True)[0].strip() | 121 repo_root, error_ok=True)[0].strip() |
131 | 122 |
132 @staticmethod | 123 @staticmethod |
133 def ShortBranchName(branch): | 124 def ShortBranchName(branch): |
134 """Converts a name like 'refs/heads/foo' to just 'foo'.""" | 125 """Converts a name like 'refs/heads/foo' to just 'foo'.""" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 for min_ver in map(int, min_version.split('.')): | 296 for min_ver in map(int, min_version.split('.')): |
306 ver = current_version_list.pop(0) | 297 ver = current_version_list.pop(0) |
307 if ver < min_ver: | 298 if ver < min_ver: |
308 return (False, current_version) | 299 return (False, current_version) |
309 elif ver > min_ver: | 300 elif ver > min_ver: |
310 return (True, current_version) | 301 return (True, current_version) |
311 return (True, current_version) | 302 return (True, current_version) |
312 | 303 |
313 | 304 |
314 class SVN(object): | 305 class SVN(object): |
315 COMMAND = "svn" | |
316 current_version = None | 306 current_version = None |
317 | 307 |
318 @staticmethod | 308 @staticmethod |
319 def Run(args, **kwargs): | 309 def Run(args, **kwargs): |
320 """Wrappers to gclient_utils.SubprocessCall().""" | 310 """Wrappers to gclient_utils.CheckCallAndFilterAndHeader().""" |
321 return gclient_utils.SubprocessCall([SVN.COMMAND] + args, **kwargs) | 311 return gclient_utils.CheckCallAndFilterAndHeader(['svn'] + args, |
| 312 always=True, **kwargs) |
322 | 313 |
323 @staticmethod | 314 @staticmethod |
324 def Capture(args, in_directory=None, print_error=True): | 315 def Capture(args, in_directory=None, print_error=True): |
325 """Runs svn, capturing output sent to stdout as a string. | 316 """Runs svn, capturing output sent to stdout as a string. |
326 | 317 |
327 Args: | 318 Args: |
328 args: A sequence of command line parameters to be passed to svn. | 319 args: A sequence of command line parameters to be passed to svn. |
329 in_directory: The directory where svn is to be run. | 320 in_directory: The directory where svn is to be run. |
330 | 321 |
331 Returns: | 322 Returns: |
332 The output sent to stdout as a string. | 323 The output sent to stdout as a string. |
333 """ | 324 """ |
334 c = [SVN.COMMAND] | |
335 c.extend(args) | |
336 stderr = None | 325 stderr = None |
337 if not print_error: | 326 if not print_error: |
338 stderr = subprocess.PIPE | 327 stderr = subprocess.PIPE |
339 return gclient_utils.Popen(c, cwd=in_directory, stdout=subprocess.PIPE, | 328 return gclient_utils.Popen(['svn'] + args, cwd=in_directory, |
340 stderr=stderr).communicate()[0] | 329 stdout=subprocess.PIPE, stderr=stderr).communicate()[0] |
341 | 330 |
342 @staticmethod | 331 @staticmethod |
343 def RunAndGetFileList(verbose, args, cwd, file_list, stdout=None): | 332 def RunAndGetFileList(verbose, args, cwd, file_list, stdout=None): |
344 """Runs svn checkout, update, or status, output to stdout. | 333 """Runs svn checkout, update, or status, output to stdout. |
345 | 334 |
346 The first item in args must be either "checkout", "update", or "status". | 335 The first item in args must be either "checkout", "update", or "status". |
347 | 336 |
348 svn's stdout is parsed to collect a list of files checked out or updated. | 337 svn's stdout is parsed to collect a list of files checked out or updated. |
349 These files are appended to file_list. svn's stdout is also printed to | 338 These files are appended to file_list. svn's stdout is also printed to |
350 sys.stdout as in Run. | 339 sys.stdout as in Run. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 failure = [] | 375 failure = [] |
387 | 376 |
388 def CaptureMatchingLines(line): | 377 def CaptureMatchingLines(line): |
389 match = compiled_pattern.search(line) | 378 match = compiled_pattern.search(line) |
390 if match: | 379 if match: |
391 file_list.append(match.group(1)) | 380 file_list.append(match.group(1)) |
392 if line.startswith('svn: '): | 381 if line.startswith('svn: '): |
393 failure.append(line) | 382 failure.append(line) |
394 | 383 |
395 try: | 384 try: |
396 SVN.RunAndFilterOutput(args, cwd=cwd, print_messages=verbose, | 385 gclient_utils.CheckCallAndFilterAndHeader( |
397 print_stdout=True, | 386 ['svn'] + args, |
398 filter_fn=CaptureMatchingLines, | 387 cwd=cwd, |
399 stdout=stdout) | 388 always=verbose, |
| 389 filter_fn=CaptureMatchingLines, |
| 390 stdout=stdout) |
400 except gclient_utils.Error: | 391 except gclient_utils.Error: |
401 def IsKnownFailure(): | 392 def IsKnownFailure(): |
402 for x in failure: | 393 for x in failure: |
403 if (x.startswith('svn: OPTIONS of') or | 394 if (x.startswith('svn: OPTIONS of') or |
404 x.startswith('svn: PROPFIND of') or | 395 x.startswith('svn: PROPFIND of') or |
405 x.startswith('svn: REPORT of') or | 396 x.startswith('svn: REPORT of') or |
406 x.startswith('svn: Unknown hostname') or | 397 x.startswith('svn: Unknown hostname') or |
407 x.startswith('svn: Server sent unexpected return value')): | 398 x.startswith('svn: Server sent unexpected return value')): |
408 return True | 399 return True |
409 return False | 400 return False |
(...skipping 21 matching lines...) Expand all Loading... |
431 # We enforce that some progress has been made or a known failure. | 422 # We enforce that some progress has been made or a known failure. |
432 if len(file_list) == previous_list_len and not IsKnownFailure(): | 423 if len(file_list) == previous_list_len and not IsKnownFailure(): |
433 # No known svn error was found and no progress, bail out. | 424 # No known svn error was found and no progress, bail out. |
434 raise | 425 raise |
435 print "Sleeping 15 seconds and retrying...." | 426 print "Sleeping 15 seconds and retrying...." |
436 time.sleep(15) | 427 time.sleep(15) |
437 continue | 428 continue |
438 break | 429 break |
439 | 430 |
440 @staticmethod | 431 @staticmethod |
441 def RunAndFilterOutput(args, **kwargs): | |
442 """Wrapper for gclient_utils.SubprocessCallAndFilter().""" | |
443 return gclient_utils.SubprocessCallAndFilter([SVN.COMMAND] + args, **kwargs) | |
444 | |
445 @staticmethod | |
446 def CaptureInfo(relpath, in_directory=None, print_error=True): | 432 def CaptureInfo(relpath, in_directory=None, print_error=True): |
447 """Returns a dictionary from the svn info output for the given file. | 433 """Returns a dictionary from the svn info output for the given file. |
448 | 434 |
449 Args: | 435 Args: |
450 relpath: The directory where the working copy resides relative to | 436 relpath: The directory where the working copy resides relative to |
451 the directory given by in_directory. | 437 the directory given by in_directory. |
452 in_directory: The directory where svn is to be run. | 438 in_directory: The directory where svn is to be run. |
453 """ | 439 """ |
454 output = SVN.Capture(["info", "--xml", relpath], in_directory, print_error) | 440 output = SVN.Capture(["info", "--xml", relpath], in_directory, print_error) |
455 dom = gclient_utils.ParseXML(output) | 441 dom = gclient_utils.ParseXML(output) |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 if not SVN.current_version: | 848 if not SVN.current_version: |
863 SVN.current_version = SVN.Capture(['--version']).split()[2] | 849 SVN.current_version = SVN.Capture(['--version']).split()[2] |
864 current_version_list = map(only_int, SVN.current_version.split('.')) | 850 current_version_list = map(only_int, SVN.current_version.split('.')) |
865 for min_ver in map(int, min_version.split('.')): | 851 for min_ver in map(int, min_version.split('.')): |
866 ver = current_version_list.pop(0) | 852 ver = current_version_list.pop(0) |
867 if ver < min_ver: | 853 if ver < min_ver: |
868 return (False, SVN.current_version) | 854 return (False, SVN.current_version) |
869 elif ver > min_ver: | 855 elif ver > min_ver: |
870 return (True, SVN.current_version) | 856 return (True, SVN.current_version) |
871 return (True, SVN.current_version) | 857 return (True, SVN.current_version) |
OLD | NEW |