Mercurial > kallithea
annotate rhodecode/lib/middleware/pygrack.py @ 2382:034e4fe1ebb2 beta
changed dulwich git interface to gitweb + subprocessio
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 04 Jun 2012 02:56:09 +0200 |
parents | |
children | 378b0247e938 |
rev | line source |
---|---|
2382
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
1 import os |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
2 import socket |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
3 import logging |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
4 import subprocess |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
5 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
6 from webob import Request, Response, exc |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
7 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
8 from rhodecode.lib import subprocessio |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
9 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
10 log = logging.getLogger(__name__) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
11 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
12 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
13 class FileWrapper(object): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
14 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
15 def __init__(self, fd, content_length): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
16 self.fd = fd |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
17 self.content_length = content_length |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
18 self.remain = content_length |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
19 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
20 def read(self, size): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
21 if size <= self.remain: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
22 try: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
23 data = self.fd.read(size) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
24 except socket.error: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
25 raise IOError(self) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
26 self.remain -= size |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
27 elif self.remain: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
28 data = self.fd.read(self.remain) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
29 self.remain = 0 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
30 else: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
31 data = None |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
32 return data |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
33 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
34 def __repr__(self): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
35 return '<FileWrapper %s len: %s, read: %s>' % ( |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
36 self.fd, self.content_length, self.content_length - self.remain |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
37 ) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
38 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
39 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
40 class GitRepository(object): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
41 git_folder_signature = set(['config', 'head', 'info', 'objects', 'refs']) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
42 commands = ['git-upload-pack', 'git-receive-pack'] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
43 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
44 def __init__(self, repo_name, content_path): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
45 files = set([f.lower() for f in os.listdir(content_path)]) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
46 if not (self.git_folder_signature.intersection(files) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
47 == self.git_folder_signature): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
48 raise OSError('%s missing git signature' % content_path) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
49 self.content_path = content_path |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
50 self.valid_accepts = ['application/x-%s-result' % |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
51 c for c in self.commands] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
52 self.repo_name = repo_name |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
53 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
54 def _get_fixedpath(self, path): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
55 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
56 Small fix for repo_path |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
57 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
58 :param path: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
59 :type path: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
60 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
61 return path.split(self.repo_name, 1)[-1].strip('/') |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
62 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
63 def inforefs(self, request, environ): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
64 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
65 WSGI Response producer for HTTP GET Git Smart |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
66 HTTP /info/refs request. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
67 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
68 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
69 git_command = request.GET['service'] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
70 if git_command not in self.commands: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
71 log.debug('command %s not allowed' % git_command) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
72 return exc.HTTPMethodNotAllowed() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
73 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
74 # note to self: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
75 # please, resist the urge to add '\n' to git capture and increment |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
76 # line count by 1. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
77 # The code in Git client not only does NOT need '\n', but actually |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
78 # blows up if you sprinkle "flush" (0000) as "0001\n". |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
79 # It reads binary, per number of bytes specified. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
80 # if you do add '\n' as part of data, count it. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
81 smart_server_advert = '# service=%s' % git_command |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
82 try: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
83 out = subprocessio.SubprocessIOChunker( |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
84 r'git %s --stateless-rpc --advertise-refs "%s"' % ( |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
85 git_command[4:], self.content_path), |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
86 starting_values=[ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
87 str(hex(len(smart_server_advert) + 4)[2:] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
88 .rjust(4, '0') + smart_server_advert + '0000') |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
89 ] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
90 ) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
91 except EnvironmentError, e: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
92 log.exception(e) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
93 raise exc.HTTPExpectationFailed() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
94 resp = Response() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
95 resp.content_type = 'application/x-%s-advertisement' % str(git_command) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
96 resp.app_iter = out |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
97 return resp |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
98 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
99 def backend(self, request, environ): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
100 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
101 WSGI Response producer for HTTP POST Git Smart HTTP requests. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
102 Reads commands and data from HTTP POST's body. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
103 returns an iterator obj with contents of git command's |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
104 response to stdout |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
105 """ |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
106 git_command = self._get_fixedpath(request.path_info) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
107 if git_command not in self.commands: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
108 log.debug('command %s not allowed' % git_command) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
109 return exc.HTTPMethodNotAllowed() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
110 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
111 if 'CONTENT_LENGTH' in environ: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
112 inputstream = FileWrapper(environ['wsgi.input'], |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
113 request.content_length) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
114 else: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
115 inputstream = environ['wsgi.input'] |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
116 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
117 try: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
118 out = subprocessio.SubprocessIOChunker( |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
119 r'git %s --stateless-rpc "%s"' % (git_command[4:], |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
120 self.content_path), |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
121 inputstream=inputstream |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
122 ) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
123 except EnvironmentError, e: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
124 log.exception(e) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
125 raise exc.HTTPExpectationFailed() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
126 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
127 if git_command in [u'git-receive-pack']: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
128 # updating refs manually after each push. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
129 # Needed for pre-1.7.0.4 git clients using regular HTTP mode. |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
130 subprocess.call(u'git --git-dir "%s" ' |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
131 'update-server-info' % self.content_path, |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
132 shell=True) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
133 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
134 resp = Response() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
135 resp.content_type = 'application/x-%s-result' % git_command.encode('utf8') |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
136 resp.app_iter = out |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
137 return resp |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
138 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
139 def __call__(self, environ, start_response): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
140 request = Request(environ) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
141 _path = self._get_fixedpath(request.path_info) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
142 if _path.startswith('info/refs'): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
143 app = self.inforefs |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
144 elif [a for a in self.valid_accepts if a in request.accept]: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
145 app = self.backend |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
146 try: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
147 resp = app(request, environ) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
148 except exc.HTTPException, e: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
149 resp = e |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
150 log.exception(e) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
151 except Exception, e: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
152 log.exception(e) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
153 resp = exc.HTTPInternalServerError() |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
154 return resp(environ, start_response) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
155 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
156 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
157 class GitDirectory(object): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
158 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
159 def __init__(self, repo_root, repo_name): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
160 repo_location = os.path.join(repo_root, repo_name) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
161 if not os.path.isdir(repo_location): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
162 raise OSError(repo_location) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
163 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
164 self.content_path = repo_location |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
165 self.repo_name = repo_name |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
166 self.repo_location = repo_location |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
167 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
168 def __call__(self, environ, start_response): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
169 content_path = self.content_path |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
170 try: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
171 app = GitRepository(self.repo_name, content_path) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
172 except (AssertionError, OSError): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
173 if os.path.isdir(os.path.join(content_path, '.git')): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
174 app = GitRepository(os.path.join(content_path, '.git')) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
175 else: |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
176 return exc.HTTPNotFound()(environ, start_response) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
177 return app(environ, start_response) |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
178 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
179 |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
180 def make_wsgi_app(repo_name, repo_root): |
034e4fe1ebb2
changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
181 return GitDirectory(repo_root, repo_name) |