Skip to content
Snippets Groups Projects
Commit c8706c80 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets Committed by Heinrich Lee Yu
Browse files

Move environments finders under namespace

parent 7afa7c80
No related branches found
No related tags found
No related merge requests found
Showing
with 208 additions and 205 deletions
Loading
Loading
@@ -1546,9 +1546,6 @@ Gitlab/NamespacedClass:
- 'app/finders/context_commits_finder.rb'
- 'app/finders/contributed_projects_finder.rb'
- 'app/finders/deployments_finder.rb'
- 'app/finders/environment_names_finder.rb'
- 'app/finders/environments_finder.rb'
- 'app/finders/environments_by_deployments_finder.rb'
- 'app/finders/events_finder.rb'
- 'app/finders/feature_flags_finder.rb'
- 'app/finders/feature_flags_user_lists_finder.rb'
Loading
Loading
Loading
Loading
@@ -197,7 +197,7 @@ def download_export
def unfoldered_environment_names
respond_to do |format|
format.json do
render json: EnvironmentNamesFinder.new(@group, current_user).execute
render json: Environments::EnvironmentNamesFinder.new(@group, current_user).execute
end
end
end
Loading
Loading
Loading
Loading
@@ -20,7 +20,7 @@ def show
 
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit }
environment_params[:find_latest] = true
@environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
@environment = Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
 
@blame = Gitlab::Blame.new(@blob, @commit)
@blame = Gitlab::View::Presenter::Factory.new(@blame, project: @project, path: @path).fabricate!
Loading
Loading
Loading
Loading
@@ -214,7 +214,7 @@ def set_last_commit_sha
def show_html
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit }
environment_params[:find_latest] = true
@environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
@environment = Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
@last_commit = @repository.last_commit_for_path(@commit.id, @blob.path, literal_pathspec: true)
@code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path)
 
Loading
Loading
Loading
Loading
@@ -167,7 +167,7 @@ def define_commit_vars
@diffs = commit.diffs(opts)
@notes_count = commit.notes.count
 
@environment = EnvironmentsByDeploymentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last
@environment = Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last
end
 
# rubocop: disable CodeReuse/ActiveRecord
Loading
Loading
Loading
Loading
@@ -136,7 +136,7 @@ def define_environment
if compare
environment_params = source_project.repository.branch_exists?(head_ref) ? { ref: head_ref } : { commit: compare.commit }
environment_params[:find_latest] = true
@environment = EnvironmentsByDeploymentsFinder.new(source_project, current_user, environment_params).execute.last
@environment = Environments::EnvironmentsByDeploymentsFinder.new(source_project, current_user, environment_params).execute.last
end
end
 
Loading
Loading
Loading
Loading
@@ -58,7 +58,7 @@ def elasticsearch_params
def environment
strong_memoize(:environment) do
if cluster_params.key?(:environment_name)
EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first
::Environments::EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first
else
project.default_environment
end
Loading
Loading
Loading
Loading
@@ -311,7 +311,7 @@ def resolve
def unfoldered_environment_names
respond_to do |format|
format.json do
render json: EnvironmentNamesFinder.new(@project, current_user).execute
render json: Environments::EnvironmentNamesFinder.new(@project, current_user).execute
end
end
end
Loading
Loading
# frozen_string_literal: true
# Finder for obtaining the unique environment names of a project or group.
#
# This finder exists so that the merge requests "environments" filter can be
# populated with a unique list of environment names. If we retrieve _just_ the
# environments, duplicates may be present (e.g. multiple projects in a group
# having a "staging" environment).
#
# In addition, this finder only produces unfoldered environments. We do this
# because when searching for environments we want to exclude review app
# environments.
class EnvironmentNamesFinder
attr_reader :project_or_group, :current_user
def initialize(project_or_group, current_user = nil)
@project_or_group = project_or_group
@current_user = current_user
end
def execute
all_environments.unfoldered.order_by_name.pluck_unique_names
end
def all_environments
if project_or_group.is_a?(Namespace)
namespace_environments
else
project_environments
end
end
def namespace_environments
# We assume reporter access is needed for the :read_environment permission
# here. This expection is also present in
# IssuableFinder::Params#min_access_level, which is used for filtering out
# merge requests that don't have the right permissions.
#
# We use this approach so we don't need to load every project into memory
# just to verify if we can see their environments. Doing so would not be
# efficient, and possibly mess up pagination if certain projects are not
# meant to be visible.
projects = project_or_group
.all_projects
.public_or_visible_to_user(current_user, Gitlab::Access::REPORTER)
Environment.for_project(projects)
end
def project_environments
if Ability.allowed?(current_user, :read_environment, project_or_group)
project_or_group.environments
else
Environment.none
end
end
end
# frozen_string_literal: true
module Environments
# Finder for obtaining the unique environment names of a project or group.
#
# This finder exists so that the merge requests "environments" filter can be
# populated with a unique list of environment names. If we retrieve _just_ the
# environments, duplicates may be present (e.g. multiple projects in a group
# having a "staging" environment).
#
# In addition, this finder only produces unfoldered environments. We do this
# because when searching for environments we want to exclude review app
# environments.
class EnvironmentNamesFinder
attr_reader :project_or_group, :current_user
def initialize(project_or_group, current_user = nil)
@project_or_group = project_or_group
@current_user = current_user
end
def execute
all_environments.unfoldered.order_by_name.pluck_unique_names
end
def all_environments
if project_or_group.is_a?(Namespace)
namespace_environments
else
project_environments
end
end
def namespace_environments
# We assume reporter access is needed for the :read_environment permission
# here. This expection is also present in
# IssuableFinder::Params#min_access_level, which is used for filtering out
# merge requests that don't have the right permissions.
#
# We use this approach so we don't need to load every project into memory
# just to verify if we can see their environments. Doing so would not be
# efficient, and possibly mess up pagination if certain projects are not
# meant to be visible.
projects = project_or_group
.all_projects
.public_or_visible_to_user(current_user, Gitlab::Access::REPORTER)
Environment.for_project(projects)
end
def project_environments
if Ability.allowed?(current_user, :read_environment, project_or_group)
project_or_group.environments
else
Environment.none
end
end
end
end
# frozen_string_literal: true
module Environments
class EnvironmentsByDeploymentsFinder
attr_reader :project, :current_user, :params
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
@params = params
end
# rubocop: disable CodeReuse/ActiveRecord
def execute
deployments = project.deployments
deployments =
if ref
deployments_query = params[:with_tags] ? 'ref = :ref OR tag IS TRUE' : 'ref = :ref'
deployments.where(deployments_query, ref: ref.to_s)
elsif commit
deployments.where(sha: commit.sha)
else
deployments.none
end
environment_ids = deployments
.group(:environment_id)
.select(:environment_id)
environments = project.environments.available
.where(id: environment_ids)
if params[:find_latest]
find_one(environments.order_by_last_deployed_at_desc)
else
find_all(environments.order_by_last_deployed_at.to_a)
end
end
# rubocop: enable CodeReuse/ActiveRecord
private
def find_one(environments)
[environments.find { |environment| valid_environment?(environment) }].compact
end
def find_all(environments)
environments.select { |environment| valid_environment?(environment) }
end
def valid_environment?(environment)
# Go in order of cost: SQL calls are cheaper than Gitaly calls
return false unless Ability.allowed?(current_user, :read_environment, environment)
return false if ref && params[:recently_updated] && !environment.recently_updated_on_branch?(ref)
return false if ref && commit && !environment.includes_commit?(commit)
true
end
def ref
params[:ref].try(:to_s)
end
def commit
params[:commit]
end
end
end
# frozen_string_literal: true
module Environments
class EnvironmentsFinder
attr_reader :project, :current_user, :params
InvalidStatesError = Class.new(StandardError)
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
@params = params
end
def execute
environments = project.environments
environments = by_name(environments)
environments = by_search(environments)
# Raises InvalidStatesError if params[:states] contains invalid states.
by_states(environments)
end
private
def by_name(environments)
if params[:name].present?
environments.for_name(params[:name])
else
environments
end
end
def by_search(environments)
if params[:search].present?
environments.for_name_like(params[:search], limit: nil)
else
environments
end
end
def by_states(environments)
if params[:states].present?
environments_with_states(environments)
else
environments
end
end
def environments_with_states(environments)
# Convert to array of strings
states = Array(params[:states]).map(&:to_s)
raise InvalidStatesError, _('Requested states are invalid') unless valid_states?(states)
environments.with_states(states)
end
def valid_states?(states)
valid_states = Environment.valid_states.map(&:to_s)
(states - valid_states).empty?
end
end
end
# frozen_string_literal: true
class EnvironmentsByDeploymentsFinder
attr_reader :project, :current_user, :params
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
@params = params
end
# rubocop: disable CodeReuse/ActiveRecord
def execute
deployments = project.deployments
deployments =
if ref
deployments_query = params[:with_tags] ? 'ref = :ref OR tag IS TRUE' : 'ref = :ref'
deployments.where(deployments_query, ref: ref.to_s)
elsif commit
deployments.where(sha: commit.sha)
else
deployments.none
end
environment_ids = deployments
.group(:environment_id)
.select(:environment_id)
environments = project.environments.available
.where(id: environment_ids)
if params[:find_latest]
find_one(environments.order_by_last_deployed_at_desc)
else
find_all(environments.order_by_last_deployed_at.to_a)
end
end
# rubocop: enable CodeReuse/ActiveRecord
private
def find_one(environments)
[environments.find { |environment| valid_environment?(environment) }].compact
end
def find_all(environments)
environments.select { |environment| valid_environment?(environment) }
end
def valid_environment?(environment)
# Go in order of cost: SQL calls are cheaper than Gitaly calls
return false unless Ability.allowed?(current_user, :read_environment, environment)
return false if ref && params[:recently_updated] && !environment.recently_updated_on_branch?(ref)
return false if ref && commit && !environment.includes_commit?(commit)
true
end
def ref
params[:ref].try(:to_s)
end
def commit
params[:commit]
end
end
# frozen_string_literal: true
class EnvironmentsFinder
attr_reader :project, :current_user, :params
InvalidStatesError = Class.new(StandardError)
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
@params = params
end
def execute
environments = project.environments
environments = by_name(environments)
environments = by_search(environments)
# Raises InvalidStatesError if params[:states] contains invalid states.
by_states(environments)
end
private
def by_name(environments)
if params[:name].present?
environments.for_name(params[:name])
else
environments
end
end
def by_search(environments)
if params[:search].present?
environments.for_name_like(params[:search], limit: nil)
else
environments
end
end
def by_states(environments)
if params[:states].present?
environments_with_states(environments)
else
environments
end
end
def environments_with_states(environments)
# Convert to array of strings
states = Array(params[:states]).map(&:to_s)
raise InvalidStatesError, _('Requested states are invalid') unless valid_states?(states)
environments.with_states(states)
end
def valid_states?(states)
valid_states = Environment.valid_states.map(&:to_s)
(states - valid_states).empty?
end
end
Loading
Loading
@@ -21,8 +21,8 @@ class EnvironmentsResolver < BaseResolver
def resolve(**args)
return unless project.present?
 
EnvironmentsFinder.new(project, context[:current_user], args).execute
rescue EnvironmentsFinder::InvalidStatesError => exception
Environments::EnvironmentsFinder.new(project, context[:current_user], args).execute
rescue Environments::EnvironmentsFinder::InvalidStatesError => exception
raise Gitlab::Graphql::Errors::ArgumentError, exception.message
end
end
Loading
Loading
Loading
Loading
@@ -1367,11 +1367,11 @@ def mergeable_ci_state?
def environments_for(current_user, latest: false)
return [] unless diff_head_commit
 
envs = EnvironmentsByDeploymentsFinder.new(target_project, current_user,
envs = Environments::EnvironmentsByDeploymentsFinder.new(target_project, current_user,
ref: target_branch, commit: diff_head_commit, with_tags: true, find_latest: latest).execute
 
if source_project
envs.concat EnvironmentsByDeploymentsFinder.new(source_project, current_user,
envs.concat Environments::EnvironmentsByDeploymentsFinder.new(source_project, current_user,
ref: source_branch, commit: diff_head_commit, find_latest: latest).execute
end
 
Loading
Loading
Loading
Loading
@@ -35,7 +35,7 @@ def self.execute_in_batch(environments)
private
 
def environments
@environments ||= EnvironmentsByDeploymentsFinder
@environments ||= Environments::EnvironmentsByDeploymentsFinder
.new(project, current_user, ref: @ref, recently_updated: true)
.execute
end
Loading
Loading
Loading
Loading
@@ -84,7 +84,7 @@ def alerts_by_identifier(environment)
 
def environment
strong_memoize(:environment) do
EnvironmentsFinder.new(project, nil, name: 'production').execute.first ||
Environments::EnvironmentsFinder.new(project, nil, name: 'production').execute.first ||
project.environments.first
end
end
Loading
Loading
Loading
Loading
@@ -26,7 +26,7 @@ class Environments < ::API::Base
get ':id/environments' do
authorize! :read_environment, user_project
 
environments = ::EnvironmentsFinder.new(user_project, current_user, params).execute
environments = ::Environments::EnvironmentsFinder.new(user_project, current_user, params).execute
 
present paginate(environments), with: Entities::Environment, current_user: current_user
end
Loading
Loading
Loading
Loading
@@ -130,7 +130,7 @@ def environment
strong_memoize(:environment) do
next unless environment_name
 
EnvironmentsFinder
::Environments::EnvironmentsFinder
.new(project, nil, { name: environment_name })
.execute
.first
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment