Browse Source

Add check_wants.

Jelmer Vernooij 6 years ago
parent
commit
6cd85b535d
2 changed files with 43 additions and 0 deletions
  1. 23 0
      dulwich/client.py
  2. 20 0
      dulwich/tests/test_client.py

+ 23 - 0
dulwich/client.py

@@ -103,9 +103,19 @@ from dulwich.pack import (
     )
 from dulwich.refs import (
     read_info_refs,
+    ANNOTATED_TAG_SUFFIX,
     )
 
 
+class InvalidWants(Exception):
+    """Invalid wants."""
+
+    def __init__(self, wants):
+        Exception.__init__(
+            self,
+            "requested wants not in server provided refs: %r" % wants)
+
+
 def _fileno_can_read(fileno):
     """Check if a file descriptor is readable."""
     return len(select.select([fileno], [], [], 0)[0]) > 0
@@ -613,6 +623,19 @@ class GitClient(object):
                 pack_data(data)
 
 
+def check_wants(wants, refs):
+    """Check that a set of wants is valid.
+
+    :param wants: Set of object SHAs to fetch
+    :param refs: Refs dictionary to check against
+    """
+    missing = set(wants) - {
+            v for (k, v) in refs.items()
+            if not k.endswith(ANNOTATED_TAG_SUFFIX)}
+    if missing:
+        raise InvalidWants(missing)
+
+
 class TraditionalGitClient(GitClient):
     """Traditional Git client."""
 

+ 20 - 0
dulwich/tests/test_client.py

@@ -42,6 +42,7 @@ from dulwich import (
     client,
     )
 from dulwich.client import (
+    InvalidWants,
     LocalGitClient,
     TraditionalGitClient,
     TCPGitClient,
@@ -53,6 +54,7 @@ from dulwich.client import (
     SubprocessSSHVendor,
     PLinkSSHVendor,
     UpdateRefsError,
+    check_wants,
     default_urllib3_manager,
     get_transport_and_path,
     get_transport_and_path_from_url,
@@ -1178,3 +1180,21 @@ class RsyncUrlTests(TestCase):
 
     def test_path(self):
         self.assertRaises(ValueError, parse_rsync_url, '/path')
+
+
+class CheckWantsTests(TestCase):
+
+    def test_fine(self):
+        check_wants(['2f3dc7a53fb752a6961d3a56683df46d4d3bf262'],
+                    {'refs/heads/blah': '2f3dc7a53fb752a6961d3a56683df46d4d3bf262'})
+
+    def test_missing(self):
+        self.assertRaises(InvalidWants, check_wants,
+                ['2f3dc7a53fb752a6961d3a56683df46d4d3bf262'],
+                {'refs/heads/blah': '3f3dc7a53fb752a6961d3a56683df46d4d3bf262'})
+
+    def test_annotated(self):
+        self.assertRaises(InvalidWants, check_wants,
+                ['2f3dc7a53fb752a6961d3a56683df46d4d3bf262'],
+                {'refs/heads/blah': '3f3dc7a53fb752a6961d3a56683df46d4d3bf262',
+                 'refs/heads/blah^{}': '2f3dc7a53fb752a6961d3a56683df46d4d3bf262'})