Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2019-03-18 19:51:11 +0300
committerBob Van Landuyt <bob@vanlanduyt.co>2019-03-26 15:21:03 +0300
commitd36415b7545fff543f08a5175790e3a92f383475 (patch)
treeb88dfef2992af721191b790ac7a5bc6f1b9eb90b /lib/gitlab
parentd64452ebfc262cfc1324fcaf116e74bc436413d3 (diff)
Allow multiple repositories per project
This changes the repository type from a binary `wiki?` to a type. So we can have more than 2 repository types. Now everywhere we called `.wiki?` and expected a boolean, we check that type.
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/gl_repository.rb35
-rw-r--r--lib/gitlab/gl_repository/repo_type.rb42
-rw-r--r--lib/gitlab/repo_path.rb25
-rw-r--r--lib/gitlab/workhorse.rb4
4 files changed, 85 insertions, 21 deletions
diff --git a/lib/gitlab/gl_repository.rb b/lib/gitlab/gl_repository.rb
index 435b74806e7..c2be7f3d63a 100644
--- a/lib/gitlab/gl_repository.rb
+++ b/lib/gitlab/gl_repository.rb
@@ -2,23 +2,38 @@
module Gitlab
module GlRepository
- def self.gl_repository(project, is_wiki)
- "#{is_wiki ? 'wiki' : 'project'}-#{project.id}"
+ PROJECT = RepoType.new(
+ name: :project,
+ access_checker_class: Gitlab::GitAccess,
+ repository_accessor: -> (project) { project.repository }
+ ).freeze
+ WIKI = RepoType.new(
+ name: :wiki,
+ access_checker_class: Gitlab::GitAccessWiki,
+ repository_accessor: -> (project) { project.wiki.repository }
+ ).freeze
+
+ TYPES = {
+ PROJECT.name.to_s => PROJECT,
+ WIKI.name.to_s => WIKI
+ }.freeze
+
+ def self.types
+ TYPES
end
- # rubocop: disable CodeReuse/ActiveRecord
def self.parse(gl_repository)
- match_data = /\A(project|wiki)-([1-9][0-9]*)\z/.match(gl_repository)
- unless match_data
+ type_name, _id = gl_repository.split('-').first
+ type = types[type_name]
+ subject_id = type&.fetch_id(gl_repository)
+
+ unless subject_id
raise ArgumentError, "Invalid GL Repository \"#{gl_repository}\""
end
- type, id = match_data.captures
- project = Project.find_by(id: id)
- wiki = type == 'wiki'
+ project = Project.find_by_id(subject_id)
- [project, wiki]
+ [project, type]
end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/lib/gitlab/gl_repository/repo_type.rb b/lib/gitlab/gl_repository/repo_type.rb
new file mode 100644
index 00000000000..7abe6c29a25
--- /dev/null
+++ b/lib/gitlab/gl_repository/repo_type.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GlRepository
+ class RepoType
+ attr_reader :name,
+ :access_checker_class,
+ :repository_accessor
+
+ def initialize(name:, access_checker_class:, repository_accessor:)
+ @name = name
+ @access_checker_class = access_checker_class
+ @repository_accessor = repository_accessor
+ end
+
+ def identifier_for_subject(subject)
+ "#{name}-#{subject.id}"
+ end
+
+ def fetch_id(identifier)
+ match = /\A#{name}-(?<id>\d+)\z/.match(identifier)
+ match[:id] if match
+ end
+
+ def wiki?
+ self == WIKI
+ end
+
+ def project?
+ self == PROJECT
+ end
+
+ def path_suffix
+ project? ? "" : ".#{name}"
+ end
+
+ def repository_for(subject)
+ repository_accessor.call(subject)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/repo_path.rb b/lib/gitlab/repo_path.rb
index 202d310e237..207a80b7db2 100644
--- a/lib/gitlab/repo_path.rb
+++ b/lib/gitlab/repo_path.rb
@@ -5,19 +5,26 @@ module Gitlab
NotFoundError = Class.new(StandardError)
def self.parse(repo_path)
- wiki = false
project_path = repo_path.sub(/\.git\z/, '').sub(%r{\A/}, '')
- project, was_redirected = find_project(project_path)
-
- if project_path.end_with?('.wiki') && project.nil?
- project, was_redirected = find_project(project_path.chomp('.wiki'))
- wiki = true
+ # Detect the repo type based on the path, the first one tried is the project
+ # type, which does not have a suffix.
+ Gitlab::GlRepository.types.each do |_name, type|
+ # If the project path does not end with the defined suffix, try the next
+ # type.
+ # We'll always try to find a project with an empty suffix (for the
+ # `Gitlab::GlRepository::PROJECT` type.
+ next unless project_path.end_with?(type.path_suffix)
+
+ project, was_redirected = find_project(project_path.chomp(type.path_suffix))
+ redirected_path = project_path if was_redirected
+
+ # If we found a matching project, then the type was matched, no need to
+ # continue looking.
+ return [project, type, redirected_path] if project
end
- redirected_path = project_path if was_redirected
-
- [project, wiki, redirected_path]
+ nil
end
def self.find_project(project_path)
diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb
index 265f6213a99..5d5a867c9ab 100644
--- a/lib/gitlab/workhorse.rb
+++ b/lib/gitlab/workhorse.rb
@@ -20,14 +20,14 @@ module Gitlab
SECRET_LENGTH = 32
class << self
- def git_http_ok(repository, is_wiki, user, action, show_all_refs: false)
+ def git_http_ok(repository, repo_type, user, action, show_all_refs: false)
raise "Unsupported action: #{action}" unless ALLOWED_GIT_HTTP_ACTIONS.include?(action.to_s)
project = repository.project
attrs = {
GL_ID: Gitlab::GlId.gl_id(user),
- GL_REPOSITORY: Gitlab::GlRepository.gl_repository(project, is_wiki),
+ GL_REPOSITORY: repo_type.identifier_for_subject(project),
GL_USERNAME: user&.username,
ShowAllRefs: show_all_refs,
Repository: repository.gitaly_repository.to_h,