Module: Gitlab::RepoPath

Defined in:
lib/gitlab/repo_path.rb

Constant Summary collapse

NotFoundError =
Class.new(StandardError)

Class Method Summary collapse

Class Method Details

.extract_snippet_info(snippet_path) ⇒ Object


70
71
72
73
74
75
76
77
# File 'lib/gitlab/repo_path.rb', line 70

def self.extract_snippet_info(snippet_path)
  path_segments = snippet_path.split('/')
  snippet_id = path_segments.pop
  path_segments.pop # Remove snippets from path
  project_path = File.join(path_segments)

  [snippet_id, project_path]
end

.find_container(type, full_path) ⇒ Object


33
34
35
36
37
38
39
40
41
42
43
# File 'lib/gitlab/repo_path.rb', line 33

def self.find_container(type, full_path)
  if type.snippet?
    snippet, redirected_path = find_snippet(full_path)

    [snippet, snippet&.project, redirected_path]
  else
    project, redirected_path = find_project(full_path)

    [project, project, redirected_path]
  end
end

.find_project(project_path) ⇒ Object


45
46
47
48
49
50
51
52
# File 'lib/gitlab/repo_path.rb', line 45

def self.find_project(project_path)
  return [nil, nil] if project_path.blank?

  project = Project.find_by_full_path(project_path, follow_redirects: true)
  redirected_path = redirected?(project, project_path) ? project_path : nil

  [project, redirected_path]
end

.find_snippet(snippet_path) ⇒ Object

Snippet_path can be either:

  • snippets/1

  • h5bp/html5-boilerplate/snippets/53


61
62
63
64
65
66
67
68
# File 'lib/gitlab/repo_path.rb', line 61

def self.find_snippet(snippet_path)
  return [nil, nil] if snippet_path.blank?

  snippet_id, project_path = extract_snippet_info(snippet_path)
  project, redirected_path = find_project(project_path)

  [Snippet.find_by_id_and_project(id: snippet_id, project: project), redirected_path]
end

.parse(path) ⇒ Object


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/gitlab/repo_path.rb', line 7

def self.parse(path)
  repo_path = path.sub(/\.git\z/, '').sub(%r{\A/}, '')
  redirected_path = nil

  # 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 type.valid?(repo_path)

    # Removing the suffix (.wiki, .design, ...) from the project path
    full_path = repo_path.chomp(type.path_suffix)
    container, project, redirected_path = find_container(type, full_path)

    return [container, project, type, redirected_path] if container
  end

  # When a project did not exist, the parsed repo_type would be empty.
  # In that case, we want to continue with a regular project repository. As we
  # could create the project if the user pushing is allowed to do so.
  [nil, nil, Gitlab::GlRepository.default_type, nil]
end

.redirected?(project, project_path) ⇒ Boolean

Returns:

  • (Boolean)

54
55
56
# File 'lib/gitlab/repo_path.rb', line 54

def self.redirected?(project, project_path)
  project && project.full_path.casecmp(project_path) != 0
end