예제 #1
0
    def decode_progress(self, bencoded_data: bytes) -> list:
        """Decodes string of bencoded progress output to list of updates

        Duplicates logic decoding logic from `SubProcessWidget.readStdout` and
        `SubProcessWidget.setProgress` which would be good to factor out.

        bdecode requires bencoded bytes and bencoded_data should BE bytes
        but doesn't appear to be.
        """
        updates = []
        for line in bencoded_data.split("\n"):
            if line.startswith(SUB_PROGRESS):
                # bdecode needs bytes, but we need to snip off the leading SUB_PROGRESS first
                n, transport_activity, task_info = bencode.bdecode(
                    line[len(SUB_PROGRESS):].encode('utf-8'))
                if n == 1000000 and not task_info:
                    task_message = "Finished!"
                else:
                    # task_info will be a list of byte-strings, so join and then decode
                    task_message = b" / ".join(task_info).decode("utf-8")
                # transport_activity will be bytes too...
                updates.append(
                    (n, transport_activity.decode('utf-8'), task_message))
        # Now we'll return a list of lines like: (0, '', 'Finding revisions /  0/2')
        return updates
예제 #2
0
 def test_bittorrent_b_encode_unicode(self):
     # Encoding should ALWAYS give bytes and expects bytes BUT our routines convert
     self.assertEqual(b"l7:versione",
                      bittorrent_b_encode_unicode(["version"]))
     # self.assertEqual(b"l3:add3:\u1234e", bittorrent_b_encode_unicode(["add", "\u1234"]))
     result = bittorrent_b_encode_unicode(["add", "\u1234"])
     self.assertEqual(b'l3:add3:\xe1\x88\xb4e', result)
     # Now check the '\u1234' comes back when it's a string...
     u = bencode.bdecode(result)
     self.assertIsInstance(u, list)
     self.assertEqual("\u1234", u[1].decode('utf-8'))
예제 #3
0
    def get_revision_paths(self, revnum):
        """See LogCache.get_revision_paths."""

        self.mutter("get-revision-paths %d", revnum)
        ret = {}
        try:
            db = bencode.bdecode(self.db[b"paths/%d" % revnum])
        except KeyError:
            raise KeyError("missing revision paths for %d" % revnum)
        for key, v in db.iteritems():
            try:
                (action, cp, cr, kind) = v
            except ValueError:
                (action, cp, cr) = v
                kind = NODE_UNKNOWN
            if cp == b"" and cr == -1:
                cp = None
            else:
                cp = cp.decode('utf-8')
            ret[key.decode('utf-8')] = (action, cp, cr, kind)
        return ret
예제 #4
0
class HgMappingv1(foreign.VcsMapping):
    """Class that maps between Bazaar and Mercurial semantics."""
    experimental = False
    revid_prefix = "hg-v1"

    def __init__(self):
        super(HgMappingv1, self).__init__(foreign_hg)

    def __str__(self):
        return self.revid_prefix

    @classmethod
    def revision_id_foreign_to_bzr(cls, revision_id):
        """See VcsMapping.revision_id_foreign_to_bzr."""
        if revision_id == mercurial.node.nullid:
            return _mod_revision.NULL_REVISION
        if len(revision_id) == 20:
            hexhgrevid = hex(revision_id)
        elif len(revision_id) == 40:
            hexhgrevid = revision_id
        else:
            raise AssertionError("Invalid hg id %r" % revision_id)
        return "%s:%s" % (cls.revid_prefix, hexhgrevid)

    @classmethod
    def revision_id_bzr_to_foreign(cls, revision_id):
        """See VcsMapping.revision_id_foreign_to_bzr."""
        if revision_id == _mod_revision.NULL_REVISION:
            return mercurial.node.nullid, cls()
        if not revision_id.startswith("%s:" % cls.revid_prefix):
            raise errors.InvalidRevisionId(revision_id, cls)
        return bin(revision_id[len(cls.revid_prefix) + 1:]), cls()

    @classmethod
    def generate_file_id(self, path):
        """Create a synthetic file_id for an hg file."""
        if isinstance(path, text_type):
            path = path.encode("utf-8")
        if path == "":
            return "TREE_ROOT"
        return "hg:" + escape_path(path)

    @classmethod
    def parse_file_id(self, fileid):
        """Parse a file id."""
        assert isinstance(fileid, str)
        if fileid == b'TREE_ROOT':
            return ""
        if not fileid.startswith(b"hg:"):
            raise ValueError('invalid file id %r' % fileid)
        return unescape_path(fileid[len("hg:"):])

    def export_revision(self, rev, lossy=True, fileids={}):
        user = rev.committer
        time = rev.timestamp
        timezone = -rev.timezone
        extra = {}
        manifest = None
        for name, value in rev.properties.iteritems():
            if name == 'manifest':
                manifest = mercurial.node.bin(value)
            elif name.startswith("hg:extra:"):
                extra[name[len("hg:extra:"):]] = base64.b64decode(value)
            elif name == 'rebase-of':
                try:
                    hgid, mapping = self.revision_id_bzr_to_foreign(value)
                except errors.InvalidRevisionId:
                    extra["bzr-revprop-" + name] = value.encode("utf-8")
                else:
                    assert len(hgid) == 20
                    extra['rebase_source'] = mercurial.node.hex(hgid)
            elif name == 'converted-from':
                if value.count('\n') <= 1:
                    continue
                extra['convert_revision'] = generate_convert_revision(
                    value.splitlines()[-2])
            else:
                assert not ":" in name
                extra["bzr-revprop-" + name] = value.encode("utf-8")
        if not lossy and not rev.revision_id.startswith(self.revid_prefix +
                                                        ":"):
            extra["bzr-mapping"] = str(self)
            extra["bzr-revision-id"] = rev.revision_id
            if len(rev.parent_ids) > 2:
                extra["bzr-extra-parents"] = " ".join(rev.parent_ids[2:])
            if fileids:
                extra["bzr-fileids"] = bencode.bencode(sorted(fileids.items()))
        desc = rev.message
        return (manifest, user, (time, timezone), desc, extra)

    def import_revision(self, revid, parent_ids, hgrevid, manifest, user,
                        (time, timezone), desc, extra):
        result = foreign.ForeignRevision(hgrevid, self, revid)
        result.parent_ids = parent_ids
        if type(desc) != unicode:
            raise AssertionError
        result.message = desc
        result.inventory_sha1 = ""
        result.timezone = -timezone
        result.timestamp = time
        if type(user) != unicode:
            raise AssertionError
        result.committer = user
        result.properties = {'manifest': mercurial.node.hex(manifest)}
        fileids = {}
        for name, value in extra.iteritems():
            if name.startswith("bzr-revprop-"):
                result.properties[name[len("bzr-revprop-")]] = value.decode(
                    "utf-8")
            elif name == "bzr-extra-parents":
                result.parent_ids += tuple(value.split(" "))
            elif name == "bzr-revision-id":
                result.revision_id = value
            elif name == "bzr-fileids":
                fileids = dict(bencode.bdecode(value))
            elif name == "convert_revision":
                result.properties['converted-from'] = convert_converted_from(
                    value)
            elif name == "rebase_source":
                result.properties[
                    'rebase-of'] = self.revision_id_foreign_to_bzr(value)
            elif name.startswith("bzr-"):
                trace.mutter("unknown bzr extra %s: %r", name, value)
            else:
                result.properties["hg:extra:" + name] = base64.b64encode(value)
        if len(hgrevid) == 40:
            hghexrevid = hgrevid
        else:
            hghexrevid = mercurial.node.hex(hgrevid)
        result.properties['converted-from'] = \
                result.properties.get('converted-from', '') + \
                "hg %s\n" % hghexrevid
        return result, fileids
예제 #5
0
    def get_revprops(self, revnum):
        """See LogCache.get_revprops."""

        self.mutter("get-revision-properties %d", revnum)
        ret = bencode.bdecode(self.db["revprops/%d" % revnum])
        return (ret[0], bool(ret[1]))