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

Side by Side Diff: trychange.py

Issue 7925014: Support for |change| argument to |GetPreferredTrySlaves()|. (Closed) Base URL: http://src.chromium.org/svn/trunk/tools/depot_tools/
Patch Set: '' Created 9 years, 2 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 | « tests/presubmit_unittest.py ('k') | 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 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 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 """Client-side script to send a try job to the try server. It communicates to 6 """Client-side script to send a try job to the try server. It communicates to
7 the try server by either writting to a svn repository or by directly connecting 7 the try server by either writting to a svn repository or by directly connecting
8 to the server by HTTP. 8 to the server by HTTP.
9 """ 9 """
10 10
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 class SCM(object): 94 class SCM(object):
95 """Simplistic base class to implement one function: ProcessOptions.""" 95 """Simplistic base class to implement one function: ProcessOptions."""
96 def __init__(self, options, path): 96 def __init__(self, options, path):
97 items = path.split('@') 97 items = path.split('@')
98 assert len(items) <= 2 98 assert len(items) <= 2
99 self.checkout_root = items[0] 99 self.checkout_root = items[0]
100 items.append(None) 100 items.append(None)
101 self.diff_against = items[1] 101 self.diff_against = items[1]
102 self.options = options 102 self.options = options
103 self.files = self.options.files 103 self.files = self.options.files
104 self.file_tuples = [('M', f) for f in self.files]
104 self.options.files = None 105 self.options.files = None
105 self.codereview_settings = None 106 self.codereview_settings = None
106 self.codereview_settings_file = 'codereview.settings' 107 self.codereview_settings_file = 'codereview.settings'
107 self.gclient_root = None 108 self.gclient_root = None
108 109
109 def GetFileNames(self): 110 def GetFileNames(self):
110 """Return the list of files in the diff.""" 111 """Return the list of files in the diff."""
111 return self.files 112 return self.files
112 113
114 def GetFileTuples(self):
115 """Return the list of file (status, filename) tuples in the diff."""
116 return self.file_tuples
117
113 def GetCodeReviewSetting(self, key): 118 def GetCodeReviewSetting(self, key):
114 """Returns a value for the given key for this repository. 119 """Returns a value for the given key for this repository.
115 120
116 Uses gcl-style settings from the repository. 121 Uses gcl-style settings from the repository.
117 """ 122 """
118 if gcl: 123 if gcl:
119 gcl_setting = gcl.GetCodeReviewSetting(key) 124 gcl_setting = gcl.GetCodeReviewSetting(key)
120 if gcl_setting != '': 125 if gcl_setting != '':
121 return gcl_setting 126 return gcl_setting
122 if self.codereview_settings is None: 127 if self.codereview_settings is None:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 assert cur.startswith(root), (root, cur) 185 assert cur.startswith(root), (root, cur)
181 while cur.startswith(root): 186 while cur.startswith(root):
182 filepath = os.path.join(cur, filename) 187 filepath = os.path.join(cur, filename)
183 if os.path.isfile(filepath): 188 if os.path.isfile(filepath):
184 logging.info('Found %s at %s' % (filename, cur)) 189 logging.info('Found %s at %s' % (filename, cur))
185 return gclient_utils.FileRead(filepath) 190 return gclient_utils.FileRead(filepath)
186 cur = os.path.dirname(cur) 191 cur = os.path.dirname(cur)
187 logging.warning('Didn\'t find %s' % filename) 192 logging.warning('Didn\'t find %s' % filename)
188 return None 193 return None
189 194
195 def SetFileTuples(self, file_tuples):
M-A Ruel 2011/09/26 17:48:34 I'd rather have self.files and self.file_tuples be
Alexei Svitkine (slow) 2011/09/26 18:14:06 Like so?
196 excluded = ['!', '?', 'X', ' ', '~']
197 def Excluded(f):
198 if f[0][0] in excluded:
199 return True
200 for r in self.options.exclude:
201 if re.search(r, f[1]):
202 logging.info('Ignoring "%s"' % f[1])
203 return True
204 return False
205
206 self.file_tuples = [f for f in file_tuples if not Excluded(f)]
207 self.files = [f[1] for f in self.file_tuples]
208
190 209
191 class SVN(SCM): 210 class SVN(SCM):
192 """Gathers the options and diff for a subversion checkout.""" 211 """Gathers the options and diff for a subversion checkout."""
193 def __init__(self, *args, **kwargs): 212 def __init__(self, *args, **kwargs):
194 SCM.__init__(self, *args, **kwargs) 213 SCM.__init__(self, *args, **kwargs)
195 self.checkout_root = scm.SVN.GetCheckoutRoot(self.checkout_root) 214 self.checkout_root = scm.SVN.GetCheckoutRoot(self.checkout_root)
196 if not self.options.email: 215 if not self.options.email:
197 # Assumes the svn credential is an email address. 216 # Assumes the svn credential is an email address.
198 self.options.email = scm.SVN.GetEmail(self.checkout_root) 217 self.options.email = scm.SVN.GetEmail(self.checkout_root)
199 logging.info("SVN(%s)" % self.checkout_root) 218 logging.info("SVN(%s)" % self.checkout_root)
(...skipping 12 matching lines...) Expand all
212 231
213 def GenerateDiff(self): 232 def GenerateDiff(self):
214 """Returns a string containing the diff for the given file list. 233 """Returns a string containing the diff for the given file list.
215 234
216 The files in the list should either be absolute paths or relative to the 235 The files in the list should either be absolute paths or relative to the
217 given root. 236 given root.
218 """ 237 """
219 if not self.files: 238 if not self.files:
220 previous_cwd = os.getcwd() 239 previous_cwd = os.getcwd()
221 os.chdir(self.checkout_root) 240 os.chdir(self.checkout_root)
222 241 self.SetFileTuples(scm.SVN.CaptureStatus(self.checkout_root))
223 excluded = ['!', '?', 'X', ' ', '~']
224 def Excluded(f):
225 if f[0][0] in excluded:
226 return True
227 for r in self.options.exclude:
228 if re.search(r, f[1]):
229 logging.info('Ignoring "%s"' % f[1])
230 return True
231 return False
232
233 self.files = [f[1] for f in scm.SVN.CaptureStatus(self.checkout_root)
234 if not Excluded(f)]
235 os.chdir(previous_cwd) 242 os.chdir(previous_cwd)
236 return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True, 243 return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True,
237 revision=self.diff_against) 244 revision=self.diff_against)
238 245
239 246
240 class GIT(SCM): 247 class GIT(SCM):
241 """Gathers the options and diff for a git checkout.""" 248 """Gathers the options and diff for a git checkout."""
242 def __init__(self, *args, **kwargs): 249 def __init__(self, *args, **kwargs):
243 SCM.__init__(self, *args, **kwargs) 250 SCM.__init__(self, *args, **kwargs)
244 self.checkout_root = scm.GIT.GetCheckoutRoot(self.checkout_root) 251 self.checkout_root = scm.GIT.GetCheckoutRoot(self.checkout_root)
245 if not self.options.name: 252 if not self.options.name:
246 self.options.name = scm.GIT.GetPatchName(self.checkout_root) 253 self.options.name = scm.GIT.GetPatchName(self.checkout_root)
247 if not self.options.email: 254 if not self.options.email:
248 self.options.email = scm.GIT.GetEmail(self.checkout_root) 255 self.options.email = scm.GIT.GetEmail(self.checkout_root)
249 if not self.diff_against: 256 if not self.diff_against:
250 self.diff_against = scm.GIT.GetUpstreamBranch(self.checkout_root) 257 self.diff_against = scm.GIT.GetUpstreamBranch(self.checkout_root)
251 if not self.diff_against: 258 if not self.diff_against:
252 raise NoTryServerAccess( 259 raise NoTryServerAccess(
253 "Unable to determine default branch to diff against. " 260 "Unable to determine default branch to diff against. "
254 "Verify this branch is set up to track another" 261 "Verify this branch is set up to track another"
255 "(via the --track argument to \"git checkout -b ...\"") 262 "(via the --track argument to \"git checkout -b ...\"")
256 logging.info("GIT(%s)" % self.checkout_root) 263 logging.info("GIT(%s)" % self.checkout_root)
257 264
258 def GenerateDiff(self): 265 def GenerateDiff(self):
259 if not self.files: 266 if not self.files:
260 self.files = scm.GIT.GetDifferentFiles(self.checkout_root, 267 self.SetFileTuples(scm.GIT.CaptureStatus(self.checkout_root,
261 branch=self.diff_against) 268 self.diff_against))
262
263 def NotExcluded(f):
264 for r in self.options.exclude:
265 if re.search(r, f):
266 logging.info('Ignoring "%s"' % f)
267 return False
268 return True
269
270 self.files = filter(NotExcluded, self.files)
271 return scm.GIT.GenerateDiff(self.checkout_root, files=self.files, 269 return scm.GIT.GenerateDiff(self.checkout_root, files=self.files,
272 full_move=True, 270 full_move=True,
273 branch=self.diff_against) 271 branch=self.diff_against)
274 272
275 273
276 def _ParseSendChangeOptions(options): 274 def _ParseSendChangeOptions(options):
277 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN.""" 275 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN."""
278 values = {} 276 values = {}
279 if options.email: 277 if options.email:
280 values['email'] = options.email 278 values['email'] = options.email
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 def GetMungedDiff(path_diff, diff): 455 def GetMungedDiff(path_diff, diff):
458 # Munge paths to match svn. 456 # Munge paths to match svn.
459 for i in range(len(diff)): 457 for i in range(len(diff)):
460 if diff[i].startswith('--- ') or diff[i].startswith('+++ '): 458 if diff[i].startswith('--- ') or diff[i].startswith('+++ '):
461 new_file = posixpath.join(path_diff, diff[i][4:]).replace('\\', '/') 459 new_file = posixpath.join(path_diff, diff[i][4:]).replace('\\', '/')
462 diff[i] = diff[i][0:4] + new_file 460 diff[i] = diff[i][0:4] + new_file
463 return diff 461 return diff
464 462
465 463
466 def TryChange(argv, 464 def TryChange(argv,
465 change,
467 file_list, 466 file_list,
468 swallow_exception, 467 swallow_exception,
469 prog=None, 468 prog=None,
470 extra_epilog=None): 469 extra_epilog=None):
471 """ 470 """
472 Args: 471 Args:
473 argv: Arguments and options. 472 argv: Arguments and options.
474 file_list: Default value to pass to --file. 473 file_list: Default value to pass to --file.
475 swallow_exception: Whether we raise or swallow exceptions. 474 swallow_exception: Whether we raise or swallow exceptions.
476 """ 475 """
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 # Use this as the base. 693 # Use this as the base.
695 root = checkouts[0].checkout_root 694 root = checkouts[0].checkout_root
696 diffs = [] 695 diffs = []
697 for checkout in checkouts: 696 for checkout in checkouts:
698 diff = checkout.GenerateDiff().splitlines(True) 697 diff = checkout.GenerateDiff().splitlines(True)
699 path_diff = gclient_utils.PathDifference(root, checkout.checkout_root) 698 path_diff = gclient_utils.PathDifference(root, checkout.checkout_root)
700 # Munge it. 699 # Munge it.
701 diffs.extend(GetMungedDiff(path_diff, diff)) 700 diffs.extend(GetMungedDiff(path_diff, diff))
702 options.diff = ''.join(diffs) 701 options.diff = ''.join(diffs)
703 702
703 if options.name is None:
M-A Ruel 2011/09/26 17:48:34 if not options.name: Not sure why it was the othe
Alexei Svitkine (slow) 2011/09/26 18:14:06 Done.
704 if options.issue:
705 options.name = 'Issue %s' % options.issue
706 else:
707 options.name = 'Unnamed'
708 print('Note: use --name NAME to change the try job name.')
709
710 if not options.email:
711 parser.error('Using an anonymous checkout. Please use --email or set '
712 'the TRYBOT_RESULTS_EMAIL_ADDRESS environment variable.')
713 else:
M-A Ruel 2011/09/26 17:48:34 actually, remove the else, since the parser.error(
Alexei Svitkine (slow) 2011/09/26 18:14:06 Done.
714 print('Results will be emailed to: ' + options.email)
715
704 if not options.bot: 716 if not options.bot:
705 # Get try slaves from PRESUBMIT.py files if not specified. 717 # Get try slaves from PRESUBMIT.py files if not specified.
706 # Even if the diff comes from options.url, use the local checkout for bot 718 # Even if the diff comes from options.url, use the local checkout for bot
707 # selection. 719 # selection.
708 try: 720 try:
709 import presubmit_support 721 import presubmit_support
710 root_presubmit = checkouts[0].ReadRootFile('PRESUBMIT.py') 722 root_presubmit = checkouts[0].ReadRootFile('PRESUBMIT.py')
723 if change is None:
724 change = presubmit_support.Change(options.name,
725 '',
726 checkouts[0].checkout_root,
727 checkouts[0].GetFileTuples(),
728 options.issue,
729 options.patchset,
730 options.email)
711 options.bot = presubmit_support.DoGetTrySlaves( 731 options.bot = presubmit_support.DoGetTrySlaves(
732 change,
712 checkouts[0].GetFileNames(), 733 checkouts[0].GetFileNames(),
713 checkouts[0].checkout_root, 734 checkouts[0].checkout_root,
714 root_presubmit, 735 root_presubmit,
715 options.project, 736 options.project,
716 False, 737 False,
717 sys.stdout) 738 sys.stdout)
718 except ImportError: 739 except ImportError:
719 pass 740 pass
720 # If no bot is specified, either the default pool will be selected or the 741 # If no bot is specified, either the default pool will be selected or the
721 # try server will refuse the job. Either case we don't need to interfere. 742 # try server will refuse the job. Either case we don't need to interfere.
722 743
723 if options.name is None:
724 if options.issue:
725 options.name = 'Issue %s' % options.issue
726 else:
727 options.name = 'Unnamed'
728 print('Note: use --name NAME to change the try job name.')
729 if not options.email:
730 parser.error('Using an anonymous checkout. Please use --email or set '
731 'the TRYBOT_RESULTS_EMAIL_ADDRESS environment variable.')
732 else:
733 print('Results will be emailed to: ' + options.email)
734
735 # Prevent rietveld updates if we aren't running all the tests. 744 # Prevent rietveld updates if we aren't running all the tests.
736 if options.testfilter is not None: 745 if options.testfilter is not None:
737 options.issue = None 746 options.issue = None
738 options.patchset = None 747 options.patchset = None
739 748
740 # Send the patch. 749 # Send the patch.
741 if options.send_patch: 750 if options.send_patch:
742 # If forced. 751 # If forced.
743 options.send_patch(options) 752 options.send_patch(options)
744 PrintSuccess(options) 753 PrintSuccess(options)
(...skipping 15 matching lines...) Expand all
760 print >> sys.stderr, e 769 print >> sys.stderr, e
761 return 1 770 return 1
762 except (gclient_utils.Error, subprocess2.CalledProcessError), e: 771 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
763 print >> sys.stderr, e 772 print >> sys.stderr, e
764 return 1 773 return 1
765 return 0 774 return 0
766 775
767 776
768 if __name__ == "__main__": 777 if __name__ == "__main__":
769 fix_encoding.fix_encoding() 778 fix_encoding.fix_encoding()
770 sys.exit(TryChange(None, [], False)) 779 sys.exit(TryChange(None, None, [], False))
OLDNEW
« no previous file with comments | « tests/presubmit_unittest.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698