Commit 47225a35 authored by Sushil Khanchi's avatar Sushil Khanchi 🐨
Browse files

repository_service: implement CreateRepository

parent 288dc6486710
......@@ -11,6 +11,8 @@ import tempfile
from mercurial import (
archival,
scmutil,
hg,
vfs as vfsmod,
)
from heptapod.gitlab.branch import gitlab_branch_from_ref
......@@ -22,6 +24,7 @@ from hgext3rd.heptapod.keep_around import (
)
from ..errors import (
internal_error,
invalid_argument,
not_implemented,
)
......@@ -250,5 +253,29 @@ class RepositoryServiceServicer(RepositoryServiceServicer, HGitalyServicer):
def CreateRepository(self, request: CreateRepositoryRequest,
context) -> CreateRepositoryResponse:
return not_implemented(context, CreateRepositoryResponse,
issue=58)
try:
repo_path = self.repo_disk_path(request.repository, context)
except KeyError:
storage_name = request.repository.storage_name
msg = (
'locate repository: no such storage: "%s"' % storage_name
)
return invalid_argument(context, CreateRepositoryResponse,
message=msg)
try:
# check if already an Hg repository (logic similar to upstream Hg)
wdir_vfs = vfsmod.vfs(repo_path, expandpath=True, realpath=True)
hgvfs = vfsmod.vfs(wdir_vfs.join(b'.hg'))
if hgvfs.exists():
# To match with Gitaly/Git behavior, if repository already
# initialized we should not return any error
# (although `hg init` would throw an error)
return CreateRepositoryResponse()
hg.peer(self.ui, opts={}, path=repo_path, create=True)
except Exception as exc:
msg = (
'create directories: "%s": error: %s'
) % (repo_path, repr(exc.args))
return internal_error(context, CreateRepositoryResponse,
message=msg)
return CreateRepositoryResponse()
......@@ -9,6 +9,7 @@ from io import BytesIO
import grpc
import shutil
import tarfile
from mercurial_testhelpers.util import as_bytes
import pytest
......@@ -19,8 +20,10 @@ from hgext3rd.heptapod.keep_around import (
)
from hgitaly.tests.common import make_empty_repo
from hgitaly.stub.shared_pb2 import Repository
from hgitaly.stub.repository_service_pb2 import (
CreateRepositoryRequest,
FindMergeBaseRequest,
GetArchiveRequest,
HasLocalBranchesRequest,
......@@ -29,9 +32,15 @@ from hgitaly.stub.repository_service_pb2 import (
)
from hgitaly.stub.repository_service_pb2_grpc import RepositoryServiceStub
from mercurial import (
error,
hg,
node as node_mod,
pycompat,
)
from heptapod.testhelpers import (
make_ui,
LocalRepoWrapper,
)
def test_repository_exists(grpc_channel, server_repos_root):
......@@ -279,3 +288,47 @@ def test_find_merge_base(grpc_channel, server_repos_root):
sha_not_exists = b'deadnode' * 5
assert do_rpc([sha0, sha_not_exists]) == b''
def test_create_repository(grpc_channel, server_repos_root):
rel_path = 'sample_repo'
default_storage = 'default'
repo_stub = RepositoryServiceStub(grpc_channel)
ui = make_ui(None)
path = server_repos_root / default_storage / rel_path
pathb = as_bytes(path)
# try to instantiate wrapper before repo creation
with pytest.raises(error.RepoError) as exc_info:
LocalRepoWrapper(hg.repository(ui, pathb), path)
assert b''.join(exc_info.value.args).endswith(b'sample_repo not found')
def do_rpc(rel_path, storage=default_storage):
grpc_repo = Repository(relative_path=rel_path, storage_name=storage)
request = CreateRepositoryRequest(repository=grpc_repo)
response = repo_stub.CreateRepository(request)
return response
do_rpc(rel_path)
# instantiating wrapper to check successful repo creation
wrapper = LocalRepoWrapper(hg.repository(ui, pathb), path)
assert wrapper.repo.path.endswith(b'default/sample_repo/.hg')
# To follow along with Gitaly, attempt to create existing repo
# shouldn't respond with any error
do_rpc(rel_path)
# when storage name doesn't exists
with pytest.raises(grpc.RpcError) as exc_info:
do_rpc(rel_path, storage='cargoship')
assert exc_info.value.code() == grpc.StatusCode.INVALID_ARGUMENT
assert 'no such storage' in exc_info.value.details()
# test with a broken symlink (which points to itself)
brepo_name = "myrepo_a_broken_symlink"
path = (server_repos_root / default_storage / brepo_name)
path.symlink_to(path)
with pytest.raises(grpc.RpcError) as exc_info:
do_rpc(brepo_name)
assert exc_info.value.code() == grpc.StatusCode.INTERNAL
assert 'Too many levels of symbolic links' in exc_info.value.details()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment