From d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 20 Oct 2021 08:43:02 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-4-stable-ee --- .../ci/pipelines_for_merge_request_finder.rb | 17 +++++++-- app/finders/clusters/agents_finder.rb | 28 +++++++++++++++ app/finders/concerns/packages/finder_helper.rb | 6 ++++ app/finders/error_tracking/errors_finder.rb | 7 ++-- app/finders/issuable_finder.rb | 7 ++-- app/finders/issuables/label_filter.rb | 42 ++++++++++++++++------ app/finders/issues_finder.rb | 13 +++++++ app/finders/members_finder.rb | 15 +++++--- app/finders/packages/group_packages_finder.rb | 4 +-- .../members/effective_access_level_finder.rb | 2 +- app/finders/projects/topics_finder.rb | 29 +++++++++++++++ app/finders/projects_finder.rb | 4 +-- app/finders/tags_finder.rb | 5 ++- 13 files changed, 149 insertions(+), 30 deletions(-) create mode 100644 app/finders/clusters/agents_finder.rb create mode 100644 app/finders/projects/topics_finder.rb (limited to 'app/finders') diff --git a/app/finders/ci/pipelines_for_merge_request_finder.rb b/app/finders/ci/pipelines_for_merge_request_finder.rb index 5d794c0903a..9476c30f525 100644 --- a/app/finders/ci/pipelines_for_merge_request_finder.rb +++ b/app/finders/ci/pipelines_for_merge_request_finder.rb @@ -5,6 +5,8 @@ module Ci class PipelinesForMergeRequestFinder include Gitlab::Utils::StrongMemoize + COMMITS_LIMIT = 100 + def initialize(merge_request, current_user) @merge_request = merge_request @current_user = current_user @@ -12,7 +14,7 @@ module Ci attr_reader :merge_request, :current_user - delegate :commit_shas, :target_project, :source_project, :source_branch, to: :merge_request + delegate :recent_diff_head_shas, :commit_shas, :target_project, :source_project, :source_branch, to: :merge_request # Fetch all pipelines that the user can read. def execute @@ -35,7 +37,7 @@ module Ci pipelines = if merge_request.persisted? - pipelines_using_cte + all_pipelines_for_merge_request else triggered_for_branch.for_sha(commit_shas) end @@ -79,6 +81,17 @@ module Ci pipelines.joins(shas_table) # rubocop: disable CodeReuse/ActiveRecord end + def all_pipelines_for_merge_request + if Feature.enabled?(:decomposed_ci_query_in_pipelines_for_merge_request_finder, target_project, default_enabled: :yaml) + pipelines_for_merge_request = triggered_by_merge_request + pipelines_for_branch = triggered_for_branch.for_sha(recent_diff_head_shas(COMMITS_LIMIT)) + + Ci::Pipeline.from_union([pipelines_for_merge_request, pipelines_for_branch]) + else + pipelines_using_cte + end + end + # NOTE: this method returns only parent merge request pipelines. # Child merge request pipelines have a different source. def triggered_by_merge_request diff --git a/app/finders/clusters/agents_finder.rb b/app/finders/clusters/agents_finder.rb new file mode 100644 index 00000000000..136bbf16981 --- /dev/null +++ b/app/finders/clusters/agents_finder.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Clusters + class AgentsFinder + def initialize(project, current_user, params: {}) + @project = project + @current_user = current_user + @params = params + end + + def execute + return ::Clusters::Agent.none unless can_read_cluster_agents? + + agents = project.cluster_agents + agents = agents.with_name(params[:name]) if params[:name].present? + + agents.ordered_by_name + end + + private + + attr_reader :project, :current_user, :params + + def can_read_cluster_agents? + current_user.can?(:read_cluster, project) + end + end +end diff --git a/app/finders/concerns/packages/finder_helper.rb b/app/finders/concerns/packages/finder_helper.rb index d2784a1d270..0ae99782cd3 100644 --- a/app/finders/concerns/packages/finder_helper.rb +++ b/app/finders/concerns/packages/finder_helper.rb @@ -54,6 +54,12 @@ module Packages packages.search_by_name(params[:package_name]) end + def filter_by_exact_package_name(packages) + return packages unless params[:package_name].present? + + packages.with_name(params[:package_name]) + end + def filter_by_package_version(packages) return packages unless params[:package_version].present? diff --git a/app/finders/error_tracking/errors_finder.rb b/app/finders/error_tracking/errors_finder.rb index d83a0c487e6..c361d6e2fc2 100644 --- a/app/finders/error_tracking/errors_finder.rb +++ b/app/finders/error_tracking/errors_finder.rb @@ -15,8 +15,7 @@ module ErrorTracking collection = by_status(collection) collection = sort(collection) - # Limit collection until pagination implemented. - limit(collection) + collection.keyset_paginate(cursor: params[:cursor], per_page: limit) end private @@ -39,9 +38,9 @@ module ErrorTracking params[:sort] ? collection.sort_by_attribute(params[:sort]) : collection.order_id_desc end - def limit(collection) + def limit # Restrict the maximum limit at 100 records. - collection.limit([(params[:limit] || 20).to_i, 100].min) + [(params[:limit] || 20).to_i, 100].min end end end diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index cf706a8f98e..7b0cd17a761 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -194,8 +194,7 @@ class IssuableFinder def use_cte_for_search? strong_memoize(:use_cte_for_search) do next false unless search - # Only simple unsorted & simple sorts can use CTE - next false if params[:sort].present? && !params[:sort].in?(klass.simple_sorts.keys) + next false unless default_or_simple_sort? attempt_group_search_optimizations? || attempt_project_search_optimizations? end @@ -244,6 +243,10 @@ class IssuableFinder klass.all end + def default_or_simple_sort? + params[:sort].blank? || params[:sort].to_s.in?(klass.simple_sorts.keys) + end + def attempt_group_search_optimizations? params[:attempt_group_search_optimizations] end diff --git a/app/finders/issuables/label_filter.rb b/app/finders/issuables/label_filter.rb index 2bbc963aa90..f4712fa6879 100644 --- a/app/finders/issuables/label_filter.rb +++ b/app/finders/issuables/label_filter.rb @@ -89,17 +89,25 @@ module Issuables end # rubocop: enable CodeReuse/ActiveRecord - # rubocop: disable CodeReuse/ActiveRecord def find_label_ids(label_names) - group_labels = Label - .where(project_id: nil) - .where(title: label_names) - .where(group_id: root_namespace.self_and_descendant_ids) + find_label_ids_uncached(label_names) + end + # Avoid repeating label queries times when the finder is instantiated multiple times during the request. + request_cache(:find_label_ids) { root_namespace.id } - project_labels = Label - .where(group_id: nil) - .where(title: label_names) - .where(project_id: Project.select(:id).where(namespace_id: root_namespace.self_and_descendant_ids)) + # This returns an array of label IDs per label name. It is possible for a label name + # to have multiple IDs because we allow labels with the same name if they are on a different + # project or group. + # + # For example, if we pass in `['bug', 'feature']`, this will return something like: + # `[ [1, 2], [3] ]` + # + # rubocop: disable CodeReuse/ActiveRecord + def find_label_ids_uncached(label_names) + return [] if label_names.empty? + + group_labels = group_labels_for_root_namespace.where(title: label_names) + project_labels = project_labels_for_root_namespace.where(title: label_names) Label .from_union([group_labels, project_labels], remove_duplicates: false) @@ -109,8 +117,18 @@ module Issuables .values .map { |labels| labels.map(&:last) } end - # Avoid repeating label queries times when the finder is instantiated multiple times during the request. - request_cache(:find_label_ids) { root_namespace.id } + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord + def group_labels_for_root_namespace + Label.where(project_id: nil).where(group_id: root_namespace.self_and_descendant_ids) + end + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord + def project_labels_for_root_namespace + Label.where(group_id: nil).where(project_id: Project.select(:id).where(namespace_id: root_namespace.self_and_descendant_ids)) + end # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord @@ -153,3 +171,5 @@ module Issuables end end end + +Issuables::LabelFilter.prepend_mod diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index abf0c180d6b..21a19aa22a1 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -91,6 +91,12 @@ class IssuesFinder < IssuableFinder by_issue_types(issues) end + # Negates all params found in `negatable_params` + def filter_negated_items(items) + issues = super + by_negated_issue_types(issues) + end + def by_confidential(items) return items if params[:confidential].nil? @@ -122,6 +128,13 @@ class IssuesFinder < IssuableFinder items.with_issue_type(params[:issue_types]) end + + def by_negated_issue_types(items) + issue_type_params = Array(not_params[:issue_types]).map(&:to_s) & WorkItem::Type.base_types.keys + return items if issue_type_params.blank? + + items.without_issue_type(issue_type_params) + end end IssuesFinder.prepend_mod_with('IssuesFinder') diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb index ea101cf1dcd..0faafa6df9c 100644 --- a/app/finders/members_finder.rb +++ b/app/finders/members_finder.rb @@ -70,11 +70,16 @@ class MembersFinder end def project_invited_groups - invited_groups_ids_including_ancestors = Gitlab::ObjectHierarchy - .new(project.invited_groups) - .base_and_ancestors - .public_or_visible_to_user(current_user) - .select(:id) + invited_groups_and_ancestors = if ::Feature.enabled?(:linear_members_finder_ancestor_scopes, current_user, default_enabled: :yaml) + project.invited_groups + .self_and_ancestors + else + Gitlab::ObjectHierarchy + .new(project.invited_groups) + .base_and_ancestors + end + + invited_groups_ids_including_ancestors = invited_groups_and_ancestors.public_or_visible_to_user(current_user).select(:id) GroupMember.with_source_id(invited_groups_ids_including_ancestors).non_minimal_access end diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb index e753fa4d455..3ac5f00d518 100644 --- a/app/finders/packages/group_packages_finder.rb +++ b/app/finders/packages/group_packages_finder.rb @@ -4,7 +4,7 @@ module Packages class GroupPackagesFinder include ::Packages::FinderHelper - def initialize(current_user, group, params = { exclude_subgroups: false, order_by: 'created_at', sort: 'asc' }) + def initialize(current_user, group, params = { exclude_subgroups: false, exact_name: false, order_by: 'created_at', sort: 'asc' }) @current_user = current_user @group = group @params = params @@ -30,7 +30,7 @@ module Packages packages = filter_with_version(packages) packages = filter_by_package_type(packages) - packages = filter_by_package_name(packages) + packages = (params[:exact_name] ? filter_by_exact_package_name(packages) : filter_by_package_name(packages)) packages = filter_by_package_version(packages) installable_only ? packages.installable : filter_by_status(packages) end diff --git a/app/finders/projects/members/effective_access_level_finder.rb b/app/finders/projects/members/effective_access_level_finder.rb index c1e3842a9e4..d238679f2fb 100644 --- a/app/finders/projects/members/effective_access_level_finder.rb +++ b/app/finders/projects/members/effective_access_level_finder.rb @@ -99,7 +99,7 @@ module Projects end def include_membership_from_project_group_shares? - project.allowed_to_share_with_group? && project.project_group_links.any? + !project.namespace.share_with_group_lock && project.project_group_links.any? end # methods for `select` options diff --git a/app/finders/projects/topics_finder.rb b/app/finders/projects/topics_finder.rb new file mode 100644 index 00000000000..7c3abc27cf7 --- /dev/null +++ b/app/finders/projects/topics_finder.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Used to filter project topics by a set of params +# +# Arguments: +# params: +# search: string +module Projects + class TopicsFinder + def initialize(params: {}) + @params = params + end + + def execute + topics = Projects::Topic.order_by_total_projects_count + by_search(topics) + end + + private + + attr_reader :current_user, :params + + def by_search(topics) + return topics unless params[:search].present? + + topics.search(params[:search]).reorder_by_similarity(params[:search]) + end + end +end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 5537058cc79..7245bb36ac9 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -182,8 +182,8 @@ class ProjectsFinder < UnionFinder def by_topics(items) return items unless params[:topic].present? - topics = params[:topic].instance_of?(String) ? params[:topic].strip.split(/\s*,\s*/) : params[:topic] - topics.each do |topic| + topics = params[:topic].instance_of?(String) ? params[:topic].split(',') : params[:topic] + topics.map(&:strip).uniq.reject(&:empty?).each do |topic| items = items.with_topic(topic) end diff --git a/app/finders/tags_finder.rb b/app/finders/tags_finder.rb index d9848d027cf..0ccbbdc1b87 100644 --- a/app/finders/tags_finder.rb +++ b/app/finders/tags_finder.rb @@ -7,6 +7,9 @@ class TagsFinder < GitRefsFinder def execute tags = repository.tags_sorted_by(sort) - by_search(tags) + + [by_search(tags), nil] + rescue Gitlab::Git::CommandError => e + [[], e] end end -- cgit v1.2.1