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

Side by Side Diff: scm.py

Issue 7851001: Remove gclient_utils.CheckCall() usage from scm.py (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 3 months 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2010 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 logging 9 import logging
10 import os 10 import os
11 import re 11 import re
12 import shutil
13 import subprocess
14 import sys 12 import sys
15 import tempfile 13 import tempfile
16 import time 14 import time
17 from xml.etree import ElementTree 15 from xml.etree import ElementTree
18 16
19 import gclient_utils 17 import gclient_utils
20 import subprocess2 18 import subprocess2
21 19
22 20
23 def ValidateEmail(email): 21 def ValidateEmail(email):
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 stdout=subprocess2.VOID, 81 stdout=subprocess2.VOID,
84 cwd=root) 82 cwd=root)
85 return 'git' 83 return 'git'
86 except (OSError, subprocess2.CalledProcessError): 84 except (OSError, subprocess2.CalledProcessError):
87 return None 85 return None
88 86
89 87
90 class GIT(object): 88 class GIT(object):
91 @staticmethod 89 @staticmethod
92 def Capture(args, **kwargs): 90 def Capture(args, **kwargs):
93 return gclient_utils.CheckCall(['git'] + args, print_error=False, 91 return subprocess2.check_output(
94 **kwargs)[0] 92 ['git'] + args, stderr=subprocess2.VOID, **kwargs)
95 93
96 @staticmethod 94 @staticmethod
97 def CaptureStatus(files, upstream_branch=None): 95 def CaptureStatus(files, upstream_branch=None):
98 """Returns git status. 96 """Returns git status.
99 97
100 @files can be a string (one file) or a list of files. 98 @files can be a string (one file) or a list of files.
101 99
102 Returns an array of (status, file) tuples.""" 100 Returns an array of (status, file) tuples."""
103 if upstream_branch is None: 101 if upstream_branch is None:
104 upstream_branch = GIT.GetUpstreamBranch(os.getcwd()) 102 upstream_branch = GIT.GetUpstreamBranch(os.getcwd())
(...skipping 21 matching lines...) Expand all
126 results.append(('%s ' % m.group(1)[0], m.group(2))) 124 results.append(('%s ' % m.group(1)[0], m.group(2)))
127 return results 125 return results
128 126
129 @staticmethod 127 @staticmethod
130 def GetEmail(cwd): 128 def GetEmail(cwd):
131 """Retrieves the user email address if known.""" 129 """Retrieves the user email address if known."""
132 # We could want to look at the svn cred when it has a svn remote but it 130 # We could want to look at the svn cred when it has a svn remote but it
133 # should be fine for now, users should simply configure their git settings. 131 # should be fine for now, users should simply configure their git settings.
134 try: 132 try:
135 return GIT.Capture(['config', 'user.email'], cwd=cwd).strip() 133 return GIT.Capture(['config', 'user.email'], cwd=cwd).strip()
136 except gclient_utils.CheckCallError: 134 except subprocess2.CalledProcessError:
137 return '' 135 return ''
138 136
139 @staticmethod 137 @staticmethod
140 def ShortBranchName(branch): 138 def ShortBranchName(branch):
141 """Converts a name like 'refs/heads/foo' to just 'foo'.""" 139 """Converts a name like 'refs/heads/foo' to just 'foo'."""
142 return branch.replace('refs/heads/', '') 140 return branch.replace('refs/heads/', '')
143 141
144 @staticmethod 142 @staticmethod
145 def GetBranchRef(cwd): 143 def GetBranchRef(cwd):
146 """Returns the full branch reference, e.g. 'refs/heads/master'.""" 144 """Returns the full branch reference, e.g. 'refs/heads/master'."""
147 return GIT.Capture(['symbolic-ref', 'HEAD'], cwd=cwd).strip() 145 return GIT.Capture(['symbolic-ref', 'HEAD'], cwd=cwd).strip()
148 146
149 @staticmethod 147 @staticmethod
150 def GetBranch(cwd): 148 def GetBranch(cwd):
151 """Returns the short branch name, e.g. 'master'.""" 149 """Returns the short branch name, e.g. 'master'."""
152 return GIT.ShortBranchName(GIT.GetBranchRef(cwd)) 150 return GIT.ShortBranchName(GIT.GetBranchRef(cwd))
153 151
154 @staticmethod 152 @staticmethod
155 def IsGitSvn(cwd): 153 def IsGitSvn(cwd):
156 """Returns true if this repo looks like it's using git-svn.""" 154 """Returns true if this repo looks like it's using git-svn."""
157 # If you have any "svn-remote.*" config keys, we think you're using svn. 155 # If you have any "svn-remote.*" config keys, we think you're using svn.
158 try: 156 try:
159 GIT.Capture(['config', '--get-regexp', r'^svn-remote\.'], cwd=cwd) 157 GIT.Capture(['config', '--get-regexp', r'^svn-remote\.'], cwd=cwd)
160 return True 158 return True
161 except gclient_utils.CheckCallError: 159 except subprocess2.CalledProcessError:
162 return False 160 return False
163 161
164 @staticmethod 162 @staticmethod
165 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards): 163 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
166 """Return the corresponding git ref if |base_url| together with |glob_spec| 164 """Return the corresponding git ref if |base_url| together with |glob_spec|
167 matches the full |url|. 165 matches the full |url|.
168 166
169 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below). 167 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below).
170 """ 168 """
171 fetch_suburl, as_ref = glob_spec.split(':') 169 fetch_suburl, as_ref = glob_spec.split(':')
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 # 1) iterate through our branch history and find the svn URL. 209 # 1) iterate through our branch history and find the svn URL.
212 # 2) find the svn-remote that fetches from the URL. 210 # 2) find the svn-remote that fetches from the URL.
213 211
214 # regexp matching the git-svn line that contains the URL. 212 # regexp matching the git-svn line that contains the URL.
215 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE) 213 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE)
216 214
217 # We don't want to go through all of history, so read a line from the 215 # We don't want to go through all of history, so read a line from the
218 # pipe at a time. 216 # pipe at a time.
219 # The -100 is an arbitrary limit so we don't search forever. 217 # The -100 is an arbitrary limit so we don't search forever.
220 cmd = ['git', 'log', '-100', '--pretty=medium'] 218 cmd = ['git', 'log', '-100', '--pretty=medium']
221 proc = gclient_utils.Popen(cmd, stdout=subprocess.PIPE) 219 proc = subprocess2.Popen(cmd, stdout=subprocess2.PIPE)
222 url = None 220 url = None
223 for line in proc.stdout: 221 for line in proc.stdout:
224 match = git_svn_re.match(line) 222 match = git_svn_re.match(line)
225 if match: 223 if match:
226 url = match.group(1) 224 url = match.group(1)
227 proc.stdout.close() # Cut pipe. 225 proc.stdout.close() # Cut pipe.
228 break 226 break
229 227
230 if url: 228 if url:
231 svn_remote_re = re.compile(r'^svn-remote\.([^.]+)\.url (.*)$') 229 svn_remote_re = re.compile(r'^svn-remote\.([^.]+)\.url (.*)$')
232 remotes = GIT.Capture(['config', '--get-regexp', 230 remotes = GIT.Capture(['config', '--get-regexp',
233 r'^svn-remote\..*\.url'], cwd=cwd).splitlines() 231 r'^svn-remote\..*\.url'], cwd=cwd).splitlines()
234 for remote in remotes: 232 for remote in remotes:
235 match = svn_remote_re.match(remote) 233 match = svn_remote_re.match(remote)
236 if match: 234 if match:
237 remote = match.group(1) 235 remote = match.group(1)
238 base_url = match.group(2) 236 base_url = match.group(2)
239 try: 237 try:
240 fetch_spec = GIT.Capture( 238 fetch_spec = GIT.Capture(
241 ['config', 'svn-remote.%s.fetch' % remote], 239 ['config', 'svn-remote.%s.fetch' % remote],
242 cwd=cwd).strip() 240 cwd=cwd).strip()
243 branch = GIT.MatchSvnGlob(url, base_url, fetch_spec, False) 241 branch = GIT.MatchSvnGlob(url, base_url, fetch_spec, False)
244 except gclient_utils.CheckCallError: 242 except subprocess2.CalledProcessError:
245 branch = None 243 branch = None
246 if branch: 244 if branch:
247 return branch 245 return branch
248 try: 246 try:
249 branch_spec = GIT.Capture( 247 branch_spec = GIT.Capture(
250 ['config', 'svn-remote.%s.branches' % remote], 248 ['config', 'svn-remote.%s.branches' % remote],
251 cwd=cwd).strip() 249 cwd=cwd).strip()
252 branch = GIT.MatchSvnGlob(url, base_url, branch_spec, True) 250 branch = GIT.MatchSvnGlob(url, base_url, branch_spec, True)
253 except gclient_utils.CheckCallError: 251 except subprocess2.CalledProcessError:
254 branch = None 252 branch = None
255 if branch: 253 if branch:
256 return branch 254 return branch
257 try: 255 try:
258 tag_spec = GIT.Capture( 256 tag_spec = GIT.Capture(
259 ['config', 'svn-remote.%s.tags' % remote], 257 ['config', 'svn-remote.%s.tags' % remote],
260 cwd=cwd).strip() 258 cwd=cwd).strip()
261 branch = GIT.MatchSvnGlob(url, base_url, tag_spec, True) 259 branch = GIT.MatchSvnGlob(url, base_url, tag_spec, True)
262 except gclient_utils.CheckCallError: 260 except subprocess2.CalledProcessError:
263 branch = None 261 branch = None
264 if branch: 262 if branch:
265 return branch 263 return branch
266 264
267 @staticmethod 265 @staticmethod
268 def FetchUpstreamTuple(cwd): 266 def FetchUpstreamTuple(cwd):
269 """Returns a tuple containg remote and remote ref, 267 """Returns a tuple containg remote and remote ref,
270 e.g. 'origin', 'refs/heads/master' 268 e.g. 'origin', 'refs/heads/master'
271 Tries to be intelligent and understand git-svn. 269 Tries to be intelligent and understand git-svn.
272 """ 270 """
273 remote = '.' 271 remote = '.'
274 branch = GIT.GetBranch(cwd) 272 branch = GIT.GetBranch(cwd)
275 try: 273 try:
276 upstream_branch = GIT.Capture( 274 upstream_branch = GIT.Capture(
277 ['config', 'branch.%s.merge' % branch], cwd=cwd).strip() 275 ['config', 'branch.%s.merge' % branch], cwd=cwd).strip()
278 except (gclient_utils.Error, subprocess2.CalledProcessError): 276 except subprocess2.CalledProcessError:
279 upstream_branch = None 277 upstream_branch = None
280 if upstream_branch: 278 if upstream_branch:
281 try: 279 try:
282 remote = GIT.Capture( 280 remote = GIT.Capture(
283 ['config', 'branch.%s.remote' % branch], cwd=cwd).strip() 281 ['config', 'branch.%s.remote' % branch], cwd=cwd).strip()
284 except (gclient_utils.Error, subprocess2.CalledProcessError): 282 except subprocess2.CalledProcessError:
285 pass 283 pass
286 else: 284 else:
287 try: 285 try:
288 upstream_branch = GIT.Capture( 286 upstream_branch = GIT.Capture(
289 ['config', 'rietveld.upstream-branch'], cwd=cwd).strip() 287 ['config', 'rietveld.upstream-branch'], cwd=cwd).strip()
290 except (gclient_utils.Error, subprocess2.CalledProcessError): 288 except subprocess2.CalledProcessError:
291 upstream_branch = None 289 upstream_branch = None
292 if upstream_branch: 290 if upstream_branch:
293 try: 291 try:
294 remote = GIT.Capture( 292 remote = GIT.Capture(
295 ['config', 'rietveld.upstream-remote'], cwd=cwd).strip() 293 ['config', 'rietveld.upstream-remote'], cwd=cwd).strip()
296 except (gclient_utils.Error, subprocess2.CalledProcessError): 294 except subprocess2.CalledProcessError:
297 pass 295 pass
298 else: 296 else:
299 # Fall back on trying a git-svn upstream branch. 297 # Fall back on trying a git-svn upstream branch.
300 if GIT.IsGitSvn(cwd): 298 if GIT.IsGitSvn(cwd):
301 upstream_branch = GIT.GetSVNBranch(cwd) 299 upstream_branch = GIT.GetSVNBranch(cwd)
302 else: 300 else:
303 # Else, try to guess the origin remote. 301 # Else, try to guess the origin remote.
304 remote_branches = GIT.Capture(['branch', '-r'], cwd=cwd).split() 302 remote_branches = GIT.Capture(['branch', '-r'], cwd=cwd).split()
305 if 'origin/master' in remote_branches: 303 if 'origin/master' in remote_branches:
306 # Fall back on origin/master if it exits. 304 # Fall back on origin/master if it exits.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 return (True, current_version) 388 return (True, current_version)
391 389
392 390
393 class SVN(object): 391 class SVN(object):
394 current_version = None 392 current_version = None
395 393
396 @staticmethod 394 @staticmethod
397 def Capture(args, **kwargs): 395 def Capture(args, **kwargs):
398 """Always redirect stderr. 396 """Always redirect stderr.
399 397
400 Throws an exception if non-0 is returned.""" 398 Throws an exception if non-0 is returned.
401 return gclient_utils.CheckCall(['svn'] + args, print_error=False, 399 """
402 **kwargs)[0] 400 return subprocess2.check_output(['svn'] + args, **kwargs)
403 401
404 @staticmethod 402 @staticmethod
405 def RunAndGetFileList(verbose, args, cwd, file_list, stdout=None): 403 def RunAndGetFileList(verbose, args, cwd, file_list, stdout=None):
406 """Runs svn checkout, update, or status, output to stdout. 404 """Runs svn checkout, update, or status, output to stdout.
407 405
408 The first item in args must be either "checkout", "update", or "status". 406 The first item in args must be either "checkout", "update", or "status".
409 407
410 svn's stdout is parsed to collect a list of files checked out or updated. 408 svn's stdout is parsed to collect a list of files checked out or updated.
411 These files are appended to file_list. svn's stdout is also printed to 409 These files are appended to file_list. svn's stdout is also printed to
412 sys.stdout as in Run. 410 sys.stdout as in Run.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 if line.startswith('svn: '): 455 if line.startswith('svn: '):
458 failure.append(line) 456 failure.append(line)
459 457
460 try: 458 try:
461 gclient_utils.CheckCallAndFilterAndHeader( 459 gclient_utils.CheckCallAndFilterAndHeader(
462 ['svn'] + args, 460 ['svn'] + args,
463 cwd=cwd, 461 cwd=cwd,
464 always=verbose, 462 always=verbose,
465 filter_fn=CaptureMatchingLines, 463 filter_fn=CaptureMatchingLines,
466 stdout=stdout) 464 stdout=stdout)
467 except (gclient_utils.Error, subprocess2.CalledProcessError): 465 except subprocess2.CalledProcessError:
468 def IsKnownFailure(): 466 def IsKnownFailure():
469 for x in failure: 467 for x in failure:
470 if (x.startswith('svn: OPTIONS of') or 468 if (x.startswith('svn: OPTIONS of') or
471 x.startswith('svn: PROPFIND of') or 469 x.startswith('svn: PROPFIND of') or
472 x.startswith('svn: REPORT of') or 470 x.startswith('svn: REPORT of') or
473 x.startswith('svn: Unknown hostname') or 471 x.startswith('svn: Unknown hostname') or
474 x.startswith('svn: Server sent unexpected return value')): 472 x.startswith('svn: Server sent unexpected return value')):
475 return True 473 return True
476 return False 474 return False
477 475
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 filename: The file to check 656 filename: The file to check
659 property_name: The name of the SVN property, e.g. "svn:mime-type" 657 property_name: The name of the SVN property, e.g. "svn:mime-type"
660 658
661 Returns: 659 Returns:
662 The value of the property, which will be the empty string if the property 660 The value of the property, which will be the empty string if the property
663 is not set on the file. If the file is not under version control, the 661 is not set on the file. If the file is not under version control, the
664 empty string is also returned. 662 empty string is also returned.
665 """ 663 """
666 try: 664 try:
667 return SVN.Capture(['propget', property_name, filename]) 665 return SVN.Capture(['propget', property_name, filename])
668 except (gclient_utils.Error, subprocess2.CalledProcessError): 666 except subprocess2.CalledProcessError:
669 return '' 667 return ''
670 668
671 @staticmethod 669 @staticmethod
672 def DiffItem(filename, full_move=False, revision=None): 670 def DiffItem(filename, full_move=False, revision=None):
673 """Diffs a single file. 671 """Diffs a single file.
674 672
675 Should be simple, eh? No it isn't. 673 Should be simple, eh? No it isn't.
676 Be sure to be in the appropriate directory before calling to have the 674 Be sure to be in the appropriate directory before calling to have the
677 expected relative path. 675 expected relative path.
678 full_move means that move or copy operations should completely recreate the 676 full_move means that move or copy operations should completely recreate the
679 files, usually in the prospect to apply the patch for a try job.""" 677 files, usually in the prospect to apply the patch for a try job."""
680 # If the user specified a custom diff command in their svn config file, 678 # If the user specified a custom diff command in their svn config file,
681 # then it'll be used when we do svn diff, which we don't want to happen 679 # then it'll be used when we do svn diff, which we don't want to happen
682 # since we want the unified diff. Using --diff-cmd=diff doesn't always 680 # since we want the unified diff. Using --diff-cmd=diff doesn't always
683 # work, since they can have another diff executable in their path that 681 # work, since they can have another diff executable in their path that
684 # gives different line endings. So we use a bogus temp directory as the 682 # gives different line endings. So we use a bogus temp directory as the
685 # config directory, which gets around these problems. 683 # config directory, which gets around these problems.
686 bogus_dir = tempfile.mkdtemp() 684 bogus_dir = tempfile.mkdtemp()
687 try: 685 try:
688 # Use "svn info" output instead of os.path.isdir because the latter fails 686 # Use "svn info" output instead of os.path.isdir because the latter fails
689 # when the file is deleted. 687 # when the file is deleted.
690 return SVN._DiffItemInternal(filename, SVN.CaptureInfo(filename), 688 return SVN._DiffItemInternal(filename, SVN.CaptureInfo(filename),
691 bogus_dir, 689 bogus_dir,
692 full_move=full_move, revision=revision) 690 full_move=full_move, revision=revision)
693 finally: 691 finally:
694 shutil.rmtree(bogus_dir) 692 gclient_utils.RemoveDirectory(bogus_dir)
695 693
696 @staticmethod 694 @staticmethod
697 def _DiffItemInternal(filename, info, bogus_dir, full_move=False, 695 def _DiffItemInternal(filename, info, bogus_dir, full_move=False,
698 revision=None): 696 revision=None):
699 """Grabs the diff data.""" 697 """Grabs the diff data."""
700 command = ["diff", "--config-dir", bogus_dir, filename] 698 command = ["diff", "--config-dir", bogus_dir, filename]
701 if revision: 699 if revision:
702 command.extend(['--revision', revision]) 700 command.extend(['--revision', revision])
703 data = None 701 data = None
704 if SVN.IsMovedInfo(info): 702 if SVN.IsMovedInfo(info):
(...skipping 29 matching lines...) Expand all
734 data = SVN.Capture(command) 732 data = SVN.Capture(command)
735 if not data: 733 if not data:
736 # We put in an empty Index entry so upload.py knows about them. 734 # We put in an empty Index entry so upload.py knows about them.
737 data = "Index: %s\n" % filename.replace(os.sep, '/') 735 data = "Index: %s\n" % filename.replace(os.sep, '/')
738 # Otherwise silently ignore directories. 736 # Otherwise silently ignore directories.
739 else: 737 else:
740 if info.get("Node Kind") != "directory": 738 if info.get("Node Kind") != "directory":
741 # Normal simple case. 739 # Normal simple case.
742 try: 740 try:
743 data = SVN.Capture(command) 741 data = SVN.Capture(command)
744 except gclient_utils.CheckCallError: 742 except subprocess2.CalledProcessError:
745 if revision: 743 if revision:
746 data = GenFakeDiff(filename) 744 data = GenFakeDiff(filename)
747 else: 745 else:
748 raise 746 raise
749 # Otherwise silently ignore directories. 747 # Otherwise silently ignore directories.
750 return data 748 return data
751 749
752 @staticmethod 750 @staticmethod
753 def GenerateDiff(filenames, root=None, full_move=False, revision=None): 751 def GenerateDiff(filenames, root=None, full_move=False, revision=None):
754 """Returns a string containing the diff for the given file list. 752 """Returns a string containing the diff for the given file list.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 if SVN.IsMovedInfo(info): 796 if SVN.IsMovedInfo(info):
799 # for now, the most common case is a head copy, 797 # for now, the most common case is a head copy,
800 # so let's just encode that as a straight up cp. 798 # so let's just encode that as a straight up cp.
801 srcurl = info.get('Copied From URL') 799 srcurl = info.get('Copied From URL')
802 root = info.get('Repository Root') 800 root = info.get('Repository Root')
803 rev = int(info.get('Copied From Rev')) 801 rev = int(info.get('Copied From Rev'))
804 assert srcurl.startswith(root) 802 assert srcurl.startswith(root)
805 src = srcurl[len(root)+1:] 803 src = srcurl[len(root)+1:]
806 try: 804 try:
807 srcinfo = SVN.CaptureInfo(srcurl) 805 srcinfo = SVN.CaptureInfo(srcurl)
808 except gclient_utils.CheckCallError, e: 806 except subprocess2.CalledProcessError, e:
809 if not 'Not a valid URL' in e.stderr: 807 if not 'Not a valid URL' in e.stderr:
810 raise 808 raise
811 # Assume the file was deleted. No idea how to figure out at which 809 # Assume the file was deleted. No idea how to figure out at which
812 # revision the file was deleted. 810 # revision the file was deleted.
813 srcinfo = {'Revision': rev} 811 srcinfo = {'Revision': rev}
814 if (srcinfo.get('Revision') != rev and 812 if (srcinfo.get('Revision') != rev and
815 SVN.Capture(['diff', '-r', '%d:head' % rev, srcurl])): 813 SVN.Capture(['diff', '-r', '%d:head' % rev, srcurl])):
816 metaheaders.append("#$ svn cp -r %d %s %s " 814 metaheaders.append("#$ svn cp -r %d %s %s "
817 "### WARNING: note non-trunk copy\n" % 815 "### WARNING: note non-trunk copy\n" %
818 (rev, src, filename)) 816 (rev, src, filename))
(...skipping 13 matching lines...) Expand all
832 # Use StringIO since it can be messy when diffing a directory move with 830 # Use StringIO since it can be messy when diffing a directory move with
833 # full_move=True. 831 # full_move=True.
834 buf = cStringIO.StringIO() 832 buf = cStringIO.StringIO()
835 for d in filter(None, diffs): 833 for d in filter(None, diffs):
836 buf.write(d) 834 buf.write(d)
837 result = buf.getvalue() 835 result = buf.getvalue()
838 buf.close() 836 buf.close()
839 return result 837 return result
840 finally: 838 finally:
841 os.chdir(previous_cwd) 839 os.chdir(previous_cwd)
842 shutil.rmtree(bogus_dir) 840 gclient_utils.RemoveDirectory(bogus_dir)
843 841
844 @staticmethod 842 @staticmethod
845 def GetEmail(repo_root): 843 def GetEmail(repo_root):
846 """Retrieves the svn account which we assume is an email address.""" 844 """Retrieves the svn account which we assume is an email address."""
847 try: 845 try:
848 infos = SVN.CaptureInfo(repo_root) 846 infos = SVN.CaptureInfo(repo_root)
849 except (gclient_utils.Error, subprocess2.CalledProcessError): 847 except subprocess2.CalledProcessError:
850 return None 848 return None
851 849
852 # Should check for uuid but it is incorrectly saved for https creds. 850 # Should check for uuid but it is incorrectly saved for https creds.
853 root = infos['Repository Root'] 851 root = infos['Repository Root']
854 realm = root.rsplit('/', 1)[0] 852 realm = root.rsplit('/', 1)[0]
855 uuid = infos['UUID'] 853 uuid = infos['UUID']
856 if root.startswith('https') or not uuid: 854 if root.startswith('https') or not uuid:
857 regexp = re.compile(r'<%s:\d+>.*' % realm) 855 regexp = re.compile(r'<%s:\d+>.*' % realm)
858 else: 856 else:
859 regexp = re.compile(r'<%s:\d+> %s' % (realm, uuid)) 857 regexp = re.compile(r'<%s:\d+> %s' % (realm, uuid))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 def GetCheckoutRoot(directory): 899 def GetCheckoutRoot(directory):
902 """Returns the top level directory of the current repository. 900 """Returns the top level directory of the current repository.
903 901
904 The directory is returned as an absolute path. 902 The directory is returned as an absolute path.
905 """ 903 """
906 directory = os.path.abspath(directory) 904 directory = os.path.abspath(directory)
907 try: 905 try:
908 info = SVN.CaptureInfo(directory) 906 info = SVN.CaptureInfo(directory)
909 cur_dir_repo_root = info['Repository Root'] 907 cur_dir_repo_root = info['Repository Root']
910 url = info['URL'] 908 url = info['URL']
911 except (gclient_utils.Error, subprocess2.CalledProcessError): 909 except subprocess2.CalledProcessError:
912 return None 910 return None
913 while True: 911 while True:
914 parent = os.path.dirname(directory) 912 parent = os.path.dirname(directory)
915 try: 913 try:
916 info = SVN.CaptureInfo(parent) 914 info = SVN.CaptureInfo(parent)
917 if (info['Repository Root'] != cur_dir_repo_root or 915 if (info['Repository Root'] != cur_dir_repo_root or
918 info['URL'] != os.path.dirname(url)): 916 info['URL'] != os.path.dirname(url)):
919 break 917 break
920 url = info['URL'] 918 url = info['URL']
921 except (gclient_utils.Error, subprocess2.CalledProcessError): 919 except subprocess2.CalledProcessError:
922 break 920 break
923 directory = parent 921 directory = parent
924 return GetCasedPath(directory) 922 return GetCasedPath(directory)
925 923
926 @staticmethod 924 @staticmethod
927 def AssertVersion(min_version): 925 def AssertVersion(min_version):
928 """Asserts svn's version is at least min_version.""" 926 """Asserts svn's version is at least min_version."""
929 def only_int(val): 927 def only_int(val):
930 if val.isdigit(): 928 if val.isdigit():
931 return int(val) 929 return int(val)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 if os.path.exists(file_path): 964 if os.path.exists(file_path):
967 # svn revert is really stupid. It fails on inconsistent line-endings, 965 # svn revert is really stupid. It fails on inconsistent line-endings,
968 # on switched directories, etc. So take no chance and delete everything! 966 # on switched directories, etc. So take no chance and delete everything!
969 # In theory, it wouldn't be necessary for property-only change but then 967 # In theory, it wouldn't be necessary for property-only change but then
970 # it'd have to look for switched directories, etc so it's not worth 968 # it'd have to look for switched directories, etc so it's not worth
971 # optimizing this use case. 969 # optimizing this use case.
972 if os.path.isfile(file_path) or os.path.islink(file_path): 970 if os.path.isfile(file_path) or os.path.islink(file_path):
973 logging.info('os.remove(%s)' % file_path) 971 logging.info('os.remove(%s)' % file_path)
974 os.remove(file_path) 972 os.remove(file_path)
975 elif os.path.isdir(file_path): 973 elif os.path.isdir(file_path):
976 logging.info('gclient_utils.RemoveDirectory(%s)' % file_path) 974 logging.info('RemoveDirectory(%s)' % file_path)
977 gclient_utils.RemoveDirectory(file_path) 975 gclient_utils.RemoveDirectory(file_path)
978 else: 976 else:
979 logging.critical( 977 logging.critical(
980 ('No idea what is %s.\nYou just found a bug in gclient' 978 ('No idea what is %s.\nYou just found a bug in gclient'
981 ', please ping maruel@chromium.org ASAP!') % file_path) 979 ', please ping maruel@chromium.org ASAP!') % file_path)
982 980
983 if (file_status[0][0] in ('D', 'A', '!') or 981 if (file_status[0][0] in ('D', 'A', '!') or
984 not file_status[0][1:].isspace()): 982 not file_status[0][1:].isspace()):
985 # Added, deleted file requires manual intervention and require calling 983 # Added, deleted file requires manual intervention and require calling
986 # revert, like for properties. 984 # revert, like for properties.
987 try: 985 try:
988 SVN.Capture(['revert', file_status[1]], cwd=repo_root) 986 SVN.Capture(['revert', file_status[1]], cwd=repo_root)
989 except gclient_utils.CheckCallError: 987 except subprocess2.CalledProcessError:
990 if not os.path.exists(file_path): 988 if not os.path.exists(file_path):
991 continue 989 continue
992 raise 990 raise
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698