summaryrefslogtreecommitdiff
path: root/lorrycontroller/gitlab.py
diff options
context:
space:
mode:
Diffstat (limited to 'lorrycontroller/gitlab.py')
-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