1 2 3 4 5 6 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
# frozen_string_literal: true
class GitRefsFinder
include Gitlab::Utils::StrongMemoize
attr_reader :next_cursor
def initialize(repository, params = {})
@repository = repository
@params = params
@next_cursor = nil
end
protected
attr_reader :repository, :params
def by_search(refs)
return refs unless search
matches = filter_refs(refs, search)
return matches if regex_search?
set_exact_match_as_first_result(matches, search)
end
def search
@params[:search].to_s.presence
end
strong_memoize_attr :search
def sort
@params[:sort].to_s.presence || 'name'
end
def pagination_params
{ limit: per_page, page_token: page_token }
end
def per_page
return if params[:per_page].blank?
Gitlab::PaginationDelegate.new(
per_page: params[:per_page].presence, page: nil, count: nil
).limit_value
end
def filter_refs(refs, term)
regex_string = RE2::Regexp.escape(term.downcase)
regex_string = unescape_regex_operators(regex_string) if regex_search?
regex_string = Gitlab::UntrustedRegexp.new(regex_string)
refs.select { |ref| regex_string.match?(ref.name.downcase) }
end
def set_exact_match_as_first_result(matches, term)
exact_match_index = find_exact_match_index(matches, term)
matches.insert(0, matches.delete_at(exact_match_index)) if exact_match_index
matches
end
def find_exact_match_index(matches, term)
matches.index { |ref| ref.name.casecmp(term) == 0 }
end
def regex_search?
Regexp.union('^', '$', '*') === search
end
strong_memoize_attr :regex_search?
def unescape_regex_operators(regex_string)
regex_string.sub('\^', '^').gsub('\*', '.*?').sub('\$', '$')
end
def set_next_cursor(records)
return if records.blank?
# TODO: Gitaly should be responsible for a cursor generation
# Follow-up for branches: https://gitlab.com/gitlab-org/gitlab/-/issues/431903
# Follow-up for tags: https://gitlab.com/gitlab-org/gitlab/-/issues/431904
@next_cursor = records.last.name
end
end
|