Module: ExtractsRef

Included in:
ExtractsPath, Snippets::BlobsActions
Defined in:
lib/extracts_ref.rb,
lib/extracts_ref/requested_ref.rb

Overview

Module providing methods for dealing with separating a tree-ish string and a file path string when combined in a request parameter Can be extended for different types of repository object, e.g. Project or Snippet

Defined Under Namespace

Classes: RequestedRef

Constant Summary collapse

InvalidPathError =
Class.new(StandardError)
BRANCH_REF_TYPE =
'heads'
TAG_REF_TYPE =
'tags'
REF_TYPES =
[BRANCH_REF_TYPE, TAG_REF_TYPE].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.qualify_ref(ref, type) ⇒ Object



18
19
20
21
22
23
# File 'lib/extracts_ref.rb', line 18

def self.qualify_ref(ref, type)
  validated_type = ref_type(type)
  return ref unless validated_type

  %(refs/#{validated_type}/#{ref})
end

.ref_type(type) ⇒ Object



12
13
14
15
16
# File 'lib/extracts_ref.rb', line 12

def self.ref_type(type)
  return unless REF_TYPES.include?(type&.downcase)

  type.downcase
end

.unqualify_ref(ref, type) ⇒ Object



25
26
27
28
29
30
# File 'lib/extracts_ref.rb', line 25

def self.unqualify_ref(ref, type)
  validated_type = ref_type(type)
  return ref unless validated_type

  ref.sub(%r{^refs/#{validated_type}/}, '')
end

Instance Method Details

#assign_ref_varsObject

Assigns common instance variables for views working with Git tree-ish objects

Assignments are:

  • @id - A string representing the joined ref and path

  • @ref - A string representing the ref (e.g., the branch, tag, or commit SHA)

  • @path - A string representing the filesystem path

  • @commit - A Commit representing the commit from the given ref

If the :id parameter appears to be requesting a specific response format, that will be handled as well. rubocop:disable Gitlab/ModuleWithInstanceVariables

Raises:



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/extracts_ref.rb', line 86

def assign_ref_vars
  @id, @ref, @path = extract_ref_path
  @repo = repository_container.repository
  raise InvalidPathError if @ref.match?(/\s/)

  return unless @ref.present?

  @commit = if ref_type
              @fully_qualified_ref = ExtractsRef.qualify_ref(@ref, ref_type)
              @repo.commit(@fully_qualified_ref)
            else
              @repo.commit(@ref)
            end
end

#extract_ref(id) ⇒ Object

Given a string containing both a Git tree-ish, such as a branch or tag, and a filesystem path joined by forward slashes, attempts to separate the two.

Expects a repository_container method that returns the active repository object. This is used to check the input against a list of valid repository refs.

Examples

# No repository_container available
extract_ref('master')
# => ['', '']

extract_ref('master')
# => ['master', '']

extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
# => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']

extract_ref("v2.0.0/README.md")
# => ['v2.0.0', 'README.md']

extract_ref('master/app/models/project.rb')
# => ['master', 'app/models/project.rb']

extract_ref('issues/1234/app/models/project.rb')
# => ['issues/1234', 'app/models/project.rb']

# Given an invalid branch, we fall back to just splitting on the first slash
extract_ref('non/existent/branch/README.md')
# => ['non', 'existent/branch/README.md']

Returns an Array where the first value is the tree-ish and the second is the path



65
66
67
68
69
70
71
72
# File 'lib/extracts_ref.rb', line 65

def extract_ref(id)
  pair = extract_raw_ref(id)

  [
    pair[0].strip,
    pair[1].delete_prefix('/').delete_suffix('/')
  ]
end

#extract_ref_pathObject



106
107
108
109
110
111
# File 'lib/extracts_ref.rb', line 106

def extract_ref_path
  id = get_id
  ref, path = extract_ref(id)

  [id, ref, path]
end

#ref_typeObject



113
114
115
# File 'lib/extracts_ref.rb', line 113

def ref_type
  ExtractsRef.ref_type(params[:ref_type])
end

#treeObject

rubocop:enable Gitlab/ModuleWithInstanceVariables



102
103
104
# File 'lib/extracts_ref.rb', line 102

def tree
  @tree ||= @repo.tree(@commit.id, @path) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end