summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Brown <ben.brown@codethink.co.uk>2016-04-26 09:48:13 +0100
committerVLetrmx <richardipsum@fastmail.co.uk>2016-06-17 18:41:01 +0000
commit9632874369753767a42d5617ee0ea888bf1b18b4 (patch)
treee8362d11b3700110d71529dcfaeaa01a2dc9a9c4
parent4947e78942bf325ed85645876f0352eb3cd24e5e (diff)
downloadlorry-controller-9632874369753767a42d5617ee0ea888bf1b18b4.tar.gz
Workaround for GitLab's lack of multi-level namespacing
Change-Id: Ic1ef8b983cc84b0ce75dc57f9e05b5cdda343dc6
-rw-r--r--lorrycontroller/gitlab.py42
1 files changed, 31 insertions, 11 deletions
diff --git a/lorrycontroller/gitlab.py b/lorrycontroller/gitlab.py
index 659d179..b22bb30 100644
--- a/lorrycontroller/gitlab.py
+++ b/lorrycontroller/gitlab.py
@@ -14,6 +14,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from __future__ import absolute_import
+import re
import urlparse
import itertools
try:
@@ -47,24 +48,25 @@ class Gitlab(object):
def first(self, predicate, iterable):
return next(itertools.ifilter(predicate, iterable))
- def split_path(self, path):
- return path.rsplit('/', 1)
+ def split_and_unslashify_path(self, path):
+ group, project = path.split('/', 1)
+ return group, project.replace('/', '_')
- def find_project(self, group, project):
+ def find_project(self, repo_path):
+ group, project = self.split_and_unslashify_path(repo_path)
predicate = lambda x: x.namespace.name == group and x.name == project
return self.first(predicate, self.gl.projects.search(project))
def has_project(self, repo_path):
- group, project = self.split_path(repo_path)
-
try:
- return bool(self.find_project(group, project))
+ return bool(self.find_project(repo_path))
except StopIteration:
return False
def create_project(self, repo_path):
- group_name, project_name = self.split_path(repo_path)
+ # GitLab only supports one level of namespacing.
+ group_name, project_name = self.split_and_unslashify_path(repo_path)
group = None
try:
group = self.gl.groups.get(group_name)
@@ -79,12 +81,31 @@ class Gitlab(object):
'name': project_name,
'public': True,
'merge_requests_enabled': False,
- 'namespace_id': group.id
+ 'namespace_id': group.id,
+ # Set the original path in the description. We will use this to
+ # work around lack of multi-level namespacing.
+ 'description': 'original_path: %s' % repo_path
}
self.gl.projects.create(project)
+ def try_get_original_path(self, project_description):
+ match = re.search('original_path:\s(.*)', str(project_description))
+ if match:
+ return match.groups()[0]
+
+ def suitable_path(self, project):
+ return (self.try_get_original_path(project.description) or
+ project.path_with_namespace)
+
def list_projects(self):
- return [x.path_with_namespace for x in self.gl.projects.list()]
+ '''List projects on a GitLab instance.
+
+ In attempt to handle GitLab's current lack of multi-level namespacing
+ (see: https://gitlab.com/gitlab-org/gitlab-ce/issues/2772), return
+ the 'original_path' stored in a project's description, if it exists.
+ '''
+
+ return [self.suitable_path(x) for x in self.gl.projects.list()]
def get_project_url(self, protocol, project_path):
'''Return the clone url for a GitLab project.
@@ -99,8 +120,7 @@ class Gitlab(object):
format matching 'http(s)://host/group/project.git'.
'''
- group, project = self.split_path(project_path)
- project = self.find_project(group, project)
+ project = self.find_project(project_path)
if protocol == 'ssh':
return project.ssh_url_to_repo