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

RepositoryService: implement FullPath

Closes #114
parent 13743355
No related branches found
No related tags found
1 merge request!131RepositoryService.FullPath and cleanup
......@@ -28,6 +28,19 @@
repo.vfs.write(GITLAB_PROJECT_FULL_PATH_FILENAME, full_path)
def get_gitlab_project_full_path(repo):
"""Get the full path of GitLab Project.
See also :func:`set_gitlab_project_full_path`.
:return: the full path, or ``None`` if not set.
"""
try:
return repo.vfs.read(GITLAB_PROJECT_FULL_PATH_FILENAME)
except FileNotFoundError:
return None
def unbundle(repo, bundle_path: str, rails_sync=False):
"""Call unbundle with proper options and conversions.
......
......@@ -51,6 +51,7 @@
validate_relative_path,
)
from ..repository import (
get_gitlab_project_full_path,
set_gitlab_project_full_path,
unbundle,
)
......@@ -80,6 +81,8 @@
FetchBundleResponse,
FindMergeBaseRequest,
FindMergeBaseResponse,
FullPathRequest,
FullPathResponse,
GetRawChangesRequest,
GetRawChangesResponse,
RepositoryExistsRequest,
......@@ -416,6 +419,32 @@
set_gitlab_project_full_path(repo, request.path.encode('utf-8'))
return SetFullPathResponse()
def FullPath(self, request: FullPathRequest,
context) -> FullPathResponse:
try:
repo = self.load_repo(request.repository, context)
except KeyError as exc:
kind, what = exc.args
if kind == 'storage':
context.abort(StatusCode.INVALID_ARGUMENT,
'fetch config: GetStorageByName: '
'no such storage: "%s"' % what)
else:
# (H)Gitaly relative paths are always ASCII, but the
# root might not be (Gitaly does disclose the full expected
# path in the error message)
context.abort(StatusCode.NOT_FOUND,
'fetch config: GetRepoPath: not a Mercurial '
'repository: "%s"' % os.fsdecode(what))
path = get_gitlab_project_full_path(repo)
if not path: # None or (not probable) empty string
# Gitaly simply returns the `git config` stderr output for now.
# Pretty ridiculous to mimick it, we can hope not much to
# depend on it.
context.abort(StatusCode.INTERNAL, "Full path not set")
return FullPathResponse(path=path)
def CreateBundle(self, request: CreateBundleRequest,
context) -> CreateBundleResponse:
repo = self.load_repo(request.repository, context).unfiltered()
......
......@@ -43,6 +43,7 @@
CreateBundleFromRefListRequest,
FetchBundleRequest,
FindMergeBaseRequest,
FullPathRequest,
GetArchiveRequest,
HasLocalBranchesRequest,
RemoveRepositoryRequest,
......@@ -145,6 +146,12 @@
return self.stub.SetFullPath(SetFullPathRequest(repository=grpc_repo,
path=path))
def full_path(self, grpc_repo=None):
if grpc_repo is None:
grpc_repo = self.grpc_repo
return self.stub.FullPath(FullPathRequest(repository=grpc_repo)).path
def create_bundle(self, save_path):
with open(save_path, 'wb') as fobj:
for chunk in self.stub.CreateBundle(CreateBundleRequest(
......@@ -558,6 +565,7 @@
assert (wrapper.path / '.hg'
/ GITLAB_PROJECT_FULL_PATH_FILENAME.decode('ascii')
).read_text(encoding='utf-8') == expected
assert fixture.full_path() == expected
def call_then_assert(full_path):
fixture.set_full_path(full_path)
......@@ -583,6 +591,28 @@
storage_name='unknown'))
def test_full_path_errors(fixture_with_repo):
fixture = fixture_with_repo
grpc_repo = fixture.grpc_repo
def call_then_assert_error(error_code, grpc_repo=None):
with pytest.raises(grpc.RpcError) as exc_info:
fixture.full_path(grpc_repo=grpc_repo)
assert exc_info.value.code() == error_code
# existing repo, but full path not set
call_then_assert_error(grpc.StatusCode.INTERNAL)
call_then_assert_error(grpc.StatusCode.NOT_FOUND,
grpc_repo=Repository(
storage_name=grpc_repo.storage_name,
relative_path='no/such/repo'))
call_then_assert_error(grpc.StatusCode.INVALID_ARGUMENT,
grpc_repo=Repository(
relative_path=grpc_repo.relative_path,
storage_name='unknown'))
def test_fetch_bundle(fixture_with_repo, tmpdir):
fixture = fixture_with_repo
wrapper = fixture.repo_wrapper
......
......@@ -243,7 +243,7 @@
norm = self.error_details_normalizer
hg_details = exc_hg.details()
git_details = exc_git.details()
if norm is not None: # pragma no cover (temporary)
if norm is not None:
hg_details = norm(hg_details, vcs='hg')
git_details = norm(git_details, vcs='git')
assert hg_details == git_details
......
......@@ -20,6 +20,7 @@
CreateBundleFromRefListRequest,
CreateRepositoryFromBundleRequest,
FindMergeBaseRequest,
FullPathRequest,
RemoveRepositoryRequest,
SetFullPathRequest,
)
......@@ -187,6 +188,33 @@
relative_path='no/such/path'))
def test_full_path(gitaly_comparison, server_repos_root):
fixture = gitaly_comparison
grpc_repo = fixture.gitaly_repo
def normalizer(msg, **kw):
return msg.replace('Mercurial', 'git')
rpc_helper = fixture.rpc_helper(
stub_cls=RepositoryServiceStub,
method_name='FullPath',
request_cls=FullPathRequest,
error_details_normalizer=normalizer,
)
assert_compare_errors = rpc_helper.assert_compare_errors
# path not set on existing repo
assert_compare_errors(same_details=False)
# unknown storage and missing repo
assert_compare_errors(same_details=False,
repository=Repository(storage_name='unknown',
relative_path='/some/path'))
assert_compare_errors(
repository=Repository(storage_name=grpc_repo.storage_name,
relative_path='no/such/path'))
def test_set_full_path(gitaly_comparison, server_repos_root):
fixture = gitaly_comparison
......
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