Skip to content

Commit

Permalink
Working pass at an HTTP server, only dumb at the moment
Browse files Browse the repository at this point in the history
Change-Id: I92c883b2274252ad83bc044f87fc8608b006b6ab
  • Loading branch information
dborowitz committed Feb 9, 2010
1 parent a93f44f commit 1f35a47
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 5 deletions.
37 changes: 37 additions & 0 deletions bin/dul-web
@@ -0,0 +1,37 @@
#!/usr/bin/python
# dul-web - HTTP-based git server
# Copyright (C) 2010 David Borowitz <dborowitz@google.com>
#
# 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.
#
# 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.

import os
import sys
from dulwich.repo import Repo
from dulwich.server import GitBackend
from dulwich.web import HTTPGitApplication
from wsgiref.simple_server import make_server

if __name__ == "__main__":
if len(sys.argv) > 1:
gitdir = sys.argv[1]
else:
gitdir = os.getcwd()

backend = GitBackend(Repo(gitdir))
app = HTTPGitApplication(backend)
# TODO: allow serving on other ports via command-line flag
server = make_server('', 8000, app)
server.serve_forever()
13 changes: 10 additions & 3 deletions dulwich/object_store.py
Expand Up @@ -20,6 +20,7 @@
"""Git object store interfaces and implementation."""


import errno
import itertools
import os
import stat
Expand Down Expand Up @@ -269,15 +270,21 @@ def __iter__(self):
def packs(self):
"""List with pack objects."""
if self._pack_cache is None:
self._pack_cache = list(self._load_packs())
self._pack_cache = self._load_packs()
return self._pack_cache

def _load_packs(self):
if not os.path.exists(self.pack_dir):
return
return []
pack_files = []
for name in os.listdir(self.pack_dir):
# TODO: verify that idx exists first
if name.startswith("pack-") and name.endswith(".pack"):
yield Pack(os.path.join(self.pack_dir, name[:-len(".pack")]))
filename = os.path.join(self.pack_dir, name)
pack_files.append((os.stat(filename).st_mtime, filename))
pack_files.sort(reverse=True)
suffix_len = len(".pack")
return [Pack(f[:-suffix_len]) for _, f in pack_files]

def _add_known_pack(self, path):
"""Add a newly appeared pack to the cache by path.
Expand Down
29 changes: 29 additions & 0 deletions dulwich/repo.py
Expand Up @@ -522,6 +522,18 @@ def __init__(self, object_store, refs):
self.object_store = object_store
self.refs = refs

def get_named_file(self, path):
"""Get a file from the control dir with a specific name.
Although the filename should be interpreted as a filename relative to
the control dir in a disk-baked Repo, the object returned need not be
pointing to a file in that location.
:param path: The path to the file, relative to the control dir.
:return: An open file object, or None if the file does not exist.
"""
raise NotImplementedError(self.get_named_file)

def fetch(self, target, determine_wants=None, progress=None):
"""Fetch objects into another repository.
Expand Down Expand Up @@ -685,6 +697,23 @@ def controldir(self):
"""Return the path of the control directory."""
return self._controldir

def get_named_file(self, path):
"""Get a file from the control dir with a specific name.
Although the filename should be interpreted as a filename relative to
the control dir in a disk-baked Repo, the object returned need not be
pointing to a file in that location.
:param path: The path to the file, relative to the control dir.
:return: An open file object, or None if the file does not exist.
"""
try:
return open(os.path.join(self.controldir(), path.lstrip('/')), 'rb')
except (IOError, OSError), e:
if e.errno == errno.ENOENT:
return None
raise

def index_path(self):
"""Return path to the index file."""
return os.path.join(self.controldir(), INDEX_FILENAME)
Expand Down
11 changes: 10 additions & 1 deletion dulwich/server.py
Expand Up @@ -120,10 +120,13 @@ def capabilities(self):
class UploadPackHandler(Handler):
"""Protocol handler for uploading a pack to the server."""

def __init__(self, backend, read, write):
def __init__(self, backend, read, write,
stateless_rpc=False, advertise_refs=False):
Handler.__init__(self, backend, read, write)
self._client_capabilities = None
self._graph_walker = None
self._stateless_rpc = stateless_rpc
self._advertise_refs = advertise_refs

def default_capabilities(self):
return ("multi_ack", "side-band-64k", "thin-pack", "ofs-delta")
Expand Down Expand Up @@ -402,6 +405,12 @@ def next(self):
class ReceivePackHandler(Handler):
"""Protocol handler for downloading a pack to the client."""

def __init__(self, backend, read, write,
stateless_rpc=False, advertise_refs=False):
Handler.__init__(self, backend, read, write)
self._stateless_rpc = stateless_rpc
self._advertise_refs = advertise_refs

def default_capabilities(self):
return ("report-status", "delete-refs")

Expand Down

0 comments on commit 1f35a47

Please sign in to comment.