Beispiel #1
0
    def commit(self, paths, message, file_data, base_revision, addeddirs,
               deleteddirs, properties, copies):
        """Commits the appropriate targets from revision in editor's store.
        """
        self.init_ra_and_client()
        commit_info = []
        def commit_cb(_commit_info, pool):
            commit_info.append(_commit_info)
        editor, edit_baton = ra.get_commit_editor2(self.ra,
                                                   message,
                                                   commit_cb,
                                                   None,
                                                   False,
                                                   self.pool)
        checksum = []
        # internal dir batons can fall out of scope and get GCed before svn is
        # done with them. This prevents that (credit to gvn for the idea).
        batons = [edit_baton, ]
        def driver_cb(parent, path, pool):
            if not parent:
                bat = editor.open_root(edit_baton, base_revision, self.pool)
                batons.append(bat)
                return bat
            if path in deleteddirs:
                bat = editor.delete_entry(path, base_revision, parent, pool)
                batons.append(bat)
                return bat
            if path not in file_data:
                if path in addeddirs:
                    bat = editor.add_directory(path, parent, None, -1, pool)
                else:
                    bat = editor.open_directory(path, parent, base_revision, pool)
                batons.append(bat)
                props = properties.get(path, {})
                if 'svn:externals' in props:
                    value = props['svn:externals']
                    editor.change_dir_prop(bat, 'svn:externals', value, pool)
                return bat
            base_text, new_text, action = file_data[path]
            compute_delta = True
            if action == 'modify':
                baton = editor.open_file(path, parent, base_revision, pool)
            elif action == 'add':
                frompath, fromrev = copies.get(path, (None, -1))
                if frompath:
                    frompath = self.path2url(frompath)
                baton = editor.add_file(path, parent, frompath, fromrev, pool)
            elif action == 'delete':
                baton = editor.delete_entry(path, base_revision, parent, pool)
                compute_delta = False

            if path in properties:
                if properties[path].get('svn:special', None):
                    new_text = 'link %s' % new_text
                for p, v in properties[path].iteritems():
                    editor.change_file_prop(baton, p, v)

            if compute_delta:
                handler, wh_baton = editor.apply_textdelta(baton, None,
                                                           self.pool)

                txdelta_stream = delta.svn_txdelta(
                    cStringIO.StringIO(base_text), cStringIO.StringIO(new_text),
                    self.pool)
                delta.svn_txdelta_send_txstream(txdelta_stream, handler,
                                                wh_baton, pool)

                # TODO pass md5(new_text) instead of None
                editor.close_file(baton, None, pool)

        delta.path_driver(editor, edit_baton, base_revision, paths, driver_cb,
                          self.pool)
        editor.close_edit(edit_baton, self.pool)
Beispiel #2
0
    def test_commit(self):
        # Replace README.txt's contents, using binary mode so we know the
        # exact contents even on Windows, and therefore the MD5 checksum.
        readme_path = '%s/trunk/README.txt' % self.path
        fp = open(readme_path, 'wb')
        fp.write('hello\n')
        fp.close()

        # Setup ra_ctx.
        ra.initialize()
        callbacks = ra.Callbacks()
        ra_ctx = ra.open2(REPOS_URL, callbacks, None, None)

        # Get commit editor.
        commit_info = [None]

        def commit_cb(_commit_info, pool):
            commit_info[0] = _commit_info

        (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, 'log message',
                                                     commit_cb, None, False)

        # Drive the commit.
        checksum = [None]

        def driver_cb(parent, path, pool):
            baton = editor.open_file(path, parent, -1, pool)
            adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool)
            (_,
             checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access,
                                                     False, editor, baton,
                                                     pool)
            return baton

        try:
            delta.path_driver(editor, edit_baton, -1, ['trunk/README.txt'],
                              driver_cb)
            editor.close_edit(edit_baton)
        except:
            try:
                editor.abort_edit(edit_baton)
            except:
                # We already have an exception in progress, not much we can do
                # about this.
                pass
            raise
        (checksum, ) = checksum
        (commit_info, ) = commit_info

        # Assert the commit.
        self.assertEquals(binascii.b2a_hex(checksum),
                          'b1946ac92492d2347c6235b4d2611184')
        self.assertEquals(commit_info.revision, 13)

        # Bump working copy state.
        wc.process_committed4(
            readme_path, wc.adm_retrieve(self.wc,
                                         os.path.dirname(readme_path)), False,
            commit_info.revision, commit_info.date, commit_info.author, None,
            False, False, checksum)

        # Assert bumped state.
        entry = wc.entry(readme_path, self.wc, False)
        self.assertEquals(entry.revision, commit_info.revision)
        self.assertEquals(entry.schedule, wc.schedule_normal)
        self.assertEquals(entry.cmt_rev, commit_info.revision)
        self.assertEquals(entry.cmt_date,
                          core.svn_time_from_cstring(commit_info.date))
Beispiel #3
0
  def test_delta_driver_commit(self):
    # Setup paths we'll commit in this test.
    to_delete = ['trunk/README.txt', 'trunk/dir1/dir2']
    to_mkdir = ['test_delta_driver_commit.d', 'test_delta_driver_commit2.d']
    to_add = ['test_delta_driver_commit', 'test_delta_driver_commit2']
    to_dir_prop = ['trunk/dir1/dir3', 'test_delta_driver_commit2.d']
    to_file_prop = ['trunk/README2.txt', 'test_delta_driver_commit2']
    all_paths = {}
    for i in to_delete + to_mkdir + to_add + to_dir_prop + to_file_prop:
      all_paths[i] = True
    # base revision for the commit
    revision = fs.youngest_rev(self.fs)

    commit_info = []
    def commit_cb(info, pool):
      commit_info.append(info)
    revprops = {"svn:log": "foobar", "testprop": ""}
    (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops,
                                                 commit_cb, None, False)
    try:
      def driver_cb(parent, path, pool):
        self.assert_(path in all_paths)
        dir_baton = file_baton = None
        if path in to_delete:
          # Leave dir_baton alone, as it must be None for delete.
          editor.delete_entry(path, revision, parent, pool)
        elif path in to_mkdir:
          dir_baton = editor.add_directory(path, parent,
                                           None, -1, # copyfrom
                                           pool)
        elif path in to_add:
          file_baton = editor.add_file(path, parent,
                                       None, -1, # copyfrom
                                       pool)
        # wc.py:test_commit tests apply_textdelta .
        if path in to_dir_prop:
          if dir_baton is None:
            dir_baton = editor.open_directory(path, parent, revision, pool)
          editor.change_dir_prop(dir_baton,
                                 'test_delta_driver_commit', 'foo', pool)
        elif path in to_file_prop:
          if file_baton is None:
            file_baton = editor.open_file(path, parent, revision, pool)
          editor.change_file_prop(file_baton,
                                  'test_delta_driver_commit', 'foo', pool)
        if file_baton is not None:
          editor.close_file(file_baton, None, pool)
        return dir_baton
      delta.path_driver(editor, edit_baton, -1, all_paths.keys(), driver_cb)
      editor.close_edit(edit_baton)
    except:
      try:
        editor.abort_edit(edit_baton)
      except:
        # We already have an exception in progress, not much we can do
        # about this.
        pass
      raise
    info = commit_info[0]

    if info.author is not None:
      revprops['svn:author'] = info.author
    revprops['svn:date'] = info.date
    self.assertEqual(ra.rev_proplist(self.ra_ctx, info.revision), revprops)

    receiver_called = [False]
    def receiver(changed_paths, revision, author, date, message, pool):
      receiver_called[0] = True
      self.assertEqual(revision, info.revision)
      self.assertEqual(author, info.author)
      self.assertEqual(date, info.date)
      self.assertEqual(message, revprops['svn:log'])
      for (path, change) in changed_paths.iteritems():
        path = path.lstrip('/')
        self.assert_(path in all_paths)
        if path in to_delete:
          self.assertEqual(change.action, 'D')
        elif path in to_mkdir or path in to_add:
          self.assertEqual(change.action, 'A')
        elif path in to_dir_prop or path in to_file_prop:
          self.assertEqual(change.action, 'M')
    ra.get_log(self.ra_ctx, [''], info.revision, info.revision,
               0,                       # limit
               True,                    # discover_changed_paths
               True,                    # strict_node_history
               receiver)
    self.assert_(receiver_called[0])
Beispiel #4
0
    def commit(self, paths, message, file_data, base_revision, addeddirs,
               deleteddirs, properties, copies):
        """Commits the appropriate targets from revision in editor's store.

        Return the committed revision as a common.Revision instance.
        """
        self.init_ra_and_client()

        def commit_cb(commit_info, pool):
            # disregard commit_info.post_commit_err for now
            r = common.Revision(commit_info.revision, commit_info.author,
                                message, commit_info.date)

            committedrev.append(r)

        committedrev = []

        editor, edit_baton = ra.get_commit_editor2(self.ra, message, commit_cb,
                                                   None, False, self.pool)
        checksum = []
        # internal dir batons can fall out of scope and get GCed before svn is
        # done with them. This prevents that (credit to gvn for the idea).
        batons = [
            edit_baton,
        ]

        def driver_cb(parent, path, pool):
            if not parent:
                bat = editor.open_root(edit_baton, base_revision, self.pool)
                batons.append(bat)
                return bat
            if path in deleteddirs:
                bat = editor.delete_entry(path, base_revision, parent, pool)
                batons.append(bat)

                if path not in addeddirs:
                    return bat

            if path not in file_data:
                if path in addeddirs:
                    frompath, fromrev = copies.get(path, (None, -1))
                    if frompath:
                        frompath = self.path2url(frompath)
                    bat = editor.add_directory(path, parent, frompath, fromrev,
                                               pool)
                else:
                    bat = editor.open_directory(path, parent, base_revision,
                                                pool)
                batons.append(bat)
                props = properties.get(path, {})
                if 'svn:externals' in props:
                    value = props['svn:externals']
                    editor.change_dir_prop(bat, 'svn:externals', value, pool)
                return bat
            base_text, new_text, action = file_data[path]
            compute_delta = True
            if action == 'modify':
                baton = editor.open_file(path, parent, base_revision, pool)
            elif action == 'add':
                frompath, fromrev = copies.get(path, (None, -1))
                if frompath:
                    frompath = self.path2url(frompath)
                baton = editor.add_file(path, parent, frompath, fromrev, pool)
            elif action == 'delete':
                baton = editor.delete_entry(path, base_revision, parent, pool)
                compute_delta = False

            if path in properties:
                if properties[path].get('svn:special', None):
                    new_text = 'link %s' % new_text
                for p, v in properties[path].iteritems():
                    editor.change_file_prop(baton, p, v)

            if compute_delta:
                handler, wh_baton = editor.apply_textdelta(
                    baton, None, self.pool)

                txdelta_stream = delta.svn_txdelta(
                    cStringIO.StringIO(base_text),
                    cStringIO.StringIO(new_text), self.pool)
                delta.svn_txdelta_send_txstream(txdelta_stream, handler,
                                                wh_baton, pool)

                # TODO pass md5(new_text) instead of None
                editor.close_file(baton, None, pool)

        try:
            delta.path_driver(editor, edit_baton, base_revision, paths,
                              driver_cb, self.pool)
        except:
            # If anything went wrong on the preceding lines, we should
            # abort the in-progress transaction.
            editor.abort_edit(edit_baton, self.pool)
            raise

        editor.close_edit(edit_baton, self.pool)

        return committedrev.pop()
Beispiel #5
0
    def test_delta_driver_commit(self):
        # Setup paths we'll commit in this test.
        to_delete = ['trunk/README.txt', 'trunk/dir1/dir2']
        to_mkdir = [
            'test_delta_driver_commit.d', 'test_delta_driver_commit2.d'
        ]
        to_add = ['test_delta_driver_commit', 'test_delta_driver_commit2']
        to_dir_prop = ['trunk/dir1/dir3', 'test_delta_driver_commit2.d']
        to_file_prop = ['trunk/README2.txt', 'test_delta_driver_commit2']
        all_paths = {}
        for i in to_delete + to_mkdir + to_add + to_dir_prop + to_file_prop:
            all_paths[i] = True
        # base revision for the commit
        revision = fs.youngest_rev(self.fs)

        commit_info = []

        def commit_cb(info, pool):
            commit_info.append(info)

        revprops = {"svn:log": "foobar", "testprop": ""}
        (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops,
                                                     commit_cb, None, False)
        try:

            def driver_cb(parent, path, pool):
                self.assert_(path in all_paths)
                dir_baton = file_baton = None
                if path in to_delete:
                    # Leave dir_baton alone, as it must be None for delete.
                    editor.delete_entry(path, revision, parent, pool)
                elif path in to_mkdir:
                    dir_baton = editor.add_directory(
                        path,
                        parent,
                        None,
                        -1,  # copyfrom
                        pool)
                elif path in to_add:
                    file_baton = editor.add_file(
                        path,
                        parent,
                        None,
                        -1,  # copyfrom
                        pool)
                # wc.py:test_commit tests apply_textdelta .
                if path in to_dir_prop:
                    if dir_baton is None:
                        dir_baton = editor.open_directory(
                            path, parent, revision, pool)
                    editor.change_dir_prop(dir_baton,
                                           'test_delta_driver_commit', 'foo',
                                           pool)
                elif path in to_file_prop:
                    if file_baton is None:
                        file_baton = editor.open_file(path, parent, revision,
                                                      pool)
                    editor.change_file_prop(file_baton,
                                            'test_delta_driver_commit', 'foo',
                                            pool)
                if file_baton is not None:
                    editor.close_file(file_baton, None, pool)
                return dir_baton

            delta.path_driver(editor, edit_baton, -1, list(all_paths.keys()),
                              driver_cb)
            editor.close_edit(edit_baton)
        except:
            try:
                editor.abort_edit(edit_baton)
            except:
                # We already have an exception in progress, not much we can do
                # about this.
                pass
            raise
        info = commit_info[0]

        if info.author is not None:
            revprops['svn:author'] = info.author
        revprops['svn:date'] = info.date
        self.assertEqual(ra.rev_proplist(self.ra_ctx, info.revision), revprops)

        receiver_called = [False]

        def receiver(changed_paths, revision, author, date, message, pool):
            receiver_called[0] = True
            self.assertEqual(revision, info.revision)
            self.assertEqual(author, info.author)
            self.assertEqual(date, info.date)
            self.assertEqual(message, revprops['svn:log'])
            for (path, change) in changed_paths.items():
                path = path.lstrip('/')
                self.assert_(path in all_paths)
                if path in to_delete:
                    self.assertEqual(change.action, 'D')
                elif path in to_mkdir or path in to_add:
                    self.assertEqual(change.action, 'A')
                elif path in to_dir_prop or path in to_file_prop:
                    self.assertEqual(change.action, 'M')

        ra.get_log(
            self.ra_ctx,
            [''],
            info.revision,
            info.revision,
            0,  # limit
            True,  # discover_changed_paths
            True,  # strict_node_history
            receiver)
        self.assert_(receiver_called[0])
Beispiel #6
0
    def test_commit(self):
        # Replace README.txt's contents, using binary mode so we know the
        # exact contents even on Windows, and therefore the MD5 checksum.
        readme_path = "%s/trunk/README.txt" % self.path
        fp = open(readme_path, "wb")
        fp.write("hello\n")
        fp.close()

        # Setup ra_ctx.
        ra.initialize()
        callbacks = ra.Callbacks()
        ra_ctx = ra.open2(REPOS_URL, callbacks, None, None)

        # Get commit editor.
        commit_info = [None]

        def commit_cb(_commit_info, pool):
            commit_info[0] = _commit_info

        (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, "log message", commit_cb, None, False)

        # Drive the commit.
        checksum = [None]

        def driver_cb(parent, path, pool):
            baton = editor.open_file(path, parent, -1, pool)
            adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool)
            (_, checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access, False, editor, baton, pool)
            return baton

        try:
            delta.path_driver(editor, edit_baton, -1, ["trunk/README.txt"], driver_cb)
            editor.close_edit(edit_baton)
        except:
            try:
                editor.abort_edit(edit_baton)
            except:
                # We already have an exception in progress, not much we can do
                # about this.
                pass
            raise
        (checksum,) = checksum
        (commit_info,) = commit_info

        # Assert the commit.
        self.assertEquals(binascii.b2a_hex(checksum), "b1946ac92492d2347c6235b4d2611184")
        self.assertEquals(commit_info.revision, 13)

        # Bump working copy state.
        wc.process_committed4(
            readme_path,
            wc.adm_retrieve(self.wc, os.path.dirname(readme_path)),
            False,
            commit_info.revision,
            commit_info.date,
            commit_info.author,
            None,
            False,
            False,
            checksum,
        )

        # Assert bumped state.
        entry = wc.entry(readme_path, self.wc, False)
        self.assertEquals(entry.revision, commit_info.revision)
        self.assertEquals(entry.schedule, wc.schedule_normal)
        self.assertEquals(entry.cmt_rev, commit_info.revision)
        self.assertEquals(entry.cmt_date, core.svn_time_from_cstring(commit_info.date))