File: projects_finder.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (99 lines) | stat: -rw-r--r-- 2,575 bytes parent folder | download
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# frozen_string_literal: true

# Namespaces::ProjectsFinder
#
# Used to filter Projects by set of params
#
# Arguments:
#   current_user
#   namespace
#   params:
#     sort: string
#     search: string
#     include_subgroups: boolean
#     include_archived: boolean
#     ids: int[]
#     with_issues_enabled: boolean
#     with_merge_requests_enabled: boolean
#
module Namespaces
  class ProjectsFinder
    def initialize(namespace: nil, current_user: nil, params: {})
      @namespace = namespace
      @current_user = current_user
      @params = params
    end

    def execute
      return Project.none if namespace.nil?

      container = if params[:include_sibling_projects] && namespace.is_a?(ProjectNamespace)
                    namespace.group
                  else
                    namespace
                  end

      collection = if params[:include_subgroups].present?
                     container.all_projects.with_route
                   else
                     container.projects.with_route
                   end

      collection = collection.not_aimed_for_deletion if params[:not_aimed_for_deletion].present?

      collection = filter_projects(collection)

      sort(collection)
    end

    private

    attr_reader :namespace, :params, :current_user

    def filter_projects(collection)
      collection = by_ids(collection)
      collection = by_archived(collection)
      collection = by_similarity(collection)
      by_feature_availability(collection)
    end

    def by_ids(items)
      return items unless params[:ids].present?

      items.id_in(params[:ids])
    end

    def by_archived(items)
      return items if Gitlab::Utils.to_boolean(params[:include_archived], default: true)

      items.non_archived
    end

    def by_similarity(items)
      return items unless params[:search].present?

      items.merge(Project.search(params[:search]))
    end

    def by_feature_availability(items)
      items = items.with_issues_available_for_user(current_user) if params[:with_issues_enabled].present?
      if params[:with_merge_requests_enabled].present?
        items = items.with_merge_requests_available_for_user(current_user)
      end

      items
    end

    def sort(items)
      return items.projects_order_id_desc unless params[:sort]

      if params[:sort] == :similarity && params[:search].present?
        return items.sorted_by_similarity_desc(params[:search])
      end

      items.sort_by_attribute(params[:sort])
    end
  end
end

Namespaces::ProjectsFinder.prepend_mod_with('Namespaces::ProjectsFinder')