Add base class for traditional git clients.
authorJelmer Vernooij <jelmer@samba.org>
Sat, 3 Sep 2011 16:15:25 +0000 (18:15 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 3 Sep 2011 16:15:25 +0000 (18:15 +0200)
dulwich/client.py
dulwich/tests/test_client.py

index e247f85d5128d0869494be2c2c199b6f0c6d0510..c397dafdf94980394786a82a882ccbf9fb89b784 100644 (file)
@@ -77,6 +77,53 @@ class GitClient(object):
         if thin_packs:
             self._fetch_capabilities.append('thin-pack')
 
+    def send_pack(self, path, determine_wants, generate_pack_contents):
+        """Upload a pack to a remote repository.
+
+        :param path: Repository path
+        :param generate_pack_contents: Function that can return a sequence of the
+            shas of the objects to upload.
+
+        :raises SendPackError: if server rejects the pack data
+        :raises UpdateRefsError: if the server supports report-status
+                                 and rejects ref updates
+        """
+        raise NotImplementedError(self.send_pack)
+
+    def fetch(self, path, target, determine_wants=None, progress=None):
+        """Fetch into a target repository.
+
+        :param path: Path to fetch from
+        :param target: Target repository to fetch into
+        :param determine_wants: Optional function to determine what refs
+            to fetch
+        :param progress: Optional progress function
+        :return: remote refs
+        """
+        if determine_wants is None:
+            determine_wants = target.object_store.determine_wants_all
+        f, commit = target.object_store.add_pack()
+        try:
+            return self.fetch_pack(path, determine_wants,
+                target.get_graph_walker(), f.write, progress)
+        finally:
+            commit()
+
+    def fetch_pack(self, path, determine_wants, graph_walker, pack_data,
+                   progress):
+        """Retrieve a pack from a git smart server.
+
+        :param determine_wants: Callback that returns list of commits to fetch
+        :param graph_walker: Object with next() and ack().
+        :param pack_data: Callback called for each bit of data in the pack
+        :param progress: Callback for progress reports (strings)
+        """
+        raise NotImplementedError(self.fetch_pack)
+
+
+class TraditionalGitClient(GitClient):
+    """Traditional Git client."""
+
     def _connect(self, cmd, path):
         """Create a connection to the server.
 
@@ -142,7 +189,6 @@ class GitClient(object):
                                              if ref not in ok]),
                                   ref_status=ref_status)
 
-
     # TODO(durin42): add side-band-64k capability support here and advertise it
     def send_pack(self, path, determine_wants, generate_pack_contents):
         """Upload a pack to a remote repository.
@@ -194,25 +240,6 @@ class GitClient(object):
             raise SendPackError('Unexpected response %r' % data)
         return new_refs
 
-    def fetch(self, path, target, determine_wants=None, progress=None):
-        """Fetch into a target repository.
-
-        :param path: Path to fetch from
-        :param target: Target repository to fetch into
-        :param determine_wants: Optional function to determine what refs
-            to fetch
-        :param progress: Optional progress function
-        :return: remote refs
-        """
-        if determine_wants is None:
-            determine_wants = target.object_store.determine_wants_all
-        f, commit = target.object_store.add_pack()
-        try:
-            return self.fetch_pack(path, determine_wants,
-                target.get_graph_walker(), f.write, progress)
-        finally:
-            commit()
-
     def fetch_pack(self, path, determine_wants, graph_walker, pack_data,
                    progress):
         """Retrieve a pack from a git smart server.
@@ -268,7 +295,7 @@ class GitClient(object):
         return refs
 
 
-class TCPGitClient(GitClient):
+class TCPGitClient(TraditionalGitClient):
     """A Git Client that works over TCP directly (i.e. git://)."""
 
     def __init__(self, host, port=None, *args, **kwargs):
@@ -330,7 +357,7 @@ class SubprocessWrapper(object):
         self.proc.wait()
 
 
-class SubprocessGitClient(GitClient):
+class SubprocessGitClient(TraditionalGitClient):
     """Git client that talks to a server using a subprocess."""
 
     def __init__(self, *args, **kwargs):
@@ -367,7 +394,7 @@ class SSHVendor(object):
 get_ssh_vendor = SSHVendor
 
 
-class SSHGitClient(GitClient):
+class SSHGitClient(TraditionalGitClient):
 
     def __init__(self, host, port=None, username=None, *args, **kwargs):
         self.host = host
@@ -387,6 +414,47 @@ class SSHGitClient(GitClient):
                 con.can_read)
 
 
+class HttpGitClient(GitClient):
+
+    def __init__(self, host, port=None, username=None, force_dumb=False, *args, **kwargs):
+        self.host = host
+        self.port = port
+        self.force_dumb = force_dumb
+        self.username = username
+        GitClient.__init__(self, *args, **kwargs)
+
+    @classmethod
+    def from_url(cls, url):
+        parsed = urlparse.urlparse(url)
+        assert parsed.scheme == 'http'
+        return cls(parsed.hostname, port=parsed.port, username=parsed.port,
+                   password=parsed.password)
+
+    def send_pack(self, path, determine_wants, generate_pack_contents):
+        """Upload a pack to a remote repository.
+
+        :param path: Repository path
+        :param generate_pack_contents: Function that can return a sequence of the
+            shas of the objects to upload.
+
+        :raises SendPackError: if server rejects the pack data
+        :raises UpdateRefsError: if the server supports report-status
+                                 and rejects ref updates
+        """
+        raise NotImplementedError(self.send_pack)
+
+    def fetch_pack(self, path, determine_wants, graph_walker, pack_data,
+                   progress):
+        """Retrieve a pack from a git smart server.
+
+        :param determine_wants: Callback that returns list of commits to fetch
+        :param graph_walker: Object with next() and ack().
+        :param pack_data: Callback called for each bit of data in the pack
+        :param progress: Callback for progress reports (strings)
+        """
+        raise NotImplementedError(self.fetch_pack)
+
+
 def get_transport_and_path(uri):
     """Obtain a git client from a URI or path.
 
index 81fc52b0fd71cfc30c38422d89ab67246ea29bdb..e070a6b2461236fd5b4a1d56b23135fbbbb73f1b 100644 (file)
@@ -19,7 +19,7 @@
 from cStringIO import StringIO
 
 from dulwich.client import (
-    GitClient,
+    TraditionalGitClient,
     TCPGitClient,
     SubprocessGitClient,
     SSHGitClient,
@@ -34,13 +34,13 @@ from dulwich.protocol import (
     )
 
 
-class DummyClient(GitClient):
+class DummyClient(TraditionalGitClient):
 
     def __init__(self, can_read, read, write):
         self.can_read = can_read
         self.read = read
         self.write = write
-        GitClient.__init__(self)
+        TraditionalGitClient.__init__(self)
 
     def _connect(self, service, path):
         return Protocol(self.read, self.write), self.can_read