Example #1
0
    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']), [])
Example #2
0
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
Example #3
0
    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)
Example #4
0
    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']), [])
Example #5
0
    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']), [])
Example #6
0
    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)
Example #7
0
    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']), [])
Example #8
0
    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)
Example #9
0
    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']), [])
Example #10
0
    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']),
                         ['*****@*****.**', '*****@*****.**'])
Example #11
0
    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)
Example #12
0
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)
Example #13
0
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
Example #14
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']), [])
Example #15
0
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