##// END OF EJS Templates
statichttprepo: do not try to write caches...
Pierre-Yves David -
r29738:c1696430 default
parent child Browse files
Show More
@@ -1,187 +1,190 b''
1 1 # statichttprepo.py - simple http repository class for mercurial
2 2 #
3 3 # This provides read-only repo access to repositories exported via static http
4 4 #
5 5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10 from __future__ import absolute_import
11 11
12 12 import errno
13 13 import os
14 14
15 15 from .i18n import _
16 16 from . import (
17 17 byterange,
18 18 changelog,
19 19 error,
20 20 localrepo,
21 21 manifest,
22 22 namespaces,
23 23 scmutil,
24 24 store,
25 25 url,
26 26 util,
27 27 )
28 28
29 29 urlerr = util.urlerr
30 30 urlreq = util.urlreq
31 31
32 32 class httprangereader(object):
33 33 def __init__(self, url, opener):
34 34 # we assume opener has HTTPRangeHandler
35 35 self.url = url
36 36 self.pos = 0
37 37 self.opener = opener
38 38 self.name = url
39 39
40 40 def __enter__(self):
41 41 return self
42 42
43 43 def __exit__(self, exc_type, exc_value, traceback):
44 44 self.close()
45 45
46 46 def seek(self, pos):
47 47 self.pos = pos
48 48 def read(self, bytes=None):
49 49 req = urlreq.request(self.url)
50 50 end = ''
51 51 if bytes:
52 52 end = self.pos + bytes - 1
53 53 if self.pos or end:
54 54 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
55 55
56 56 try:
57 57 f = self.opener.open(req)
58 58 data = f.read()
59 59 code = f.code
60 60 except urlerr.httperror as inst:
61 61 num = inst.code == 404 and errno.ENOENT or None
62 62 raise IOError(num, inst)
63 63 except urlerr.urlerror as inst:
64 64 raise IOError(None, inst.reason[1])
65 65
66 66 if code == 200:
67 67 # HTTPRangeHandler does nothing if remote does not support
68 68 # Range headers and returns the full entity. Let's slice it.
69 69 if bytes:
70 70 data = data[self.pos:self.pos + bytes]
71 71 else:
72 72 data = data[self.pos:]
73 73 elif bytes:
74 74 data = data[:bytes]
75 75 self.pos += len(data)
76 76 return data
77 77 def readlines(self):
78 78 return self.read().splitlines(True)
79 79 def __iter__(self):
80 80 return iter(self.readlines())
81 81 def close(self):
82 82 pass
83 83
84 84 def build_opener(ui, authinfo):
85 85 # urllib cannot handle URLs with embedded user or passwd
86 86 urlopener = url.opener(ui, authinfo)
87 87 urlopener.add_handler(byterange.HTTPRangeHandler())
88 88
89 89 class statichttpvfs(scmutil.abstractvfs):
90 90 def __init__(self, base):
91 91 self.base = base
92 92
93 93 def __call__(self, path, mode='r', *args, **kw):
94 94 if mode not in ('r', 'rb'):
95 95 raise IOError('Permission denied')
96 96 f = "/".join((self.base, urlreq.quote(path)))
97 97 return httprangereader(f, urlopener)
98 98
99 99 def join(self, path):
100 100 if path:
101 101 return os.path.join(self.base, path)
102 102 else:
103 103 return self.base
104 104
105 105 return statichttpvfs
106 106
107 107 class statichttppeer(localrepo.localpeer):
108 108 def local(self):
109 109 return None
110 110 def canpush(self):
111 111 return False
112 112
113 113 class statichttprepository(localrepo.localrepository):
114 114 supported = localrepo.localrepository._basesupported
115 115
116 116 def __init__(self, ui, path):
117 117 self._url = path
118 118 self.ui = ui
119 119
120 120 self.root = path
121 121 u = util.url(path.rstrip('/') + "/.hg")
122 122 self.path, authinfo = u.authinfo()
123 123
124 124 opener = build_opener(ui, authinfo)
125 125 self.opener = opener(self.path)
126 126 self.vfs = self.opener
127 127 self._phasedefaults = []
128 128
129 129 self.names = namespaces.namespaces()
130 130
131 131 try:
132 132 requirements = scmutil.readrequires(self.vfs, self.supported)
133 133 except IOError as inst:
134 134 if inst.errno != errno.ENOENT:
135 135 raise
136 136 requirements = set()
137 137
138 138 # check if it is a non-empty old-style repository
139 139 try:
140 140 fp = self.vfs("00changelog.i")
141 141 fp.read(1)
142 142 fp.close()
143 143 except IOError as inst:
144 144 if inst.errno != errno.ENOENT:
145 145 raise
146 146 # we do not care about empty old-style repositories here
147 147 msg = _("'%s' does not appear to be an hg repository") % path
148 148 raise error.RepoError(msg)
149 149
150 150 # setup store
151 151 self.store = store.store(requirements, self.path, opener)
152 152 self.spath = self.store.path
153 153 self.svfs = self.store.opener
154 154 self.sjoin = self.store.join
155 155 self._filecache = {}
156 156 self.requirements = requirements
157 157
158 158 self.manifest = manifest.manifest(self.svfs)
159 159 self.changelog = changelog.changelog(self.svfs)
160 160 self._tags = None
161 161 self.nodetagscache = None
162 162 self._branchcaches = {}
163 163 self._revbranchcache = None
164 164 self.encodepats = None
165 165 self.decodepats = None
166 166 self._transref = None
167 167
168 168 def _restrictcapabilities(self, caps):
169 169 caps = super(statichttprepository, self)._restrictcapabilities(caps)
170 170 return caps.difference(["pushkey"])
171 171
172 172 def url(self):
173 173 return self._url
174 174
175 175 def local(self):
176 176 return False
177 177
178 178 def peer(self):
179 179 return statichttppeer(self)
180 180
181 181 def lock(self, wait=True):
182 182 raise error.Abort(_('cannot lock static-http repository'))
183 183
184 def _writecaches(self):
185 pass # statichttprepository are read only
186
184 187 def instance(ui, path, create):
185 188 if create:
186 189 raise error.Abort(_('cannot create new static-http repository'))
187 190 return statichttprepository(ui, path[7:])
General Comments 0
You need to be logged in to leave comments. Login now