Explorar o código

Simplify tag parsing.

Jelmer Vernooij %!s(int64=16) %!d(string=hai) anos
pai
achega
9b9d318902
Modificáronse 2 ficheiros con 57 adicións e 63 borrados
  1. 15 63
      dulwich/objects.py
  2. 42 0
      dulwich/tests/test_objects.py

+ 15 - 63
dulwich/objects.py

@@ -284,69 +284,21 @@ class Tag(ShaFile):
 
     def _parse_text(self):
         """Grab the metadata attached to the tag"""
-        text = self._text
-        count = 0
-        assert text.startswith(OBJECT_ID), "Invalid tag object, " \
-            "must start with %s" % OBJECT_ID
-        count += len(OBJECT_ID)
-        assert text[count] == ' ', "Invalid tag object, " \
-            "%s must be followed by space not %s" % (OBJECT_ID, text[count])
-        count += 1
-        self._object_sha = text[count:count+40]
-        count += 40
-        assert text[count] == '\n', "Invalid tag object, " \
-            "%s sha must be followed by newline" % OBJECT_ID
-        count += 1
-        assert text[count:].startswith(TYPE_ID), "Invalid tag object, " \
-            "%s sha must be followed by %s" % (OBJECT_ID, TYPE_ID)
-        count += len(TYPE_ID)
-        assert text[count] == ' ', "Invalid tag object, " \
-            "%s must be followed by space not %s" % (TAG_ID, text[count])
-        count += 1
-        self._object_type = ""
-        while text[count] != '\n':
-            self._object_type += text[count]
-            count += 1
-        count += 1
-        assert self._object_type in (COMMIT_ID, BLOB_ID, TREE_ID, TAG_ID), "Invalid tag object, " \
-            "unexpected object type %s" % self._object_type
-        self._object_type = type_map[self._object_type]
-
-        assert text[count:].startswith(TAG_ID), "Invalid tag object, " \
-            "object type must be followed by %s" % (TAG_ID)
-        count += len(TAG_ID)
-        assert text[count] == ' ', "Invalid tag object, " \
-            "%s must be followed by space not %s" % (TAG_ID, text[count])
-        count += 1
-        self._name = ""
-        while text[count] != '\n':
-            self._name += text[count]
-            count += 1
-        count += 1
-
-        assert text[count:].startswith(TAGGER_ID), "Invalid tag object, " \
-            "%s must be followed by %s" % (TAG_ID, TAGGER_ID)
-        count += len(TAGGER_ID)
-        assert text[count] == ' ', "Invalid tag object, " \
-            "%s must be followed by space not %s" % (TAGGER_ID, text[count])
-        count += 1
-        self._tagger = ""
-        while text[count] != '>':
-            assert text[count] != '\n', "Malformed tagger information"
-            self._tagger += text[count]
-            count += 1
-        self._tagger += text[count]
-        count += 1
-        assert text[count] == ' ', "Invalid tag object, " \
-            "tagger information must be followed by space not %s" % text[count]
-        count += 1
-        self._tag_time = int(text[count:count+10])
-        while text[count] != '\n':
-            count += 1
-        count += 1
-        assert text[count] == '\n', "There must be a new line after the headers"
-        count += 1
-        self._message = text[count:]
+        f = StringIO(self._text)
+        for l in f:
+            l = l.rstrip("\n")
+            if l == "":
+                break # empty line indicates end of headers
+            (field, value) = l.split(" ", 1)
+            if field == OBJECT_ID:
+                self._object_sha = value
+            elif field == TYPE_ID:
+                self._object_type = type_map[value]
+            elif field == TAG_ID:
+                self._name = value
+            elif field == TAGGER_ID:
+                self._tagger = value
+        self._message = f.read()
         self._needs_parsing = False
 
     def get_object(self):

+ 42 - 0
dulwich/tests/test_objects.py

@@ -203,3 +203,45 @@ class TreeSerializationTests(unittest.TestCase):
         x["a"] = (stat.S_IFDIR, "d80c186a03f423a81b39df39dc87fd269736ca86")
         x["a/c"] = (stat.S_IFDIR, "d80c186a03f423a81b39df39dc87fd269736ca86")
         self.assertEquals(["a.c", "a", "a/c"], [p[0] for p in x.iteritems()])
+
+
+
+class TagParseTests(unittest.TestCase):
+
+    def test_parse_simple(self):
+        x = Tag()
+        x.set_raw_string("""object a38d6181ff27824c79fc7df825164a212eff6a3f
+type commit
+tag v2.6.22-rc7
+tagger Linus Torvalds <torvalds@woody.linux-foundation.org> Sun Jul 1 12:54:34 2007 -0700
+
+Linux 2.6.22-rc7
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.7 (GNU/Linux)
+
+iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
+OK2XeQOiEeXtT76rV4t2WR4=
+=ivrA
+-----END PGP SIGNATURE-----
+""")
+        self.assertEquals("Linus Torvalds <torvalds@woody.linux-foundation.org>", x.tagger)
+        self.assertEquals("v2.6.22-rc7", tag.name)
+
+    def test_parse_no_tagger(self):
+        x = Tag()
+        x.set_raw_string("""object a38d6181ff27824c79fc7df825164a212eff6a3f
+type commit
+tag v2.6.22-rc7
+
+Linux 2.6.22-rc7
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.7 (GNU/Linux)
+
+iD8DBQBGiAaAF3YsRnbiHLsRAitMAKCiLboJkQECM/jpYsY3WPfvUgLXkACgg3ql
+OK2XeQOiEeXtT76rV4t2WR4=
+=ivrA
+-----END PGP SIGNATURE-----
+""")
+        self.assertEquals(None, x.tagger)
+        self.assertEquals("v2.6.22-rc7", tag.name)
+