diff --git a/dulwich/objectspec.py b/dulwich/objectspec.py index 630ca122..f1500424 100644 --- a/dulwich/objectspec.py +++ b/dulwich/objectspec.py @@ -1,136 +1,136 @@ # objectspec.py -- Object specification # Copyright (C) 2014 Jelmer Vernooij # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License or (at your option) a later version of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. """Object specification.""" def to_bytes(text): if getattr(text, "encode", None) is not None: text = text.encode('ascii') return text def parse_object(repo, objectish): """Parse a string referring to an object. :param repo: A `Repo` object :param objectish: A string referring to an object :return: A git object :raise KeyError: If the object can not be found """ objectish = to_bytes(objectish) return repo[objectish] def parse_ref(container, refspec): """Parse a string referring to a reference. :param container: A RefsContainer object :param refspec: A string referring to a ref :return: A ref :raise KeyError: If the ref can not be found """ refspec = to_bytes(refspec) for ref in [refspec, b"refs/heads/" + refspec]: if ref in container: return ref else: raise KeyError(refspec) def parse_reftuple(lh_container, rh_container, refspec): """Parse a reftuple spec. :param lh_container: A RefsContainer object :param hh_container: A RefsContainer object :param refspec: A string :return: A tuple with left and right ref :raise KeyError: If one of the refs can not be found """ - if refspec.startswith("+"): + if refspec.startswith(b"+"): force = True refspec = refspec[1:] else: force = False refspec = to_bytes(refspec) if b":" in refspec: (lh, rh) = refspec.split(b":") else: lh = rh = refspec - if rh == "": + if rh == b"": lh = None else: lh = parse_ref(lh_container, lh) - if rh == "": + if rh == b"": rh = None else: try: rh = parse_ref(rh_container, rh) except KeyError: # TODO: check force? if not b"/" in rh: rh = b"refs/heads/" + rh return (lh, rh, force) def parse_reftuples(lh_container, rh_container, refspecs): """Parse a list of reftuple specs to a list of reftuples. :param lh_container: A RefsContainer object :param hh_container: A RefsContainer object :param refspecs: A list of refspecs or a string :return: A list of refs :raise KeyError: If one of the refs can not be found """ if not isinstance(refspecs, list): refspecs = [refspecs] ret = [] # TODO: Support * in refspecs for refspec in refspecs: ret.append(parse_reftuple(lh_container, rh_container, refspec)) return ret def parse_refs(container, refspecs): """Parse a list of refspecs to a list of refs. :param container: A RefsContainer object :param refspecs: A list of refspecs or a string :return: A list of refs :raise KeyError: If one of the refs can not be found """ # TODO: Support * in refspecs if not isinstance(refspecs, list): refspecs = [refspecs] ret = [] for refspec in refspecs: ret.append(parse_ref(container, refspec)) return ret def parse_commit_range(repo, committishs): """Parse a string referring to a range of commits. :param repo: A `Repo` object :param committishs: A string referring to a range of commits. :return: An iterator over `Commit` objects :raise KeyError: When the reference commits can not be found :raise ValueError: If the range can not be parsed """ committishs = to_bytes(committishs) return iter([repo[committishs]]) diff --git a/dulwich/tests/test_objectspec.py b/dulwich/tests/test_objectspec.py index 13e063ab..3949d842 100644 --- a/dulwich/tests/test_objectspec.py +++ b/dulwich/tests/test_objectspec.py @@ -1,139 +1,139 @@ # test_objectspec.py -- tests for objectspec.py # Copyright (C) 2014 Jelmer Vernooij # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License or (at your option) any later version of # the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. """Tests for revision spec parsing.""" # TODO: Round-trip parse-serialize-parse and serialize-parse-serialize tests. from dulwich.objects import ( Blob, ) from dulwich.objectspec import ( parse_object, parse_commit_range, parse_ref, parse_refs, parse_reftuple, parse_reftuples, ) from dulwich.repo import MemoryRepo from dulwich.tests import ( TestCase, ) from dulwich.tests.utils import ( build_commit_graph, ) class ParseObjectTests(TestCase): """Test parse_object.""" def test_nonexistent(self): r = MemoryRepo() self.assertRaises(KeyError, parse_object, r, "thisdoesnotexist") def test_blob_by_sha(self): r = MemoryRepo() b = Blob.from_string(b"Blah") r.object_store.add_object(b) self.assertEqual(b, parse_object(r, b.id)) class ParseCommitRangeTests(TestCase): """Test parse_commit_range.""" def test_nonexistent(self): r = MemoryRepo() self.assertRaises(KeyError, parse_commit_range, r, "thisdoesnotexist") def test_commit_by_sha(self): r = MemoryRepo() c1, c2, c3 = build_commit_graph(r.object_store, [[1], [2, 1], [3, 1, 2]]) self.assertEqual([c1], list(parse_commit_range(r, c1.id))) class ParseRefTests(TestCase): def test_nonexistent(self): r = {} - self.assertRaises(KeyError, parse_ref, r, "thisdoesnotexist") + self.assertRaises(KeyError, parse_ref, r, b"thisdoesnotexist") def test_head(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals("refs/heads/foo", parse_ref(r, "foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals(b"refs/heads/foo", parse_ref(r, b"foo")) def test_full(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals("refs/heads/foo", parse_ref(r, "refs/heads/foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals(b"refs/heads/foo", parse_ref(r, b"refs/heads/foo")) class ParseRefsTests(TestCase): def test_nonexistent(self): r = {} - self.assertRaises(KeyError, parse_refs, r, ["thisdoesnotexist"]) + self.assertRaises(KeyError, parse_refs, r, [b"thisdoesnotexist"]) def test_head(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals(["refs/heads/foo"], parse_refs(r, ["foo"])) + r = {b"refs/heads/foo": "bla"} + self.assertEquals([b"refs/heads/foo"], parse_refs(r, [b"foo"])) def test_full(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals(["refs/heads/foo"], parse_refs(r, "refs/heads/foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals([b"refs/heads/foo"], parse_refs(r, b"refs/heads/foo")) class ParseReftupleTests(TestCase): def test_nonexistent(self): r = {} - self.assertRaises(KeyError, parse_reftuple, r, r, "thisdoesnotexist") + self.assertRaises(KeyError, parse_reftuple, r, r, b"thisdoesnotexist") def test_head(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals(("refs/heads/foo", "refs/heads/foo", False), - parse_reftuple(r, r, "foo")) - self.assertEquals(("refs/heads/foo", "refs/heads/foo", True), - parse_reftuple(r, r, "+foo")) - self.assertEquals(("refs/heads/foo", "refs/heads/foo", True), - parse_reftuple(r, {}, "+foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals((b"refs/heads/foo", b"refs/heads/foo", False), + parse_reftuple(r, r, b"foo")) + self.assertEquals((b"refs/heads/foo", b"refs/heads/foo", True), + parse_reftuple(r, r, b"+foo")) + self.assertEquals((b"refs/heads/foo", b"refs/heads/foo", True), + parse_reftuple(r, {}, b"+foo")) def test_full(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals(("refs/heads/foo", "refs/heads/foo", False), - parse_reftuple(r, r, "refs/heads/foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals((b"refs/heads/foo", b"refs/heads/foo", False), + parse_reftuple(r, r, b"refs/heads/foo")) class ParseReftuplesTests(TestCase): def test_nonexistent(self): r = {} self.assertRaises(KeyError, parse_reftuples, r, r, - ["thisdoesnotexist"]) + [b"thisdoesnotexist"]) def test_head(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals([("refs/heads/foo", "refs/heads/foo", False)], - parse_reftuples(r, r, ["foo"])) + r = {b"refs/heads/foo": "bla"} + self.assertEquals([(b"refs/heads/foo", b"refs/heads/foo", False)], + parse_reftuples(r, r, [b"foo"])) def test_full(self): - r = {"refs/heads/foo": "bla"} - self.assertEquals([("refs/heads/foo", "refs/heads/foo", False)], - parse_reftuples(r, r, "refs/heads/foo")) + r = {b"refs/heads/foo": "bla"} + self.assertEquals([(b"refs/heads/foo", b"refs/heads/foo", False)], + parse_reftuples(r, r, b"refs/heads/foo"))