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

Side by Side Diff: checkout.py

Issue 6015008: Make many operations quieter. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/commit-queue
Patch Set: Rebase against trunk Created 10 years 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 | commit_queue.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 # coding=utf8 1 # coding=utf8
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 """Manages a project checkout. 5 """Manages a project checkout.
6 6
7 Includes support for svn, git-svn and git. 7 Includes support for svn, git-svn and git.
8 """ 8 """
9 9
10 import logging 10 import logging
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 if self.commit_user: 75 if self.commit_user:
76 args = args + [ 76 args = args + [
77 '--username', self.commit_user, '--password', self.commit_pwd] 77 '--username', self.commit_user, '--password', self.commit_pwd]
78 return args 78 return args
79 79
80 def _check_call_svn(self, args, **kwargs): 80 def _check_call_svn(self, args, **kwargs):
81 """Runs svn and throws an exception if the command failed.""" 81 """Runs svn and throws an exception if the command failed."""
82 kwargs.setdefault('cwd', self.project_path) 82 kwargs.setdefault('cwd', self.project_path)
83 return subprocess2.check_call(self._add_svn_flags(args), **kwargs) 83 return subprocess2.check_call(self._add_svn_flags(args), **kwargs)
84 84
85 def _capture_svn(self, args, **kwargs): 85 def _check_capture_svn(self, args, **kwargs):
86 """Runs svn and throws an exception if the command failed. 86 """Runs svn and throws an exception if the command failed.
87 87
88 Returns the output. 88 Returns the output.
89 """ 89 """
90 kwargs.setdefault('cwd', self.project_path) 90 kwargs.setdefault('cwd', self.project_path)
91 return subprocess2.check_capture(self._add_svn_flags(args), **kwargs) 91 return subprocess2.check_capture(self._add_svn_flags(args), **kwargs)
92 92
93 @staticmethod 93 @staticmethod
94 def _parse_svn_info(output, key): 94 def _parse_svn_info(output, key):
95 """Returns value for key from svn info output. 95 """Returns value for key from svn info output.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 156
157 def commit(self, commit_message, user): 157 def commit(self, commit_message, user):
158 """Commits a patch.""" 158 """Commits a patch."""
159 logging.info('Committing patch for %s' % user) 159 logging.info('Committing patch for %s' % user)
160 assert self.commit_user 160 assert self.commit_user
161 assert self.commit_pwd 161 assert self.commit_pwd
162 handle, commit_filename = tempfile.mkstemp(text=True) 162 handle, commit_filename = tempfile.mkstemp(text=True)
163 os.write(handle, commit_message) 163 os.write(handle, commit_message)
164 os.close(handle) 164 os.close(handle)
165 try: 165 try:
166 output = self._capture_svn(['commit', '--file', commit_filename]) 166 output = self._check_capture_svn(['commit', '--file', commit_filename])
167 revision = re.compile( 167 revision = re.compile(
168 r'.*?\nCommitted revision (\d+)', 168 r'.*?\nCommitted revision (\d+)',
169 re.DOTALL).match(output).group(1) 169 re.DOTALL).match(output).group(1)
170 # Fix the committer. 170 # Fix the committer.
171 self._update_committer(revision, user) 171 self._update_committer(revision, user)
172 finally: 172 finally:
173 os.remove(commit_filename) 173 os.remove(commit_filename)
174 return int(revision) 174 return int(revision)
175 175
176 def _revert(self): 176 def _revert(self):
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 gclient_utils.RemoveDirectory(file_path) 212 gclient_utils.RemoveDirectory(file_path)
213 else: 213 else:
214 logging.error('no idea what is %s.\nYou just found a bug in gclient' 214 logging.error('no idea what is %s.\nYou just found a bug in gclient'
215 ', please ping maruel@chromium.org ASAP!' % file_path) 215 ', please ping maruel@chromium.org ASAP!' % file_path)
216 except EnvironmentError: 216 except EnvironmentError:
217 logging.error('Failed to remove %s.' % file_path) 217 logging.error('Failed to remove %s.' % file_path)
218 218
219 # Revive files that were deleted above. 219 # Revive files that were deleted above.
220 self._check_call_svn(['update', '--force'] + flags) 220 self._check_call_svn(['update', '--force'] + flags)
221 221
222 out = self._capture_svn(['info', '.']) 222 out = self._check_capture_svn(['info', '.'])
223 return int(self._parse_svn_info(out, 'revision')) 223 return int(self._parse_svn_info(out, 'revision'))
224 224
225 225
226 class GitCheckoutBase(CheckoutBase): 226 class GitCheckoutBase(CheckoutBase):
227 """Base class for git checkout. Not to be used as-is.""" 227 """Base class for git checkout. Not to be used as-is."""
228 def __init__(self, root_dir, project_name, remote_branch): 228 def __init__(self, root_dir, project_name, remote_branch):
229 super(GitCheckoutBase, self).__init__(root_dir, project_name) 229 super(GitCheckoutBase, self).__init__(root_dir, project_name)
230 # There is no reason to not hardcode it. 230 # There is no reason to not hardcode it.
231 self.remote = 'origin' 231 self.remote = 'origin'
232 self.remote_branch = remote_branch 232 self.remote_branch = remote_branch
233 self.working_branch = 'working_branch' 233 self.working_branch = 'working_branch'
234 assert self.remote_branch 234 assert self.remote_branch
235 235
236 def prepare(self): 236 def prepare(self):
237 """Resets the git repository in a clean state.""" 237 """Resets the git repository in a clean state."""
238 assert os.path.isdir(self.project_path) 238 assert os.path.isdir(self.project_path)
239 self._check_call_git(['checkout', 'master', '--force']) 239 branches, active = self._branches()
240 self._check_call_git(['pull', self.remote, self.remote_branch]) 240 if active != 'master':
241 self._call_git(['branch', '-D', self.working_branch]) 241 self._check_call_git(['checkout', 'master', '--force', '--quiet'])
242 self._check_call_git(['pull', self.remote, self.remote_branch, '--quiet'])
243 if self.working_branch in branches:
244 self._call_git(['branch', '-D', self.working_branch])
242 245
243 def apply_patch(self, patch_data): 246 def apply_patch(self, patch_data):
244 """Applies a patch on 'working_branch'.""" 247 """Applies a patch on 'working_branch'."""
245 self._check_call_git( 248 self._check_call_git(
246 ['checkout', '-b', self.working_branch, 249 ['checkout', '-b', self.working_branch,
247 '%s/%s' % (self.remote, self.remote_branch)]) 250 '%s/%s' % (self.remote, self.remote_branch)])
248 self._check_call_git(['apply', '--index', '-p0'], stdin=patch_data) 251 self._check_call_git(['apply', '--index', '-p0'], stdin=patch_data)
249 self._check_call_git(['commit', '-m', 'Committed patch']) 252 self._check_call_git(['commit', '-m', 'Committed patch'])
250 253
251 def commit(self, commit_message, user): 254 def commit(self, commit_message, user):
252 """Updates the commit message. 255 """Updates the commit message.
253 256
254 Subclass needs to dcommit or push.""" 257 Subclass needs to dcommit or push."""
255 self._check_call_git(['commit', '--amend', '-m', commit_message]) 258 self._check_call_git(['commit', '--amend', '-m', commit_message])
256 259
257 def _check_call_git(self, args, **kwargs): 260 def _check_call_git(self, args, **kwargs):
258 kwargs.setdefault('cwd', self.project_path) 261 kwargs.setdefault('cwd', self.project_path)
259 return subprocess2.check_call(['git'] + args, **kwargs) 262 return subprocess2.check_call(['git'] + args, **kwargs)
260 263
261 def _call_git(self, args, **kwargs): 264 def _call_git(self, args, **kwargs):
262 """Like check_call but doesn't throw on failure.""" 265 """Like check_call but doesn't throw on failure."""
263 kwargs.setdefault('cwd', self.project_path) 266 kwargs.setdefault('cwd', self.project_path)
264 return subprocess2.call(['git'] + args, **kwargs) 267 return subprocess2.call(['git'] + args, **kwargs)
265 268
266 def _check_capture_git(self, args, **kwargs): 269 def _check_capture_git(self, args, **kwargs):
267 kwargs.setdefault('cwd', self.project_path) 270 kwargs.setdefault('cwd', self.project_path)
268 return subprocess2.check_capture(['git'] + args, **kwargs) 271 return subprocess2.check_capture(['git'] + args, **kwargs)
269 272
273 def _branches(self):
274 """Returns the list of branches and the active one."""
275 out = self._check_capture_git(['branch']).splitlines(False)
276 branches = [l[2:] for l in out]
277 active = None
278 for l in out:
279 if l.startswith('*'):
280 active = l[2:]
281 break
282 return branches, active
283
270 284
271 class GitSvnCheckoutBase(GitCheckoutBase, SvnMixIn): 285 class GitSvnCheckoutBase(GitCheckoutBase, SvnMixIn):
272 """Base class for git-svn checkout. Not to be used as-is.""" 286 """Base class for git-svn checkout. Not to be used as-is."""
273 def __init__(self, 287 def __init__(self,
274 root_dir, project_name, remote_branch, 288 root_dir, project_name, remote_branch,
275 commit_user, commit_pwd, 289 commit_user, commit_pwd,
276 svn_url, trunk): 290 svn_url, trunk):
277 """trunk is optional.""" 291 """trunk is optional."""
278 super(GitSvnCheckoutBase, self).__init__( 292 super(GitSvnCheckoutBase, self).__init__(
279 root_dir, project_name + '.git', remote_branch) 293 root_dir, project_name + '.git', remote_branch)
280 self.commit_user = commit_user 294 self.commit_user = commit_user
281 self.commit_pwd = commit_pwd 295 self.commit_pwd = commit_pwd
282 # svn_url in this case is the root of the svn repository. 296 # svn_url in this case is the root of the svn repository.
283 self.svn_url = svn_url 297 self.svn_url = svn_url
284 self.trunk = trunk 298 self.trunk = trunk
285 assert bool(self.commit_user) == bool(self.commit_pwd) 299 assert bool(self.commit_user) == bool(self.commit_pwd)
286 assert self.svn_url 300 assert self.svn_url
287 assert self.trunk 301 assert self.trunk
288 302
289 def prepare(self): 303 def prepare(self):
290 """Resets the git repository in a clean state.""" 304 """Resets the git repository in a clean state."""
291 self._check_call_git(['checkout', 'master', '--force']) 305 branches, active = self._branches()
292 self._check_call_git_svn(['rebase']) 306 if active != 'master':
293 self._call_git(['branch', '-D', self.working_branch]) 307 self._check_call_git(['checkout', 'master', '--force', '--quiet'])
308 # git svn rebase --quiet --quiet doesn't work, use two steps to silence it.
309 self._check_call_git_svn(['fetch'])
310 self._check_call_git(
311 ['rebase', '--quiet', '%s/%s' % (self.remote, self.remote_branch)])
312 if self.working_branch in branches:
313 self._call_git(['branch', '-D', self.working_branch])
294 return int(self._git_svn_info('revision')) 314 return int(self._git_svn_info('revision'))
295 315
296 def _git_svn_info(self, key): 316 def _git_svn_info(self, key):
297 """Calls git svn info. This doesn't support nor need --config-dir.""" 317 """Calls git svn info. This doesn't support nor need --config-dir."""
298 return self._parse_svn_info( 318 return self._parse_svn_info(
299 self._check_capture_git(['svn', 'info']), key) 319 self._check_capture_git(['svn', 'info']), key)
300 320
301 def commit(self, commit_message, user): 321 def commit(self, commit_message, user):
302 """Commits a patch.""" 322 """Commits a patch."""
303 logging.info('Committing patch for %s' % user) 323 logging.info('Committing patch for %s' % user)
304 # Fix the commit message. 324 # Fix the commit message.
305 super(GitSvnCheckoutBase, self).commit(commit_message, user) 325 super(GitSvnCheckoutBase, self).commit(commit_message, user)
306 # Commit with git svn dcommit, then use svn directly to update the 326 # Commit with git svn dcommit, then use svn directly to update the
307 # committer on the revision. 327 # committer on the revision.
308 self._check_call_git_svn(['dcommit', '--rmdir', '--find-copies-harder']) 328 self._check_call_git_svn(['dcommit', '--rmdir', '--find-copies-harder'])
309 revision = int(self._git_svn_info('revision')) 329 revision = int(self._git_svn_info('revision'))
310 # Fix the committer. 330 # Fix the committer.
311 self._update_committer(revision, user) 331 self._update_committer(revision, user)
312 return revision 332 return revision
313 333
314 def _cache_svn_auth(self): 334 def _cache_svn_auth(self):
315 """Caches the svn credentials. It is necessary since git-svn doesn't prompt 335 """Caches the svn credentials. It is necessary since git-svn doesn't prompt
316 for it.""" 336 for it."""
317 if not self.commit_user: 337 if not self.commit_user:
318 return 338 return
319 logging.info('Caching svn credentials for %s' % self.commit_user) 339 # Use capture to lower noise in logs.
320 self._check_call_svn(['ls', self.svn_url], cwd=None) 340 self._check_capture_svn(['ls', self.svn_url], cwd=None)
321 341
322 def _check_call_git_svn(self, args, **kwargs): 342 def _check_call_git_svn(self, args, **kwargs):
323 """Handles svn authentication while calling git svn.""" 343 """Handles svn authentication while calling git svn."""
324 args = ['svn'] + args + ['--config-dir', self.svn_config_dir] 344 args = ['svn'] + args + ['--config-dir', self.svn_config_dir]
325 self._cache_svn_auth() 345 self._cache_svn_auth()
326 return self._check_call_git(args, **kwargs) 346 return self._check_call_git(args, **kwargs)
327 347
328 348
329 class GitSvnPremadeCheckout(GitSvnCheckoutBase): 349 class GitSvnPremadeCheckout(GitSvnCheckoutBase):
330 """Manages a git-svn clone made out from an initial git-svn seed. 350 """Manages a git-svn clone made out from an initial git-svn seed.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 user, message)) 431 user, message))
412 return 'FAKE' 432 return 'FAKE'
413 433
414 @property 434 @property
415 def project_name(self): 435 def project_name(self):
416 return self.checkout.project_name 436 return self.checkout.project_name
417 437
418 @property 438 @property
419 def project_path(self): 439 def project_path(self):
420 return self.checkout.project_path 440 return self.checkout.project_path
OLDNEW
« no previous file with comments | « no previous file | commit_queue.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698