##// END OF EJS Templates
hg: fixed code after version upgrade to 4.6.0 release
marcink -
r432:92b33b73 default
parent child
Show More
@@ -211,12 +211,12 class HgRemote(object):
211 if node['path'] == path:
211 if node['path'] == path:
212 return memfilectx(
212 return memfilectx(
213 _repo,
213 _repo,
214 changectx=memctx,
214 path=node['path'],
215 path=node['path'],
215 data=node['content'],
216 data=node['content'],
216 islink=False,
217 islink=False,
217 isexec=bool(node['mode'] & stat.S_IXUSR),
218 isexec=bool(node['mode'] & stat.S_IXUSR),
218 copied=False,
219 copied=False)
219 memctx=memctx)
220
220
221 raise exceptions.AbortException(
221 raise exceptions.AbortException(
222 "Given path haven't been marked as added, "
222 "Given path haven't been marked as added, "
@@ -454,9 +454,10 class HgRemote(object):
454 fctx = ctx.filectx(path)
454 fctx = ctx.filectx(path)
455
455
456 result = []
456 result = []
457 for i, (a_line, content) in enumerate(fctx.annotate()):
457 for i, annotate_obj in enumerate(fctx.annotate(), 1):
458 ln_no = i + 1
458 ln_no = i
459 sha = hex(a_line.fctx.node())
459 sha = hex(annotate_obj.fctx.node())
460 content = annotate_obj.text
460 result.append((ln_no, sha, content))
461 result.append((ln_no, sha, content))
461 return result
462 return result
462
463
@@ -533,10 +534,22 class HgRemote(object):
533
534
534 @reraise_safe_exceptions
535 @reraise_safe_exceptions
535 def lookup(self, wire, revision, both):
536 def lookup(self, wire, revision, both):
536 # TODO Paris: Ugly hack to "deserialize" long for msgpack
537
537 if isinstance(revision, float):
538 revision = long(revision)
539 repo = self._factory.repo(wire)
538 repo = self._factory.repo(wire)
539
540 if isinstance(revision, int):
541 # NOTE(marcink):
542 # since Mercurial doesn't support indexes properly
543 # we need to shift accordingly by one to get proper index, e.g
544 # repo[-1] => repo[-2]
545 # repo[0] => repo[-1]
546 # repo[1] => repo[2] we also never call repo[0] because
547 # it's actually second commit
548 if revision <= 0:
549 revision = revision + -1
550 else:
551 revision = revision + 1
552
540 try:
553 try:
541 ctx = repo[revision]
554 ctx = repo[revision]
542 except RepoLookupError:
555 except RepoLookupError:
@@ -36,15 +36,15 def patch_largefiles_capabilities():
36 lfproto = hgcompat.largefiles.proto
36 lfproto = hgcompat.largefiles.proto
37 wrapper = _dynamic_capabilities_wrapper(
37 wrapper = _dynamic_capabilities_wrapper(
38 lfproto, hgcompat.extensions.extensions)
38 lfproto, hgcompat.extensions.extensions)
39 lfproto.capabilities = wrapper
39 lfproto._capabilities = wrapper
40
40
41
41
42 def _dynamic_capabilities_wrapper(lfproto, extensions):
42 def _dynamic_capabilities_wrapper(lfproto, extensions):
43
43
44 wrapped_capabilities = lfproto.capabilities
44 wrapped_capabilities = lfproto._capabilities
45 logger = logging.getLogger('vcsserver.hg')
45 logger = logging.getLogger('vcsserver.hg')
46
46
47 def _dynamic_capabilities(repo, proto):
47 def _dynamic_capabilities(orig, repo, proto):
48 """
48 """
49 Adds dynamic behavior, so that the capability is only added if the
49 Adds dynamic behavior, so that the capability is only added if the
50 extension is enabled in the current ui object.
50 extension is enabled in the current ui object.
@@ -52,10 +52,10 def _dynamic_capabilities_wrapper(lfprot
52 if 'largefiles' in dict(extensions(repo.ui)):
52 if 'largefiles' in dict(extensions(repo.ui)):
53 logger.debug('Extension largefiles enabled')
53 logger.debug('Extension largefiles enabled')
54 calc_capabilities = wrapped_capabilities
54 calc_capabilities = wrapped_capabilities
55 return calc_capabilities(orig, repo, proto)
55 else:
56 else:
56 logger.debug('Extension largefiles disabled')
57 logger.debug('Extension largefiles disabled')
57 calc_capabilities = lfproto.capabilitiesorig
58 return orig(repo, proto)
58 return calc_capabilities(repo, proto)
59
59
60 return _dynamic_capabilities
60 return _dynamic_capabilities
61
61
@@ -164,7 +164,8 def _extras_from_ui(ui):
164 def _rev_range_hash(repo, node):
164 def _rev_range_hash(repo, node):
165
165
166 commits = []
166 commits = []
167 for rev in xrange(repo[node], len(repo)):
167 start = repo[node].rev()
168 for rev in xrange(start, len(repo)):
168 ctx = repo[rev]
169 ctx = repo[rev]
169 commit_id = mercurial.node.hex(ctx.node())
170 commit_id = mercurial.node.hex(ctx.node())
170 branch = ctx.branch()
171 branch = ctx.branch()
@@ -21,9 +21,9 import itertools
21
21
22 import mercurial
22 import mercurial
23 import mercurial.error
23 import mercurial.error
24 import mercurial.wireprotoserver
24 import mercurial.hgweb.common
25 import mercurial.hgweb.common
25 import mercurial.hgweb.hgweb_mod
26 import mercurial.hgweb.hgweb_mod
26 import mercurial.hgweb.protocol
27 import webob.exc
27 import webob.exc
28
28
29 from vcsserver import pygrack, exceptions, settings, git_lfs
29 from vcsserver import pygrack, exceptions, settings, git_lfs
@@ -73,14 +73,18 class HgWeb(mercurial.hgweb.hgweb_mod.hg
73
73
74 This may be called by multiple threads.
74 This may be called by multiple threads.
75 """
75 """
76 req = mercurial.hgweb.request.wsgirequest(environ, start_response)
76 from mercurial.hgweb import request as requestmod
77 gen = self.run_wsgi(req)
77 req = requestmod.parserequestfromenv(environ)
78 res = requestmod.wsgiresponse(req, start_response)
79 gen = self.run_wsgi(req, res)
78
80
79 first_chunk = None
81 first_chunk = None
80
82
81 try:
83 try:
82 data = gen.next()
84 data = gen.next()
83 def first_chunk(): yield data
85
86 def first_chunk():
87 yield data
84 except StopIteration:
88 except StopIteration:
85 pass
89 pass
86
90
@@ -88,17 +92,18 class HgWeb(mercurial.hgweb.hgweb_mod.hg
88 return itertools.chain(first_chunk(), gen)
92 return itertools.chain(first_chunk(), gen)
89 return gen
93 return gen
90
94
91 def _runwsgi(self, req, repo):
95 def _runwsgi(self, req, res, repo):
92 cmd = req.form.get('cmd', [''])[0]
93 if not mercurial.hgweb.protocol.iscmd(cmd):
94 req.respond(
95 mercurial.hgweb.common.ErrorResponse(
96 mercurial.hgweb.common.HTTP_BAD_REQUEST),
97 mercurial.hgweb.protocol.HGTYPE
98 )
99 return ['']
100
96
101 return super(HgWeb, self)._runwsgi(req, repo)
97 cmd = req.qsparams.get('cmd', '')
98 if not mercurial.wireprotoserver.iscmd(cmd):
99 # NOTE(marcink): for unsupported commands, we return bad request
100 # internally from HG
101 from mercurial.hgweb.common import statusmessage
102 res.status = statusmessage(mercurial.hgweb.common.HTTP_BAD_REQUEST)
103 res.setbodybytes('')
104 return res.sendresponse()
105
106 return super(HgWeb, self)._runwsgi(req, res, repo)
102
107
103
108
104 def make_hg_ui_from_config(repo_config):
109 def make_hg_ui_from_config(repo_config):
@@ -28,56 +28,45 def test_patch_largefiles_capabilities_a
28 patched_capabilities):
28 patched_capabilities):
29 lfproto = hgcompat.largefiles.proto
29 lfproto = hgcompat.largefiles.proto
30 hgpatches.patch_largefiles_capabilities()
30 hgpatches.patch_largefiles_capabilities()
31 assert lfproto.capabilities.func_name == '_dynamic_capabilities'
31 assert lfproto._capabilities.func_name == '_dynamic_capabilities'
32
32
33
33
34 def test_dynamic_capabilities_uses_original_function_if_not_enabled(
34 def test_dynamic_capabilities_uses_original_function_if_not_enabled(
35 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities):
35 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities,
36 orig_capabilities):
36 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
37 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
37 hgcompat.largefiles.proto, stub_extensions)
38 hgcompat.largefiles.proto, stub_extensions)
38
39
39 caps = dynamic_capabilities(stub_repo, stub_proto)
40 caps = dynamic_capabilities(orig_capabilities, stub_repo, stub_proto)
40
41
41 stub_extensions.assert_called_once_with(stub_ui)
42 stub_extensions.assert_called_once_with(stub_ui)
42 assert LARGEFILES_CAPABILITY not in caps
43 assert LARGEFILES_CAPABILITY not in caps
43
44
44
45
45 def test_dynamic_capabilities_uses_updated_capabilitiesorig(
46 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities):
47 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
48 hgcompat.largefiles.proto, stub_extensions)
49
50 # This happens when the extension is loaded for the first time, important
51 # to ensure that an updated function is correctly picked up.
52 hgcompat.largefiles.proto.capabilitiesorig = mock.Mock(
53 return_value='REPLACED')
54
55 caps = dynamic_capabilities(stub_repo, stub_proto)
56 assert 'REPLACED' == caps
57
58
59 def test_dynamic_capabilities_ignores_updated_capabilities(
46 def test_dynamic_capabilities_ignores_updated_capabilities(
60 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities):
47 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities,
48 orig_capabilities):
61 stub_extensions.return_value = [('largefiles', mock.Mock())]
49 stub_extensions.return_value = [('largefiles', mock.Mock())]
62 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
50 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
63 hgcompat.largefiles.proto, stub_extensions)
51 hgcompat.largefiles.proto, stub_extensions)
64
52
65 # This happens when the extension is loaded for the first time, important
53 # This happens when the extension is loaded for the first time, important
66 # to ensure that an updated function is correctly picked up.
54 # to ensure that an updated function is correctly picked up.
67 hgcompat.largefiles.proto.capabilities = mock.Mock(
55 hgcompat.largefiles.proto._capabilities = mock.Mock(
68 side_effect=Exception('Must not be called'))
56 side_effect=Exception('Must not be called'))
69
57
70 dynamic_capabilities(stub_repo, stub_proto)
58 dynamic_capabilities(orig_capabilities, stub_repo, stub_proto)
71
59
72
60
73 def test_dynamic_capabilities_uses_largefiles_if_enabled(
61 def test_dynamic_capabilities_uses_largefiles_if_enabled(
74 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities):
62 stub_repo, stub_proto, stub_ui, stub_extensions, patched_capabilities,
63 orig_capabilities):
75 stub_extensions.return_value = [('largefiles', mock.Mock())]
64 stub_extensions.return_value = [('largefiles', mock.Mock())]
76
65
77 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
66 dynamic_capabilities = hgpatches._dynamic_capabilities_wrapper(
78 hgcompat.largefiles.proto, stub_extensions)
67 hgcompat.largefiles.proto, stub_extensions)
79
68
80 caps = dynamic_capabilities(stub_repo, stub_proto)
69 caps = dynamic_capabilities(orig_capabilities, stub_repo, stub_proto)
81
70
82 stub_extensions.assert_called_once_with(stub_ui)
71 stub_extensions.assert_called_once_with(stub_ui)
83 assert LARGEFILES_CAPABILITY in caps
72 assert LARGEFILES_CAPABILITY in caps
@@ -94,15 +83,11 def patched_capabilities(request):
94 Patch in `capabilitiesorig` and restore both capability functions.
83 Patch in `capabilitiesorig` and restore both capability functions.
95 """
84 """
96 lfproto = hgcompat.largefiles.proto
85 lfproto = hgcompat.largefiles.proto
97 orig_capabilities = lfproto.capabilities
86 orig_capabilities = lfproto._capabilities
98 orig_capabilitiesorig = lfproto.capabilitiesorig
99
100 lfproto.capabilitiesorig = mock.Mock(return_value='ORIG')
101
87
102 @request.addfinalizer
88 @request.addfinalizer
103 def restore():
89 def restore():
104 lfproto.capabilities = orig_capabilities
90 lfproto._capabilities = orig_capabilities
105 lfproto.capabilitiesorig = orig_capabilitiesorig
106
91
107
92
108 @pytest.fixture
93 @pytest.fixture
@@ -120,6 +105,15 def stub_proto(stub_ui):
120
105
121
106
122 @pytest.fixture
107 @pytest.fixture
108 def orig_capabilities():
109 from mercurial.wireprotov1server import wireprotocaps
110
111 def _capabilities(repo, proto):
112 return wireprotocaps
113 return _capabilities
114
115
116 @pytest.fixture
123 def stub_ui():
117 def stub_ui():
124 return hgcompat.ui.ui()
118 return hgcompat.ui.ui()
125
119
General Comments 0
You need to be logged in to leave comments. Login now