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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
commit859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch)
treed7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /app/finders
parent446d496a6d000c73a304be52587cd9bbc7493136 (diff)
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/autocomplete/users_finder.rb10
-rw-r--r--app/finders/ci/jobs_finder.rb7
-rw-r--r--app/finders/ci/testing/daily_build_group_report_results_finder.rb88
-rw-r--r--app/finders/concerns/packages/finder_helper.rb33
-rw-r--r--app/finders/container_repositories_finder.rb9
-rw-r--r--app/finders/deployments_finder.rb85
-rw-r--r--app/finders/labels_finder.rb6
-rw-r--r--app/finders/license_template_finder.rb5
-rw-r--r--app/finders/merge_request/metrics_finder.rb65
-rw-r--r--app/finders/merge_requests/oldest_per_commit_finder.rb33
-rw-r--r--app/finders/packages/group_packages_finder.rb30
-rw-r--r--app/finders/packages/nuget/package_finder.rb2
-rw-r--r--app/finders/packages/packages_finder.rb21
-rw-r--r--app/finders/repositories/commits_with_trailer_finder.rb82
-rw-r--r--app/finders/repositories/previous_tag_finder.rb51
-rw-r--r--app/finders/template_finder.rb16
-rw-r--r--app/finders/terraform/states_finder.rb28
-rw-r--r--app/finders/user_recent_events_finder.rb43
18 files changed, 515 insertions, 99 deletions
diff --git a/app/finders/autocomplete/users_finder.rb b/app/finders/autocomplete/users_finder.rb
index 8dc3c2320ed..ff5d9ea7d19 100644
--- a/app/finders/autocomplete/users_finder.rb
+++ b/app/finders/autocomplete/users_finder.rb
@@ -38,7 +38,9 @@ module Autocomplete
end
end
- items.uniq
+ items.uniq.tap do |unique_items|
+ preload_associations(unique_items)
+ end
end
private
@@ -91,6 +93,12 @@ module Autocomplete
User.none
end
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def preload_associations(items)
+ ActiveRecord::Associations::Preloader.new.preload(items, :status)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/finders/ci/jobs_finder.rb b/app/finders/ci/jobs_finder.rb
index 78791d737da..4408c9cdb6d 100644
--- a/app/finders/ci/jobs_finder.rb
+++ b/app/finders/ci/jobs_finder.rb
@@ -45,11 +45,12 @@ module Ci
return unless pipeline
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, pipeline)
- jobs_by_type(pipeline, type).latest
+ jobs_scope = jobs_by_type(pipeline, type)
+ params[:include_retried] ? jobs_scope : jobs_scope.latest
end
def filter_by_scope(builds)
- return filter_by_statuses!(params[:scope], builds) if params[:scope].is_a?(Array)
+ return filter_by_statuses!(builds) if params[:scope].is_a?(Array)
case params[:scope]
when 'pending'
@@ -63,7 +64,7 @@ module Ci
end
end
- def filter_by_statuses!(statuses, builds)
+ def filter_by_statuses!(builds)
unknown_statuses = params[:scope] - ::CommitStatus::AVAILABLE_STATUSES
raise ArgumentError, 'Scope contains invalid value(s)' unless unknown_statuses.empty?
diff --git a/app/finders/ci/testing/daily_build_group_report_results_finder.rb b/app/finders/ci/testing/daily_build_group_report_results_finder.rb
new file mode 100644
index 00000000000..70d9e55dc47
--- /dev/null
+++ b/app/finders/ci/testing/daily_build_group_report_results_finder.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+# DailyBuildGroupReportResultsFinder
+#
+# Used to filter DailyBuildGroupReportResults by set of params
+#
+# Arguments:
+# current_user
+# params:
+# project: integer
+# group: integer
+# coverage: boolean
+# ref_path: string
+# start_date: date
+# end_date: date
+# sort: boolean
+# limit: integer
+
+module Ci
+ module Testing
+ class DailyBuildGroupReportResultsFinder
+ include Gitlab::Allowable
+
+ MAX_ITEMS = 1_000
+
+ attr_reader :params, :current_user
+
+ def initialize(params: {}, current_user: nil)
+ @params = params
+ @current_user = current_user
+ end
+
+ def execute
+ return Ci::DailyBuildGroupReportResult.none unless query_allowed?
+
+ collection = Ci::DailyBuildGroupReportResult.by_projects(params[:project])
+ collection = filter_report_results(collection)
+ collection
+ end
+
+ private
+
+ def query_allowed?
+ can?(current_user, :read_build_report_results, params[:project])
+ end
+
+ def filter_report_results(collection)
+ collection = by_coverage(collection)
+ collection = by_ref_path(collection)
+ collection = by_dates(collection)
+
+ collection = sort(collection)
+ collection = limit_by(collection)
+ collection
+ end
+
+ def by_coverage(items)
+ params[:coverage].present? ? items.with_coverage : items
+ end
+
+ def by_ref_path(items)
+ params[:ref_path].present? ? items.by_ref_path(params[:ref_path]) : items.with_default_branch
+ end
+
+ def by_dates(items)
+ params[:start_date].present? && params[:end_date].present? ? items.by_dates(params[:start_date], params[:end_date]) : items
+ end
+
+ def sort(items)
+ params[:sort].present? ? items.ordered_by_date_and_group_name : items
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def limit_by(items)
+ items.limit(limit)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def limit
+ return MAX_ITEMS unless params[:limit].present?
+
+ [params[:limit].to_i, MAX_ITEMS].min
+ end
+ end
+ end
+end
+
+Ci::Testing::DailyBuildGroupReportResultsFinder.prepend_if_ee('::EE::Ci::Testing::DailyBuildGroupReportResultsFinder')
diff --git a/app/finders/concerns/packages/finder_helper.rb b/app/finders/concerns/packages/finder_helper.rb
index 524e7aa7ff9..30bc0ff7909 100644
--- a/app/finders/concerns/packages/finder_helper.rb
+++ b/app/finders/concerns/packages/finder_helper.rb
@@ -4,6 +4,9 @@ module Packages
module FinderHelper
extend ActiveSupport::Concern
+ InvalidPackageTypeError = Class.new(StandardError)
+ InvalidStatusError = Class.new(StandardError)
+
private
def packages_visible_to_user(user, within_group:)
@@ -25,5 +28,35 @@ module Packages
::Project.in_namespace(namespace_ids)
.public_or_visible_to_user(user, ::Gitlab::Access::REPORTER)
end
+
+ def package_type
+ params[:package_type].presence
+ end
+
+ def filter_by_package_type(packages)
+ return packages unless package_type
+ raise InvalidPackageTypeError unless ::Packages::Package.package_types.key?(package_type)
+
+ packages.with_package_type(package_type)
+ end
+
+ def filter_by_package_name(packages)
+ return packages unless params[:package_name].present?
+
+ packages.search_by_name(params[:package_name])
+ end
+
+ def filter_with_version(packages)
+ return packages if params[:include_versionless].present?
+
+ packages.has_version
+ end
+
+ def filter_by_status(packages)
+ return packages.displayable unless params[:status].present?
+ raise InvalidStatusError unless Package.statuses.key?(params[:status])
+
+ packages.with_status(params[:status])
+ end
end
end
diff --git a/app/finders/container_repositories_finder.rb b/app/finders/container_repositories_finder.rb
index 5109efb361b..14e4d6799d8 100644
--- a/app/finders/container_repositories_finder.rb
+++ b/app/finders/container_repositories_finder.rb
@@ -14,7 +14,8 @@ class ContainerRepositoriesFinder
return unless authorized?
repositories = @subject.is_a?(Project) ? project_repositories : group_repositories
- filter_by_image_name(repositories)
+ repositories = filter_by_image_name(repositories)
+ sort(repositories)
end
private
@@ -39,6 +40,12 @@ class ContainerRepositoriesFinder
repositories.search_by_name(@params[:name])
end
+ def sort(repositories)
+ return repositories unless @params[:sort]
+
+ repositories.order_by(@params[:sort])
+ end
+
def authorized?
Ability.allowed?(@user, :read_container_image, @subject)
end
diff --git a/app/finders/deployments_finder.rb b/app/finders/deployments_finder.rb
index 4038f93cf2d..89a28d9dfb8 100644
--- a/app/finders/deployments_finder.rb
+++ b/app/finders/deployments_finder.rb
@@ -1,57 +1,56 @@
# frozen_string_literal: true
+# WARNING: This finder does not check permissions!
+#
+# Arguments:
+# params:
+# project: Project model - Find deployments for this project
+# updated_after: DateTime
+# updated_before: DateTime
+# finished_after: DateTime
+# finished_before: DateTime
+# environment: String
+# status: String (see Deployment.statuses)
+# order_by: String (see ALLOWED_SORT_VALUES constant)
+# sort: String (asc | desc)
class DeploymentsFinder
- attr_reader :project, :params
+ attr_reader :params
- ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref].freeze
+ ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref finished_at].freeze
DEFAULT_SORT_VALUE = 'id'
ALLOWED_SORT_DIRECTIONS = %w[asc desc].freeze
DEFAULT_SORT_DIRECTION = 'asc'
- def initialize(project, params = {})
- @project = project
+ def initialize(params = {})
@params = params
end
def execute
items = init_collection
items = by_updated_at(items)
+ items = by_finished_at(items)
items = by_environment(items)
items = by_status(items)
- sort(items)
+ items = preload_associations(items)
+ items = sort(items)
+
+ items
end
private
- # rubocop: disable CodeReuse/ActiveRecord
def init_collection
- project
- .deployments
- .includes(
- :user,
- environment: [],
- deployable: {
- job_artifacts: [],
- pipeline: {
- project: {
- route: [],
- namespace: :route
- }
- },
- project: {
- namespace: :route
- }
- }
- )
+ if params[:project]
+ params[:project].deployments
+ else
+ Deployment.none
+ end
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def sort(items)
- items.order(sort_params)
+ items.order(sort_params) # rubocop: disable CodeReuse/ActiveRecord
end
- # rubocop: enable CodeReuse/ActiveRecord
def by_updated_at(items)
items = items.updated_before(params[:updated_before]) if params[:updated_before].present?
@@ -60,6 +59,13 @@ class DeploymentsFinder
items
end
+ def by_finished_at(items)
+ items = items.finished_before(params[:finished_before]) if params[:finished_before].present?
+ items = items.finished_after(params[:finished_after]) if params[:finished_after].present?
+
+ items
+ end
+
def by_environment(items)
if params[:environment].present?
items.for_environment_name(params[:environment])
@@ -87,4 +93,27 @@ class DeploymentsFinder
sort_values['id'] = sort_values.delete('created_at') if sort_values['created_at'] # Sorting by `id` produces the same result as sorting by `created_at`
end
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def preload_associations(scope)
+ scope.includes(
+ :user,
+ environment: [],
+ deployable: {
+ job_artifacts: [],
+ pipeline: {
+ project: {
+ route: [],
+ namespace: :route
+ }
+ },
+ project: {
+ namespace: :route
+ }
+ }
+ )
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
+
+DeploymentsFinder.prepend_if_ee('EE::DeploymentsFinder')
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index 4358cf249f7..bedd6891d02 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -100,6 +100,10 @@ class LabelsFinder < UnionFinder
strong_memoize(:group_ids) do
groups = groups_to_include(group)
+ # Because we are sure that all groups are in the same hierarchy tree
+ # we can preset root group for all of them to optimize permission checks
+ Group.preset_root_ancestor_for(groups)
+
groups_user_can_read_labels(groups).map(&:id)
end
end
@@ -173,7 +177,7 @@ class LabelsFinder < UnionFinder
end
if group?
- @projects = if params[:include_subgroups]
+ @projects = if params[:include_descendant_groups]
@projects.in_namespace(group.self_and_descendants.select(:id))
else
@projects.in_namespace(group.id)
diff --git a/app/finders/license_template_finder.rb b/app/finders/license_template_finder.rb
index 4d68b963dc3..c4cb33235af 100644
--- a/app/finders/license_template_finder.rb
+++ b/app/finders/license_template_finder.rb
@@ -28,6 +28,10 @@ class LicenseTemplateFinder
end
end
+ def template_names
+ ::Gitlab::Template::BaseTemplate.template_names_by_category(vendored_licenses)
+ end
+
private
def vendored_licenses
@@ -36,6 +40,7 @@ class LicenseTemplateFinder
LicenseTemplate.new(
key: license.key,
name: license.name,
+ project: project,
nickname: license.nickname,
category: (license.featured? ? :Popular : :Other),
content: license.content,
diff --git a/app/finders/merge_request/metrics_finder.rb b/app/finders/merge_request/metrics_finder.rb
new file mode 100644
index 00000000000..d93e53d1636
--- /dev/null
+++ b/app/finders/merge_request/metrics_finder.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+class MergeRequest::MetricsFinder
+ include Gitlab::Allowable
+
+ def initialize(current_user, params = {})
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ return klass.none if target_project.blank? || user_not_authorized?
+
+ items = init_collection
+ items = by_target_project(items)
+ items = by_merged_after(items)
+ items = by_merged_before(items)
+
+ items
+ end
+
+ private
+
+ attr_reader :current_user, :params
+
+ def by_target_project(items)
+ items.by_target_project(target_project)
+ end
+
+ def by_merged_after(items)
+ return items unless merged_after
+
+ items.merged_after(merged_after)
+ end
+
+ def by_merged_before(items)
+ return items unless merged_before
+
+ items.merged_before(merged_before)
+ end
+
+ def user_not_authorized?
+ !can?(current_user, :read_merge_request, target_project)
+ end
+
+ def init_collection
+ klass.all
+ end
+
+ def klass
+ MergeRequest::Metrics
+ end
+
+ def target_project
+ params[:target_project]
+ end
+
+ def merged_after
+ params[:merged_after]
+ end
+
+ def merged_before
+ params[:merged_before]
+ end
+end
diff --git a/app/finders/merge_requests/oldest_per_commit_finder.rb b/app/finders/merge_requests/oldest_per_commit_finder.rb
new file mode 100644
index 00000000000..f50db43d7d2
--- /dev/null
+++ b/app/finders/merge_requests/oldest_per_commit_finder.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ # OldestPerCommitFinder is used to retrieve the oldest merge requests for
+ # every given commit, grouped per commit SHA.
+ #
+ # This finder is useful when you need to efficiently retrieve the first/oldest
+ # merge requests for multiple commits, and you want to do so in batches;
+ # instead of running a query for every commit.
+ class OldestPerCommitFinder
+ def initialize(project)
+ @project = project
+ end
+
+ # Returns a Hash that maps a commit ID to the oldest merge request that
+ # introduced that commit.
+ def execute(commits)
+ id_rows = MergeRequestDiffCommit
+ .oldest_merge_request_id_per_commit(@project.id, commits.map(&:id))
+
+ mrs = MergeRequest
+ .preload_target_project
+ .id_in(id_rows.map { |r| r[:merge_request_id] })
+ .index_by(&:id)
+
+ id_rows.each_with_object({}) do |row, hash|
+ if (mr = mrs[row[:merge_request_id]])
+ hash[row[:sha]] = mr
+ end
+ end
+ end
+ end
+end
diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb
index 860c4068b31..db5161d6e16 100644
--- a/app/finders/packages/group_packages_finder.rb
+++ b/app/finders/packages/group_packages_finder.rb
@@ -2,9 +2,7 @@
module Packages
class GroupPackagesFinder
- attr_reader :current_user, :group, :params
-
- InvalidPackageTypeError = Class.new(StandardError)
+ include ::Packages::FinderHelper
def initialize(current_user, group, params = { exclude_subgroups: false, order_by: 'created_at', sort: 'asc' })
@current_user = current_user
@@ -20,6 +18,8 @@ module Packages
private
+ attr_reader :current_user, :group, :params
+
def packages_for_group_projects
packages = ::Packages::Package
.including_build_info
@@ -32,6 +32,7 @@ module Packages
packages = filter_with_version(packages)
packages = filter_by_package_type(packages)
packages = filter_by_package_name(packages)
+ packages = filter_by_status(packages)
packages
end
@@ -46,10 +47,6 @@ module Packages
.with_feature_available_for_user(:repository, current_user)
end
- def package_type
- params[:package_type].presence
- end
-
def groups
return [group] if exclude_subgroups?
@@ -59,24 +56,5 @@ module Packages
def exclude_subgroups?
params[:exclude_subgroups]
end
-
- def filter_by_package_type(packages)
- return packages unless package_type
- raise InvalidPackageTypeError unless Package.package_types.key?(package_type)
-
- packages.with_package_type(package_type)
- end
-
- def filter_by_package_name(packages)
- return packages unless params[:package_name].present?
-
- packages.search_by_name(params[:package_name])
- end
-
- def filter_with_version(packages)
- return packages if params[:include_versionless].present?
-
- packages.has_version
- end
end
end
diff --git a/app/finders/packages/nuget/package_finder.rb b/app/finders/packages/nuget/package_finder.rb
index 8f585f045a1..2f66bd145ee 100644
--- a/app/finders/packages/nuget/package_finder.rb
+++ b/app/finders/packages/nuget/package_finder.rb
@@ -5,7 +5,7 @@ module Packages
class PackageFinder
include ::Packages::FinderHelper
- MAX_PACKAGES_COUNT = 50
+ MAX_PACKAGES_COUNT = 300
def initialize(current_user, project_or_group, package_name:, package_version: nil, limit: MAX_PACKAGES_COUNT)
@current_user = current_user
diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb
index 72a63224d2f..bd9e62e3f2a 100644
--- a/app/finders/packages/packages_finder.rb
+++ b/app/finders/packages/packages_finder.rb
@@ -2,7 +2,7 @@
module Packages
class PackagesFinder
- attr_reader :params, :project
+ include ::Packages::FinderHelper
def initialize(project, params = {})
@project = project
@@ -21,29 +21,14 @@ module Packages
packages = filter_with_version(packages)
packages = filter_by_package_type(packages)
packages = filter_by_package_name(packages)
+ packages = filter_by_status(packages)
packages = order_packages(packages)
packages
end
private
- def filter_with_version(packages)
- return packages if params[:include_versionless].present?
-
- packages.has_version
- end
-
- def filter_by_package_type(packages)
- return packages unless params[:package_type]
-
- packages.with_package_type(params[:package_type])
- end
-
- def filter_by_package_name(packages)
- return packages unless params[:package_name]
-
- packages.search_by_name(params[:package_name])
- end
+ attr_reader :params, :project
def order_packages(packages)
packages.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
diff --git a/app/finders/repositories/commits_with_trailer_finder.rb b/app/finders/repositories/commits_with_trailer_finder.rb
new file mode 100644
index 00000000000..4bd643c345b
--- /dev/null
+++ b/app/finders/repositories/commits_with_trailer_finder.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module Repositories
+ # Finder for obtaining commits between two refs, with a Git trailer set.
+ class CommitsWithTrailerFinder
+ # The maximum number of commits to retrieve per page.
+ #
+ # This value is arbitrarily chosen. Lowering it means more Gitaly calls, but
+ # less data being loaded into memory at once. Increasing it has the opposite
+ # effect.
+ #
+ # This amount is based around the number of commits that usually go in a
+ # GitLab release. Some examples for GitLab's own releases:
+ #
+ # * 13.6.0: 4636 commits
+ # * 13.5.0: 5912 commits
+ # * 13.4.0: 5541 commits
+ #
+ # Using this limit should result in most (very large) projects only needing
+ # 5-10 Gitaly calls, while keeping memory usage at a reasonable amount.
+ COMMITS_PER_PAGE = 1024
+
+ # The `project` argument specifies the project for which to obtain the
+ # commits.
+ #
+ # The `from` and `to` arguments specify the range of commits to include. The
+ # commit specified in `from` won't be included itself. The commit specified
+ # in `to` _is_ included.
+ #
+ # The `per_page` argument specifies how many commits are retrieved in a single
+ # Gitaly API call.
+ def initialize(project:, from:, to:, per_page: COMMITS_PER_PAGE)
+ @project = project
+ @from = from
+ @to = to
+ @per_page = per_page
+ end
+
+ # Fetches all commits that have the given trailer set.
+ #
+ # The commits are yielded to the supplied block in batches. This allows
+ # other code to process these commits in batches too, instead of first
+ # having to load all commits into memory.
+ #
+ # Example:
+ #
+ # CommitsWithTrailerFinder.new(...).each_page('Signed-off-by') do |commits|
+ # commits.each do |commit|
+ # ...
+ # end
+ # end
+ def each_page(trailer)
+ return to_enum(__method__, trailer) unless block_given?
+
+ offset = 0
+ response = fetch_commits
+
+ while response.any?
+ commits = []
+
+ response.each do |commit|
+ commits.push(commit) if commit.trailers.key?(trailer)
+ end
+
+ yield commits
+
+ offset += response.length
+ response = fetch_commits(offset)
+ end
+ end
+
+ private
+
+ def fetch_commits(offset = 0)
+ range = "#{@from}..#{@to}"
+
+ @project
+ .repository
+ .commits(range, limit: @per_page, offset: offset, trailers: true)
+ end
+ end
+end
diff --git a/app/finders/repositories/previous_tag_finder.rb b/app/finders/repositories/previous_tag_finder.rb
new file mode 100644
index 00000000000..150a6332c29
--- /dev/null
+++ b/app/finders/repositories/previous_tag_finder.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Repositories
+ # A finder class for getting the tag of the last release before a given
+ # version.
+ #
+ # Imagine a project with the following tags:
+ #
+ # * v1.0.0
+ # * v1.1.0
+ # * v2.0.0
+ #
+ # If the version supplied is 2.1.0, the tag returned will be v2.0.0. And when
+ # the version is 1.1.1, or 1.2.0, the returned tag will be v1.1.0.
+ #
+ # This finder expects that all tags to consider meet the following
+ # requirements:
+ #
+ # * They start with the letter "v"
+ # * They use semantic versioning for the tag format
+ #
+ # Tags not meeting these requirements are ignored.
+ class PreviousTagFinder
+ TAG_REGEX = /\Av(?<version>#{Gitlab::Regex.unbounded_semver_regex})\z/.freeze
+
+ def initialize(project)
+ @project = project
+ end
+
+ def execute(new_version)
+ tags = {}
+ versions = [new_version]
+
+ @project.repository.tags.each do |tag|
+ matches = tag.name.match(TAG_REGEX)
+
+ next unless matches
+
+ version = matches[:version]
+ tags[version] = tag
+ versions << version
+ end
+
+ VersionSorter.sort!(versions)
+
+ index = versions.index(new_version)
+
+ tags[versions[index - 1]] if index&.positive?
+ end
+ end
+end
diff --git a/app/finders/template_finder.rb b/app/finders/template_finder.rb
index dac7c526474..36f8d144908 100644
--- a/app/finders/template_finder.rb
+++ b/app/finders/template_finder.rb
@@ -21,6 +21,18 @@ class TemplateFinder
new(type, project, params)
end
end
+
+ def all_template_names(project, type)
+ return {} if !VENDORED_TEMPLATES.key?(type.to_s) && type.to_s != 'licenses'
+
+ build(type, project).template_names
+ end
+
+ # This is issues and merge requests description templates only.
+ # This will be removed once we introduce group level inherited templates
+ def all_template_names_array(project, type)
+ all_template_names(project, type).values.flatten.uniq
+ end
end
attr_reader :type, :project, :params
@@ -43,6 +55,10 @@ class TemplateFinder
vendored_templates.all(project)
end
end
+
+ def template_names
+ vendored_templates.template_names(project)
+ end
end
TemplateFinder.prepend_if_ee('::EE::TemplateFinder')
diff --git a/app/finders/terraform/states_finder.rb b/app/finders/terraform/states_finder.rb
new file mode 100644
index 00000000000..bbe90fead2b
--- /dev/null
+++ b/app/finders/terraform/states_finder.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Terraform
+ class StatesFinder
+ def initialize(project, current_user, params: {})
+ @project = project
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ return ::Terraform::State.none unless can_read_terraform_states?
+
+ states = project.terraform_states
+ states = states.with_name(params[:name]) if params[:name].present?
+
+ states.ordered_by_name
+ end
+
+ private
+
+ attr_reader :project, :current_user, :params
+
+ def can_read_terraform_states?
+ current_user.can?(:read_terraform_state, project)
+ end
+ end
+end
diff --git a/app/finders/user_recent_events_finder.rb b/app/finders/user_recent_events_finder.rb
index f376b26ab9c..596a413782e 100644
--- a/app/finders/user_recent_events_finder.rb
+++ b/app/finders/user_recent_events_finder.rb
@@ -15,40 +15,47 @@ class UserRecentEventsFinder
requires_cross_project_access
- attr_reader :current_user, :target_user, :params
+ attr_reader :current_user, :target_user, :params, :event_filter
DEFAULT_LIMIT = 20
MAX_LIMIT = 100
- def initialize(current_user, target_user, params = {})
+ def initialize(current_user, target_user, event_filter, params = {})
@current_user = current_user
@target_user = target_user
@params = params
+ @event_filter = event_filter || EventFilter.new(EventFilter::ALL)
end
- # rubocop: disable CodeReuse/ActiveRecord
def execute
+ if target_user.is_a? User
+ execute_single
+ else
+ execute_multi
+ end
+ end
+
+ private
+
+ def execute_single
return Event.none unless can?(current_user, :read_user_profile, target_user)
- recent_events(params[:offset] || 0)
- .joins(:project)
+ event_filter.apply_filter(target_events
.with_associations
.limit_recent(limit, params[:offset])
+ .order_created_desc)
end
- # rubocop: enable CodeReuse/ActiveRecord
-
- private
# rubocop: disable CodeReuse/ActiveRecord
- def recent_events(offset)
- sql = <<~SQL
- (#{projects}) AS projects_for_join
- JOIN (#{target_events.to_sql}) AS #{Event.table_name}
- ON #{Event.table_name}.project_id = projects_for_join.id
- SQL
+ def execute_multi
+ users = []
+ @target_user.each do |user|
+ users.append(user.id) if can?(current_user, :read_user_profile, user)
+ end
+
+ return Event.none if users.empty?
- # Workaround for https://github.com/rails/rails/issues/24193
- Event.from([Arel.sql(sql)])
+ event_filter.apply_filter(Event.where(author: users).limit_recent(limit, params[:offset] || 0))
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -58,10 +65,6 @@ class UserRecentEventsFinder
end
# rubocop: enable CodeReuse/ActiveRecord
- def projects
- target_user.project_interactions.to_sql
- end
-
def limit
return DEFAULT_LIMIT unless params[:limit].present?