Skip to content
Snippets Groups Projects
Commit 018805dc73db authored by Georges Racinet's avatar Georges Racinet
Browse files

Mercurial native mode: configuring through WSGI environment

This is part of heptapod#364.

Heptapod Workhorse will pass the `X-HEPTAPOD-HG-NATIVE` header
with the appropriate value, and we use it to set configuration
on the wished repository accordingly.

We could have made the `env` argument of the `load_repo()` method
optional (and hence hadn't needed to adapt existing tests), but
nothing would then prove that it wasn't forgotten, even with coverage
proving that `load_repo()` is indeed called (which it does).
parent edbb23858466
No related branches found
Tags heptapod-0.12.0rc6
1 merge request!34Triggering Mercurial native mode from environment variables and HTTP headers
Pipeline #12875 passed with warnings
......@@ -20,6 +20,8 @@
make_ui,
)
parametrize = pytest.mark.parametrize
def test_missing_repositories_root(tmpdir):
hgrc_path = tmpdir.join('heptapod.hgrc')
......@@ -120,7 +122,7 @@
hgs = make_hgserve(tmpdir)
hgs.ui.setconfig(b'heptapod', b'canary', b'yellow')
repo = hgs.load_repo(b'group/proj.hg')
repo = hgs.load_repo(b'group/proj.hg', {})
assert repo[0].description() == b'Foo'
repo.ui.setconfig(b'heptapod', b'canary', b'red')
......@@ -131,6 +133,6 @@
def test_load_repo_not_found(tmpdir):
hgs = make_hgserve(tmpdir)
with pytest.raises(ErrorResponse) as exc_info:
hgs.load_repo(b'does/not/exist')
hgs.load_repo(b'does/not/exist', {})
assert exc_info.value.args[0] == 'Not Found'
......@@ -135,2 +137,15 @@
assert exc_info.value.args[0] == 'Not Found'
@parametrize('header_value,expected', (('yes', True), ('no', False)))
def test_load_repo_native_header(tmpdir, header_value, expected):
wrapper = LocalRepoWrapper.init(
tmpdir.join('group').ensure(dir=True)
.join('proj.hg'))
wrapper.write_commit('foo', message='Foo')
hgs = make_hgserve(tmpdir)
repo = hgs.load_repo(b'group/proj.hg',
env={'HTTP_X_HEPTAPOD_HG_NATIVE': header_value})
ui = repo.ui
assert ui.configbool(b'heptapod', b'native') is expected
......@@ -135,7 +135,7 @@
# instances instead of every request.
gc.collect()
def load_repo(self, uri_path):
def load_repo(self, uri_path, env):
repo_path = os.path.join(self.repos_root, uri_path)
if not os.path.isdir(os.path.join(repo_path, b'.hg')):
# hg.repository() would raise a RepoError which is
......@@ -144,7 +144,17 @@
raise ErrorResponse(HTTP_NOT_FOUND, "Not Found")
logger.info("loading repo at %r", repo_path)
# ensure caller gets private copy of ui
return hg.repository(self.ui.copy(), repo_path)
repo = hg.repository(self.ui.copy(), repo_path)
# setting native mode, as a string so that standard hg boolean
# synonyms (yes, true, etc.) just work as usual.
# (this is likely to be assumed by developers in debugging sessions).
native = env.get('HTTP_X_HEPTAPOD_HG_NATIVE')
if native is not None:
repo.ui.setconfig(
b'heptapod', b'native', pycompat.sysbytes(native))
return repo
def _runwsgi(self, env, respond):
baseurl = self.ui.config(b'web', b'baseurl')
......@@ -166,7 +176,7 @@
res.headers[b'Content-Security-Policy'] = csp
try:
repo = self.load_repo(uri_path)
repo = self.load_repo(uri_path, env)
return hgweb_mod.hgweb(repo).run_wsgi(req, res)
except IOError as inst:
raise ErrorResponse(HTTP_SERVER_ERROR, inst.strerror)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment