Esempio n. 1
0
 def testChangeInfoMembers(self):
     self.mox.ReplayAll()
     members = [
         'CloseIssue',
         'Delete',
         'Exists',
         'GetFiles',
         'GetFileNames',
         'GetLocalRoot',
         'GetIssueDescription',
         'Load',
         'MissingTests',
         'NeedsUpload',
         'PrimeLint',
         'RpcServer',
         'Save',
         'SendToRietveld',
         'SEPARATOR',
         'UpdateRietveldDescription',
         'description',
         'issue',
         'name',
         'needs_upload',
         'patch',
         'patchset',
         'reviewers',
         'rietveld',
     ]
     # If this test fails, you should add the relevant test.
     self.compareMembers(
         gcl.ChangeInfo('', 0, 0, '', None, self.fake_root_dir, 'foo',
                        False), members)
Esempio n. 2
0
    def testNormal(self):
        change_info = gcl.ChangeInfo('naame', 0, 0, 'deescription',
                                     [('A', 'aa'),
                                      ('M', 'bb')], self.fake_root_dir)
        self.mox.StubOutWithMock(change_info, 'Save')
        args = ['--no_watchlists']
        change_info.Save()
        gcl.DoPresubmitChecks(change_info, False, True).AndReturn(True)
        gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('my_server')
        gcl.tempfile.mkstemp(text=True).AndReturn((42, 'descfile'))
        gcl.os.write(42, change_info.description)
        gcl.os.close(42)
        gcl.GetCodeReviewSetting('CC_LIST')
        gcl.os.getcwd().AndReturn('somewhere')
        gcl.os.chdir(change_info.GetLocalRoot())
        gcl.GenerateDiff(change_info.GetFileNames())
        gcl.upload.RealMain([
            'upload.py', '-y', '--server=my_server',
            "--description_file=descfile", "--message=deescription"
        ], change_info.patch).AndReturn(("1", "2"))
        gcl.os.remove('descfile')
        gcl.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=0.5)
        gcl.GetCodeReviewSetting('TRY_ON_UPLOAD').AndReturn('True')
        gcl.TryChange(change_info, [], swallow_exception=True)
        gcl.os.chdir('somewhere')
        self.mox.ReplayAll()

        gcl.UploadCL(change_info, args)
        self.assertEquals(change_info.issue, 1)
        self.assertEquals(change_info.patchset, 2)
Esempio n. 3
0
    def testSaveEmpty(self):
        gcl.GetChangelistInfoFile('').AndReturn('foo')
        gcl.WriteFile('foo',
                      gcl.ChangeInfo._SEPARATOR.join(['0, 0, clean', '', '']))
        self.mox.ReplayAll()

        change_info = gcl.ChangeInfo('', 0, 0, '', None, self.fake_root_dir)
        change_info.Save()
Esempio n. 4
0
  def testSaveDirty(self):
    gcl.GetChangelistInfoFile('n').AndReturn('foo')
    values = {
        'description': 'des', 'patchset': 0, 'issue': 0,
        'files': [], 'needs_upload': True, 'rietveld': 'https://foo'}
    gcl.gclient_utils.FileWrite(
        'foo', gcl.json.dumps(values, sort_keys=True, indent=2))
    self.mox.ReplayAll()

    change_info = gcl.ChangeInfo('n', 0, 0, 'des', None, self.fake_root_dir,
                                 'foo', needs_upload=True)
    change_info.Save()
Esempio n. 5
0
 def testChangeInfoBase(self):
     files = [('M', 'foo'), ('A', 'bar')]
     self.mox.ReplayAll()
     o = gcl.ChangeInfo('name2', '42', '53', 'description2', files,
                        self.fake_root_dir, 'foo', False)
     self.assertEquals(o.name, 'name2')
     self.assertEquals(o.issue, 42)
     self.assertEquals(o.patchset, 53)
     self.assertEquals(o.description, 'description2')
     self.assertEquals(o.patch, None)
     self.assertEquals(o.GetFileNames(), ['foo', 'bar'])
     self.assertEquals(o.GetFiles(), files)
     self.assertEquals(o.GetLocalRoot(), self.fake_root_dir)
Esempio n. 6
0
    def testSaveDirty(self):
        gcl.GetChangelistInfoFile('').AndReturn('foo')
        gcl.WriteFile('foo',
                      gcl.ChangeInfo._SEPARATOR.join(['0, 0, dirty', '', '']))
        self.mox.ReplayAll()

        change_info = gcl.ChangeInfo('',
                                     0,
                                     0,
                                     '',
                                     None,
                                     self.fake_root_dir,
                                     needs_upload=True)
        change_info.Save()
Esempio n. 7
0
  def testNormal(self):
    change_info = gcl.ChangeInfo(
        'naame',
        0,
        0,
        'deescription',
        [('A', 'aa'), ('M', 'bb')],
        self.fake_root_dir,
        'my_server',
        False)
    self.mox.StubOutWithMock(change_info, 'Save')
    change_info.Save()
    output = presubmit_support.PresubmitOutput()
    gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
    gcl.tempfile.mkstemp(text=True).AndReturn((42, 'descfile'))
    gcl.os.write(42, change_info.description)
    gcl.os.close(42)
    gcl.GetCodeReviewSetting('CC_LIST')
    gcl.GetCodeReviewSetting('PRIVATE')
    gcl.GetCodeReviewSetting('PROJECT')
    gcl.os.getcwd().AndReturn('somewhere')
    gcl.os.chdir(change_info.GetLocalRoot())
    gcl.GenerateDiff(change_info.GetFileNames())
    gcl.upload.RealMain(
        ['upload.py', '-y', '--server=https://my_server', "--file=descfile" ],
        change_info.patch).AndReturn(("1", "2"))
    gcl.os.remove('descfile')
    change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=60)
    gcl.os.chdir('somewhere')
    gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
                         " submit a try. ***")
    gcl.sys.stdout.write("\n")
    gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
    gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
        ).AndReturn(change_info)
    self.mox.ReplayAll()

    gcl.CMDupload(['naame', '--no_watchlists'])
    self.assertEquals(change_info.issue, 1)
    self.assertEquals(change_info.patchset, 2)
    self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
        'a try. ***\n'
        '*** Upload does not submit a try; use gcl try to submit a try. ***\n')
Esempio n. 8
0
 def testChangeInfoMembers(self):
     self.mox.ReplayAll()
     members = [
         'CloseIssue',
         'Delete',
         'GetFiles',
         'GetFileNames',
         'GetLocalRoot',
         'Exists',
         'Load',
         'MissingTests',
         'NeedsUpload',
         'Save',
         'UpdateRietveldDescription',
         'description',
         'issue',
         'name',
         'needs_upload',
         'patch',
         'patchset',
     ]
     # If this test fails, you should add the relevant test.
     self.compareMembers(
         gcl.ChangeInfo('', 0, 0, '', None, self.fake_root_dir), members)
Esempio n. 9
0
def Revert(revisions,
           force=False,
           commit=True,
           send_email=True,
           message=None,
           reviewers=None):
    """Reverts many revisions in one change list.

  If force is True, it will override local modifications.
  If commit is True, a commit is done after the revert.
  If send_mail is True, a review email is sent.
  If message is True, it is used as the change description.
  reviewers overrides the blames email addresses for review email."""

    # Use the oldest revision as the primary revision.
    changename = "revert%d" % revisions[len(revisions) - 1]
    if not force and os.path.exists(gcl.GetChangelistInfoFile(changename)):
        print "Error, change %s already exist." % changename
        return 1

    # Move to the repository root and make the revision numbers sorted in
    # decreasing order.
    local_root = gcl.GetRepositoryRoot()
    os.chdir(local_root)
    revisions.sort(reverse=True)
    revisions_string = ",".join([str(rev) for rev in revisions])
    revisions_string_rev = ",".join([str(-rev) for rev in revisions])

    # Get all the modified files by the revision. We'll use this list to optimize
    # the svn merge.
    logs = []
    for revision in revisions:
        logs.extend(CaptureSVNLog(["-r", str(revision), "-v"]))

    files = []
    blames = []
    repo_base = GetRepoBase()
    for log in logs:
        for file in log['paths']:
            file_name = file['path']
            # Remove the /trunk/src/ part. The + 1 is for the last slash.
            if not file_name.startswith(repo_base):
                raise OutsideOfCheckout(file_name)
            files.append(file_name[len(repo_base):])
        blames.append(log['author'])

    # On Windows, we need to fix the slashes once they got the url part removed.
    if sys.platform == 'win32':
        # On Windows, gcl expect the correct slashes.
        files = [file.replace('/', os.sep) for file in files]

    # Keep unique.
    files = UniqueFast(files)
    blames = UniqueFast(blames)
    if not reviewers:
        reviewers = blames
    else:
        reviewers = UniqueFast(reviewers)

    # Make sure there's something to revert.
    if not files:
        raise NoModifiedFile
    if not reviewers:
        raise NoBlameList

    if blames:
        print "Blaming %s\n" % ",".join(blames)
    if reviewers != blames:
        print "Emailing %s\n" % ",".join(reviewers)
    print "These files were modified in %s:" % revisions_string
    print "\n".join(files)
    print ""

    # Make sure these files are unmodified with svn status.
    status = gclient_scm.scm.SVN.CaptureStatus(files)
    if status:
        if force:
            # TODO(maruel): Use the tool to correctly revert '?' files.
            gcl.RunShell(["svn", "revert"] + files)
        else:
            raise ModifiedFile(status)
    # svn up on each of these files
    gcl.RunShell(["svn", "up"] + files)

    files_status = {}
    # Extract the first level subpaths. Subversion seems to degrade
    # exponentially w.r.t. repository size during merges. Working at the root
    # directory is too rough for svn due to the repository size.
    roots = UniqueFast([file.split(os.sep)[0] for file in files])
    for root in roots:
        # Is it a subdirectory or a files?
        is_root_subdir = os.path.isdir(root)
        need_to_update = False
        if is_root_subdir:
            os.chdir(root)
            file_list = []
            # List the file directly since it is faster when there is only one file.
            for file in files:
                if file.startswith(root):
                    file_list.append(file[len(root) + 1:])
            if len(file_list) > 1:
                # Listing multiple files is not supported by svn merge.
                file_list = ['.']
                need_to_update = True
        else:
            # Oops, root was in fact a file in the root directory.
            file_list = [root]
            root = "."

        print "Reverting %s in %s/" % (revisions_string, root)
        if need_to_update:
            # Make sure '.' revision is high enough otherwise merge will be
            # unhappy.
            retcode = gcl.RunShellWithReturnCode(['svn', 'up', '.', '-N'])[1]
            if retcode:
                print 'svn up . -N failed in %s/.' % root
                return retcode

        command = ["svn", "merge", "-c", revisions_string_rev]
        command.extend(file_list)
        (output, retcode) = gcl.RunShellWithReturnCode(command,
                                                       print_output=True)
        if retcode:
            print "'%s' failed:" % command
            return retcode

        # Grab the status
        lines = output.split('\n')
        for line in lines:
            if line.startswith('---'):
                continue
            if line.startswith('Skipped'):
                print ""
                raise ModifiedFile(line[9:-1])
            # Update the status.
            status = line[:5] + '  '
            file = line[5:]
            if is_root_subdir:
                files_status[root + os.sep + file] = status
            else:
                files_status[file] = status

        if is_root_subdir:
            os.chdir('..')

    # Transform files_status from a dictionary to a list of tuple.
    files_status = [(files_status[file], file) for file in files]

    description = "Reverting %s." % revisions_string
    if message:
        description += "\n\n"
        description += message
    # Don't use gcl.Change() since it prompts the user for infos.
    change_info = gcl.ChangeInfo(changename, 0, 0, description, files_status,
                                 local_root)
    change_info.Save()

    upload_args = ['--no_presubmit', '-r', ",".join(reviewers)]
    if send_email:
        upload_args.append('--send_mail')
    if commit:
        upload_args.append('--no_try')
    gcl.UploadCL(change_info, upload_args)

    retcode = 0
    if commit:
        gcl.Commit(change_info, ['--no_presubmit', '--force'])
        # TODO(maruel):  gclient sync (to leave the local checkout in an usable
        # state)
        retcode = gclient.Main(["gclient.py", "sync"])
    return retcode