def testMissingWatchlistsFileOK(self): """Test that we act gracefully if WATCHLISTS file is missing.""" watchlists.Watchlists._HasWatchlistsFile().AndReturn(False) self.mox.ReplayAll() wl = watchlists.Watchlists('/some/random/path') self.assertEqual(wl.GetWatchersForPaths(['some_path']), [])
def _CheckWatchlist(input_api, output_api): """Check that the WATCHLIST file parses correctly.""" errors = [] for f in input_api.AffectedFiles(): if f.LocalPath() != 'WATCHLISTS': continue import StringIO import logging import watchlists log_buffer = StringIO.StringIO() log_handler = logging.StreamHandler(log_buffer) log_handler.setFormatter( logging.Formatter('%(levelname)s: %(message)s')) logger = logging.getLogger() logger.addHandler(log_handler) wl = watchlists.Watchlists(input_api.change.RepositoryRoot()) logger.removeHandler(log_handler) log_handler.flush() log_buffer.flush() if log_buffer.getvalue(): errors.append( output_api.PresubmitError( 'Cannot parse WATCHLISTS file, please resolve.', log_buffer.getvalue().splitlines())) return errors
def testWinPathWatchers(self): """Test watchers for a windows path (containing backward slashes).""" watchers = ['*****@*****.**', '*****@*****.**'] contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'browser': { 'filepath': 'chrome/browser/.*', }, }, 'WATCHLISTS': { 'browser': %s, }, } """ % watchers saved_sep = watchlists.os.sep watchlists.os.sep = '\\' # to pose as win32 watchlists.Watchlists._HasWatchlistsFile().AndReturn(True) watchlists.Watchlists._ContentsOfWatchlistsFile().AndReturn(contents) self.mox.ReplayAll() wl = watchlists.Watchlists(r'a\path') returned_watchers = wl.GetWatchersForPaths( [r'chrome\browser\renderer_host\render_widget_host.h']) watchlists.os.sep = saved_sep # revert back os.sep before asserts self.assertEqual(returned_watchers, watchers)
def testGarbledWatchlistsFileOK(self): """Test that we act gracefully if WATCHLISTS file is garbled.""" contents = 'some garbled and unwanted text' watchlists.Watchlists._HasWatchlistsFile.return_value = True watchlists.Watchlists._ContentsOfWatchlistsFile.return_value = contents wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['some_path']), [])
def testGarbledWatchlistsFileOK(self): """Test that we act gracefully if WATCHLISTS file is garbled.""" contents = 'some garbled and unwanted text' watchlists.Watchlists._HasWatchlistsFile().AndReturn(True) watchlists.Watchlists._ContentsOfWatchlistsFile().AndReturn(contents) watchlists.logging.error(super_mox.mox.IgnoreArg()) self.mox.ReplayAll() wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['some_path']), [])
def testValidWatcher(self): watchers = ['*****@*****.**', '*****@*****.**'] contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'a_module': { 'filepath': 'a_module', }, }, 'WATCHLISTS': { 'a_module': %s, }, } """ % watchers watchlists.Watchlists._HasWatchlistsFile.return_value = True watchlists.Watchlists._ContentsOfWatchlistsFile.return_value = contents wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['a_module']), watchers)
def testNoWatchers(self): contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'a_module': { 'filepath': 'a_module', }, }, 'WATCHLISTS': { 'a_module': [], }, } """ watchlists.Watchlists._HasWatchlistsFile.return_value = True watchlists.Watchlists._ContentsOfWatchlistsFile.return_value = contents wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['a_module']), [])
def testValidWatcher(self): watchers = ['*****@*****.**', '*****@*****.**'] contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'a_module': { 'filepath': 'a_module', }, }, 'WATCHLISTS': { 'a_module': %s, }, } """ % watchers watchlists.Watchlists._HasWatchlistsFile().AndReturn(True) watchlists.Watchlists._ContentsOfWatchlistsFile().AndReturn(contents) self.mox.ReplayAll() wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['a_module']), watchers)
def testNoWatchers(self): contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'a_module': { 'filepath': 'a_module', }, }, 'WATCHLISTS': { 'a_module': [], }, } """ watchlists.Watchlists._HasWatchlistsFile().AndReturn(True) watchlists.Watchlists._ContentsOfWatchlistsFile().AndReturn(contents) self.mox.ReplayAll() wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['a_module']), [])
def testMultipleWatchlistsTrigger(self): """Test that multiple watchlists can get triggered for one filepath.""" contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'mac': { 'filepath': 'mac', }, 'views': { 'filepath': 'views', }, }, 'WATCHLISTS': { 'mac': ['*****@*****.**'], 'views': ['*****@*****.**'], }, } """ watchlists.Watchlists._HasWatchlistsFile.return_value = True watchlists.Watchlists._ContentsOfWatchlistsFile.return_value = contents wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['file_views_mac']), ['*****@*****.**', '*****@*****.**'])
def testDuplicateWatchers(self): """Test that multiple watchlists can get triggered for one filepath.""" watchers = ['*****@*****.**'] contents = \ """{ 'WATCHLIST_DEFINITIONS': { 'mac': { 'filepath': 'mac', }, 'views': { 'filepath': 'views', }, }, 'WATCHLISTS': { 'mac': %s, 'views': %s, }, } """ % (watchers, watchers) watchlists.Watchlists._HasWatchlistsFile.return_value = True watchlists.Watchlists._ContentsOfWatchlistsFile.return_value = contents wl = watchlists.Watchlists('/a/path') self.assertEqual(wl.GetWatchersForPaths(['file_views_mac']), watchers)
def UploadCL(change_info, args): if not change_info.GetFiles(): print "Nothing to upload, changelist is empty." return if not OptionallyDoPresubmitChecks(change_info, False, args): return no_try = FilterFlag(args, "--no_try") or FilterFlag(args, "--no-try") no_watchlists = FilterFlag(args, "--no_watchlists") or \ FilterFlag(args, "--no-watchlists") # Map --send-mail to --send_mail if FilterFlag(args, "--send-mail"): args.append("--send_mail") # Supports --clobber for the try server. clobber = FilterFlag(args, "--clobber") # Disable try when the server is overridden. server_1 = re.compile(r"^-s\b.*") server_2 = re.compile(r"^--server\b.*") for arg in args: if server_1.match(arg) or server_2.match(arg): no_try = True break upload_arg = ["upload.py", "-y"] upload_arg.append("--server=" + GetCodeReviewSetting("CODE_REVIEW_SERVER")) upload_arg.extend(args) desc_file = "" if change_info.issue: # Uploading a new patchset. found_message = False for arg in args: if arg.startswith("--message") or arg.startswith("-m"): found_message = True break if not found_message: upload_arg.append("--message=''") upload_arg.append("--issue=%d" % change_info.issue) else: # First time we upload. handle, desc_file = tempfile.mkstemp(text=True) os.write(handle, change_info.description) os.close(handle) # Watchlist processing -- CC people interested in this changeset # http://dev.chromium.org/developers/contributing-code/watchlists if not no_watchlists: import watchlists watchlist = watchlists.Watchlists(change_info.GetLocalRoot()) watchers = watchlist.GetWatchersForPaths( change_info.GetFileNames()) cc_list = GetCodeReviewSetting("CC_LIST") if not no_watchlists and watchers: # Filter out all empty elements and join by ',' cc_list = ','.join(filter(None, [cc_list] + watchers)) if cc_list: upload_arg.append("--cc=" + cc_list) upload_arg.append("--description_file=" + desc_file + "") if change_info.description: subject = change_info.description[:77] if subject.find("\r\n") != -1: subject = subject[:subject.find("\r\n")] if subject.find("\n") != -1: subject = subject[:subject.find("\n")] if len(change_info.description) > 77: subject = subject + "..." upload_arg.append("--message=" + subject) # Change the current working directory before calling upload.py so that it # shows the correct base. previous_cwd = os.getcwd() os.chdir(change_info.GetLocalRoot()) # If we have a lot of files with long paths, then we won't be able to fit # the command to "svn diff". Instead, we generate the diff manually for # each file and concatenate them before passing it to upload.py. if change_info.patch is None: change_info.patch = GenerateDiff(change_info.GetFileNames()) issue, patchset = upload.RealMain(upload_arg, change_info.patch) if issue and patchset: change_info.issue = int(issue) change_info.patchset = int(patchset) change_info.Save() if desc_file: os.remove(desc_file) # Do background work on Rietveld to lint the file so that the results are # ready when the issue is viewed. SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) # Move back before considering try, so GetCodeReviewSettings is # consistent. os.chdir(previous_cwd) # Once uploaded to Rietveld, send it to the try server. if not no_try: try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD') if try_on_upload and try_on_upload.lower() == 'true': trychange_args = [] if clobber: trychange_args.append('--clobber') TryChange(change_info, trychange_args, swallow_exception=True)
def CMDupload(change_info, args): """Uploads the changelist to the server for review. This does not submit a try job; use gcl try to submit a try job. """ if '-s' in args or '--server' in args: ErrorExit('Don\'t use the -s flag, fix codereview.settings instead') if not change_info.GetFiles(): print "Nothing to upload, changelist is empty." return 0 if not OptionallyDoPresubmitChecks(change_info, False, args): return 1 no_watchlists = (FilterFlag(args, "--no_watchlists") or FilterFlag(args, "--no-watchlists")) # Map --send-mail to --send_mail if FilterFlag(args, "--send-mail"): args.append("--send_mail") upload_arg = ["upload.py", "-y"] server = GetCodeReviewSetting("CODE_REVIEW_SERVER") if not server: ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND) upload_arg.append("--server=%s" % server) upload_arg.extend(args) desc_file = "" if change_info.issue: # Uploading a new patchset. found_message = False for arg in args: if arg.startswith("--message") or arg.startswith("-m"): found_message = True break if not found_message: upload_arg.append("--message=''") upload_arg.append("--issue=%d" % change_info.issue) else: # First time we upload. handle, desc_file = tempfile.mkstemp(text=True) os.write(handle, change_info.description) os.close(handle) # Watchlist processing -- CC people interested in this changeset # http://dev.chromium.org/developers/contributing-code/watchlists if not no_watchlists: import watchlists watchlist = watchlists.Watchlists(change_info.GetLocalRoot()) watchers = watchlist.GetWatchersForPaths(change_info.GetFileNames()) cc_list = GetCodeReviewSetting("CC_LIST") if not no_watchlists and watchers: # Filter out all empty elements and join by ',' cc_list = ','.join(filter(None, [cc_list] + watchers)) if cc_list: upload_arg.append("--cc=" + cc_list) upload_arg.append("--description_file=" + desc_file + "") if change_info.description: subject = change_info.description[:77] if subject.find("\r\n") != -1: subject = subject[:subject.find("\r\n")] if subject.find("\n") != -1: subject = subject[:subject.find("\n")] if len(change_info.description) > 77: subject = subject + "..." upload_arg.append("--message=" + subject) if GetCodeReviewSetting("PRIVATE") == "True": upload_arg.append("--private") # Change the current working directory before calling upload.py so that it # shows the correct base. previous_cwd = os.getcwd() os.chdir(change_info.GetLocalRoot()) # If we have a lot of files with long paths, then we won't be able to fit # the command to "svn diff". Instead, we generate the diff manually for # each file and concatenate them before passing it to upload.py. if change_info.patch is None: change_info.patch = GenerateDiff(change_info.GetFileNames()) issue, patchset = upload.RealMain(upload_arg, change_info.patch) if issue and patchset: change_info.issue = int(issue) change_info.patchset = int(patchset) change_info.Save() if desc_file: os.remove(desc_file) # Do background work on Rietveld to lint the file so that the results are # ready when the issue is viewed. SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) # Move back before considering try, so GetCodeReviewSettings is # consistent. os.chdir(previous_cwd) print "*** Upload does not submit a try; use gcl try to submit a try. ***" return 0
def testMissingWatchlistsFileOK(self): """Test that we act gracefully if WATCHLISTS file is missing.""" watchlists.Watchlists._HasWatchlistsFile.return_value = False wl = watchlists.Watchlists('/some/random/path') self.assertEqual(wl.GetWatchersForPaths(['some_path']), [])
def CMDupload(change_info, args): """Uploads the changelist to the server for review. This does not submit a try job; use gcl try to submit a try job. """ if '-s' in args or '--server' in args: ErrorExit('Don\'t use the -s flag, fix codereview.settings instead') if not change_info.GetFiles(): print "Nothing to upload, changelist is empty." return 0 output = OptionallyDoPresubmitChecks(change_info, False, args) if not output.should_continue(): return 1 no_watchlists = (FilterFlag(args, "--no_watchlists") or FilterFlag(args, "--no-watchlists")) # Map --send-mail to --send_mail if FilterFlag(args, "--send-mail"): args.append("--send_mail") # Replace -m with -t and --message with --title, but make sure to # preserve anything after the -m/--message. found_deprecated_arg = [False] def replace_message(a): if a.startswith('-m'): found_deprecated_arg[0] = True return '-t' + a[2:] elif a.startswith('--message'): found_deprecated_arg[0] = True return '--title' + a[9:] return a args = map(replace_message, args) if found_deprecated_arg[0]: print >> sys.stderr, ( '\nWARNING: Use -t or --title to set the title of the patchset.\n' 'In the near future, -m or --message will send a message instead.\n' 'See http://goo.gl/JGg0Z for details.\n') upload_arg = ["upload.py", "-y"] upload_arg.append("--server=%s" % change_info.rietveld) reviewers = change_info.get_reviewers() or output.reviewers if (reviewers and not any(arg.startswith('-r') or arg.startswith('--reviewer') for arg in args)): upload_arg.append('--reviewers=%s' % ','.join(reviewers)) upload_arg.extend(args) desc_file = None try: if change_info.issue: # Uploading a new patchset. upload_arg.append("--issue=%d" % change_info.issue) if not any(i.startswith('--title') or i.startswith('-t') for i in args): upload_arg.append('--title= ') else: # First time we upload. handle, desc_file = tempfile.mkstemp(text=True) os.write(handle, change_info.description) os.close(handle) # Watchlist processing -- CC people interested in this changeset # http://dev.chromium.org/developers/contributing-code/watchlists if not no_watchlists: import watchlists watchlist = watchlists.Watchlists(change_info.GetLocalRoot()) watchers = watchlist.GetWatchersForPaths(change_info.GetFileNames()) cc_list = GetCodeReviewSetting("CC_LIST") if not no_watchlists and watchers: # Filter out all empty elements and join by ',' cc_list = ','.join(filter(None, [cc_list] + watchers)) if cc_list: upload_arg.append("--cc=" + cc_list) upload_arg.append("--file=%s" % desc_file) if GetCodeReviewSetting("PRIVATE") == "True": upload_arg.append("--private") # If we have a lot of files with long paths, then we won't be able to fit # the command to "svn diff". Instead, we generate the diff manually for # each file and concatenate them before passing it to upload.py. if change_info.patch is None: change_info.patch = GenerateDiff(change_info.GetFileNames()) # Change the current working directory before calling upload.py so that it # shows the correct base. previous_cwd = os.getcwd() os.chdir(change_info.GetLocalRoot()) try: try: issue, patchset = upload.RealMain(upload_arg, change_info.patch) except KeyboardInterrupt: sys.exit(1) if issue and patchset: change_info.issue = int(issue) change_info.patchset = int(patchset) change_info.Save() change_info.PrimeLint() finally: os.chdir(previous_cwd) finally: if desc_file: os.remove(desc_file) print "*** Upload does not submit a try; use gcl try to submit a try. ***" return 0