| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 | 6 |
| 7 import os | 7 import os |
| 8 import re | 8 import re |
| 9 import subprocess | 9 import subprocess |
| 10 import sys | 10 import sys |
| 11 import threading | 11 import threading |
| 12 | 12 |
| 13 | 13 |
| 14 # Show more information about the commands being executed. | 14 # Show more information about the commands being executed. |
| 15 VERBOSE = False | 15 VERBOSE = False |
| 16 | 16 |
| 17 # The longest any single subprocess will be allowed to run. | 17 # The longest any single subprocess will be allowed to run. |
| 18 TIMEOUT = 20 * 60 | 18 TIMEOUT = 20 * 60 |
| 19 | 19 |
| 20 | 20 |
| 21 def GetStatusOutput(cmd, cwd=None): | 21 def GetStatusOutput(cmd, cwd=None, interactive=False): |
| 22 """Return (status, output) of executing cmd in a shell.""" | 22 """Return (status, output) of executing cmd in a shell.""" |
| 23 if VERBOSE: | 23 if VERBOSE: |
| 24 print '' | 24 print '' |
| 25 print '[DEBUG] Running "%s"' % cmd | 25 print '[DEBUG] Running "%s"' % cmd |
| 26 | 26 |
| 27 def _thread_main(): | 27 def _thread_main(): |
| 28 thr = threading.current_thread() | 28 thr = threading.current_thread() |
| 29 thr.status = -1 | 29 thr.status = -1 |
| 30 thr.stdout = '' | 30 thr.stdout = '' |
| 31 thr.stderr = '<timeout>' | 31 thr.stderr = '<timeout>' |
| 32 try: | 32 try: |
| 33 proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, cwd=cwd, | 33 if interactive: |
| 34 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 34 proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, |
| 35 (stdout, _) = proc.communicate() | 35 cwd=cwd, stdout=sys.stdout, |
| 36 stderr=subprocess.STDOUT) |
| 37 stdout = '' |
| 38 proc.wait() |
| 39 else: |
| 40 proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, |
| 41 cwd=cwd, stdout=subprocess.PIPE, |
| 42 stderr=subprocess.STDOUT) |
| 43 (stdout, _) = proc.communicate() |
| 36 except Exception, e: | 44 except Exception, e: |
| 37 thr.status = -1 | 45 thr.status = -1 |
| 38 thr.stdout = '' | 46 thr.stdout = '' |
| 39 thr.stderr = repr(e) | 47 thr.stderr = repr(e) |
| 40 else: | 48 else: |
| 41 thr.status = proc.returncode | 49 thr.status = proc.returncode |
| 42 thr.stdout = stdout | 50 thr.stdout = stdout |
| 43 thr.stderr = '' | 51 thr.stderr = '' |
| 44 | 52 |
| 45 thr = threading.Thread(target=_thread_main) | 53 thr = threading.Thread(target=_thread_main) |
| 46 thr.daemon = True | 54 thr.daemon = True |
| 47 thr.start() | 55 thr.start() |
| 48 thr.join(TIMEOUT) | 56 thr.join(TIMEOUT) |
| 49 | 57 |
| 50 # pylint: disable=E1101 | 58 # pylint: disable=E1101 |
| 51 if VERBOSE: | 59 if VERBOSE: |
| 52 short_output = ' '.join(thr.stdout.splitlines()) | 60 short_output = ' '.join(thr.stdout.splitlines()) |
| 53 short_output = short_output.strip(' \t\n\r') | 61 short_output = short_output.strip(' \t\n\r') |
| 54 print '[DEBUG] Output: %d, %-60s' % (thr.status, short_output) | 62 print '[DEBUG] Output: %d, %-60s' % (thr.status, short_output) |
| 55 | 63 |
| 56 return (thr.status, thr.stdout) | 64 return (thr.status, thr.stdout) |
| 57 | 65 |
| 58 | 66 |
| 59 def Git(git_repo, command, is_mirror=False): | 67 def Git(git_repo, command, is_mirror=False, interactive=False): |
| 60 """Execute a git command within a local git repo.""" | 68 """Execute a git command within a local git repo.""" |
| 61 if is_mirror: | 69 if is_mirror: |
| 62 cmd = 'git --git-dir=%s %s' % (git_repo, command) | 70 cmd = 'git --git-dir=%s %s' % (git_repo, command) |
| 63 cwd = None | 71 cwd = None |
| 64 else: | 72 else: |
| 65 cmd = 'git %s' % command | 73 cmd = 'git %s' % command |
| 66 cwd = git_repo | 74 cwd = git_repo |
| 67 (status, output) = GetStatusOutput(cmd, cwd) | 75 (status, output) = GetStatusOutput(cmd, cwd, interactive) |
| 68 if status != 0: | 76 if status != 0: |
| 69 raise Exception('Failed to run %s. error %d. output %s' % (cmd, status, | 77 raise Exception('Failed to run %s. error %d. output %s' % (cmd, status, |
| 70 output)) | 78 output)) |
| 71 return (status, output) | 79 return (status, output) |
| 72 | 80 |
| 73 | 81 |
| 74 def Clone(git_url, git_repo, is_mirror): | 82 def Clone(git_url, git_repo, is_mirror): |
| 75 """Clone a repository.""" | 83 """Clone a repository.""" |
| 76 cmd = 'clone%s %s %s' % (' --mirror' if is_mirror else '', git_url, git_repo) | 84 cmd = 'clone' |
| 85 if is_mirror == 'bare': |
| 86 cmd += ' --bare --progress ' |
| 87 elif is_mirror: |
| 88 cmd += ' --mirror ' |
| 89 cmd += '%s %s' % (git_url, git_repo) |
| 90 |
| 77 if not is_mirror and not os.path.exists(git_repo): | 91 if not is_mirror and not os.path.exists(git_repo): |
| 78 os.makedirs(git_repo) | 92 os.makedirs(git_repo) |
| 79 return Git(git_repo, cmd, is_mirror) | 93 # Because this step can take a looooong time, we want it to be interactive |
| 94 # so that git will print out status messages as it clones so that buildbot |
| 95 # doesn't kill the process. |
| 96 return Git(git_repo, cmd, is_mirror, True) |
| 80 | 97 |
| 81 | 98 |
| 82 def Fetch(git_repo, git_url, is_mirror): | 99 def Fetch(git_repo, git_url, is_mirror): |
| 83 """Fetch the latest objects for a given git repository.""" | 100 """Fetch the latest objects for a given git repository.""" |
| 84 # Always update the upstream url | 101 # Always update the upstream url |
| 85 Git(git_repo, 'config remote.origin.url %s' % git_url) | 102 Git(git_repo, 'config remote.origin.url %s' % git_url) |
| 86 Git(git_repo, 'fetch origin', is_mirror) | 103 Git(git_repo, 'fetch origin', is_mirror) |
| 87 | 104 |
| 88 | 105 |
| 89 def Ping(git_repo, verbose=False): | 106 def Ping(git_repo, verbose=False): |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 regex = str(svn_rev) | 221 regex = str(svn_rev) |
| 205 return _SearchImpl(git_repo, svn_rev, is_mirror, refspec, fetch_url, regex) | 222 return _SearchImpl(git_repo, svn_rev, is_mirror, refspec, fetch_url, regex) |
| 206 | 223 |
| 207 | 224 |
| 208 def Search(git_repo, svn_rev, is_mirror, refspec='FETCH_HEAD', fetch_url=None): | 225 def Search(git_repo, svn_rev, is_mirror, refspec='FETCH_HEAD', fetch_url=None): |
| 209 """Return the Git commit id fuzzy matching the given SVN revision. | 226 """Return the Git commit id fuzzy matching the given SVN revision. |
| 210 | 227 |
| 211 If fetch_url is not None, will update repo if revision is newer.""" | 228 If fetch_url is not None, will update repo if revision is newer.""" |
| 212 regex = CreateLessThanOrEqualRegex(svn_rev) | 229 regex = CreateLessThanOrEqualRegex(svn_rev) |
| 213 return _SearchImpl(git_repo, svn_rev, is_mirror, refspec, fetch_url, regex) | 230 return _SearchImpl(git_repo, svn_rev, is_mirror, refspec, fetch_url, regex) |
| OLD | NEW |