2018-09-29 18:34:47 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-05-14 08:33:31 -04:00
|
|
|
module API
|
2012-06-27 07:32:56 -04:00
|
|
|
module Entities
|
2017-08-15 13:44:37 -04:00
|
|
|
class Project < BasicProjectDetails
|
2017-07-25 05:35:45 -04:00
|
|
|
include ::API::Helpers::RelatedResourcesHelpers
|
|
|
|
|
2021-03-03 07:11:16 -05:00
|
|
|
expose :container_registry_url, as: :container_registry_image_prefix, if: -> (_, _) { Gitlab.config.registry.enabled }
|
|
|
|
|
2017-07-25 05:35:45 -04:00
|
|
|
expose :_links do
|
|
|
|
expose :self do |project|
|
|
|
|
expose_url(api_v4_projects_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
2018-05-03 12:15:48 -04:00
|
|
|
expose :issues, if: -> (project, options) { issues_available?(project, options) } do |project|
|
2017-07-25 05:35:45 -04:00
|
|
|
expose_url(api_v4_projects_issues_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
2018-05-03 12:15:48 -04:00
|
|
|
expose :merge_requests, if: -> (project, options) { mrs_available?(project, options) } do |project|
|
2017-07-25 05:35:45 -04:00
|
|
|
expose_url(api_v4_projects_merge_requests_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :repo_branches do |project|
|
|
|
|
expose_url(api_v4_projects_repository_branches_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :labels do |project|
|
|
|
|
expose_url(api_v4_projects_labels_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :events do |project|
|
|
|
|
expose_url(api_v4_projects_events_path(id: project.id))
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :members do |project|
|
|
|
|
expose_url(api_v4_projects_members_path(id: project.id))
|
|
|
|
end
|
2022-04-20 20:10:20 -04:00
|
|
|
|
|
|
|
expose :cluster_agents do |project|
|
|
|
|
expose_url(api_v4_projects_cluster_agents_path(id: project.id))
|
|
|
|
end
|
2017-07-25 05:35:45 -04:00
|
|
|
end
|
|
|
|
|
2020-07-21 08:09:30 -04:00
|
|
|
expose :packages_enabled
|
2019-05-29 08:13:27 -04:00
|
|
|
expose :empty_repo?, as: :empty_repo
|
2014-04-18 11:55:06 -04:00
|
|
|
expose :archived?, as: :archived
|
2017-08-03 03:43:24 -04:00
|
|
|
expose :visibility
|
2014-03-17 08:33:41 -04:00
|
|
|
expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group }
|
2017-09-01 18:39:22 -04:00
|
|
|
expose :resolve_outdated_diff_discussions
|
2020-01-08 16:08:08 -05:00
|
|
|
expose :container_expiration_policy, using: Entities::ContainerExpirationPolicy,
|
|
|
|
if: -> (project, _) { project.container_expiration_policy }
|
2016-08-01 18:31:21 -04:00
|
|
|
|
|
|
|
# Expose old field names with the new permissions methods to keep API compatible
|
2019-05-15 07:19:16 -04:00
|
|
|
# TODO: remove in API v5, replaced by *_access_level
|
2016-11-29 14:21:39 -05:00
|
|
|
expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:current_user]) }
|
|
|
|
expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:current_user]) }
|
|
|
|
expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:current_user]) }
|
2017-02-22 05:13:59 -05:00
|
|
|
expose(:jobs_enabled) { |project, options| project.feature_available?(:builds, options[:current_user]) }
|
2016-11-29 14:21:39 -05:00
|
|
|
expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:current_user]) }
|
2021-07-09 05:09:53 -04:00
|
|
|
expose(:container_registry_enabled) { |project, options| project.feature_available?(:container_registry, options[:current_user]) }
|
2020-07-09 05:09:27 -04:00
|
|
|
expose :service_desk_enabled
|
2021-12-06 22:12:22 -05:00
|
|
|
expose :service_desk_address, if: -> (project, options) do
|
|
|
|
Ability.allowed?(options[:current_user], :admin_issue, project)
|
|
|
|
end
|
2016-08-01 18:31:21 -04:00
|
|
|
|
2020-01-30 07:08:54 -05:00
|
|
|
expose(:can_create_merge_request_in) do |project, options|
|
|
|
|
Ability.allowed?(options[:current_user], :create_merge_request_in, project)
|
|
|
|
end
|
|
|
|
|
2019-05-15 07:19:16 -04:00
|
|
|
expose(:issues_access_level) { |project, options| project.project_feature.string_access_level(:issues) }
|
|
|
|
expose(:repository_access_level) { |project, options| project.project_feature.string_access_level(:repository) }
|
|
|
|
expose(:merge_requests_access_level) { |project, options| project.project_feature.string_access_level(:merge_requests) }
|
2020-03-19 14:09:17 -04:00
|
|
|
expose(:forking_access_level) { |project, options| project.project_feature.string_access_level(:forking) }
|
2019-05-15 07:19:16 -04:00
|
|
|
expose(:wiki_access_level) { |project, options| project.project_feature.string_access_level(:wiki) }
|
|
|
|
expose(:builds_access_level) { |project, options| project.project_feature.string_access_level(:builds) }
|
|
|
|
expose(:snippets_access_level) { |project, options| project.project_feature.string_access_level(:snippets) }
|
2020-01-23 07:08:38 -05:00
|
|
|
expose(:pages_access_level) { |project, options| project.project_feature.string_access_level(:pages) }
|
2020-12-16 10:10:18 -05:00
|
|
|
expose(:operations_access_level) { |project, options| project.project_feature.string_access_level(:operations) }
|
2020-12-16 16:09:57 -05:00
|
|
|
expose(:analytics_access_level) { |project, options| project.project_feature.string_access_level(:analytics) }
|
2021-08-02 14:08:48 -04:00
|
|
|
expose(:container_registry_access_level) { |project, options| project.project_feature.string_access_level(:container_registry) }
|
2022-02-25 10:16:30 -05:00
|
|
|
expose(:security_and_compliance_access_level) { |project, options| project.project_feature.string_access_level(:security_and_compliance) }
|
2019-05-15 07:19:16 -04:00
|
|
|
|
2020-02-05 07:09:15 -05:00
|
|
|
expose :emails_disabled
|
2016-09-06 12:48:00 -04:00
|
|
|
expose :shared_runners_enabled
|
|
|
|
expose :lfs_enabled?, as: :lfs_enabled
|
2015-04-10 12:35:05 -04:00
|
|
|
expose :creator_id
|
2019-11-19 11:17:35 -05:00
|
|
|
expose :forked_from_project, using: Entities::BasicProjectDetails, if: ->(project, options) do
|
|
|
|
project.forked? && Ability.allowed?(options[:current_user], :read_project, project.forked_from_project)
|
|
|
|
end
|
2022-01-11 13:16:38 -05:00
|
|
|
expose :mr_default_target_self, if: -> (project) { project.forked? }
|
|
|
|
|
2022-03-22 11:07:25 -04:00
|
|
|
expose :import_url, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } do |project|
|
|
|
|
project[:import_url]
|
|
|
|
end
|
|
|
|
expose :import_type, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) }
|
2017-06-01 10:57:41 -04:00
|
|
|
expose :import_status
|
2018-11-27 04:41:27 -05:00
|
|
|
expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } do |project|
|
|
|
|
project.import_state&.last_error
|
|
|
|
end
|
2017-09-26 04:49:53 -04:00
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) }
|
2016-01-11 09:27:20 -05:00
|
|
|
expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] }
|
2019-06-07 07:51:42 -04:00
|
|
|
expose :ci_default_git_depth
|
2020-10-20 02:09:03 -04:00
|
|
|
expose :ci_forward_deployment_enabled
|
2021-06-14 05:10:15 -04:00
|
|
|
expose :ci_job_token_scope_enabled
|
2017-02-23 03:16:20 -05:00
|
|
|
expose :public_builds, as: :public_jobs
|
2019-05-15 08:35:55 -04:00
|
|
|
expose :build_git_strategy, if: lambda { |project, options| options[:user_can_admin_project] } do |project, options|
|
|
|
|
project.build_allow_git_fetch ? 'fetch' : 'clone'
|
|
|
|
end
|
2019-05-15 09:32:18 -04:00
|
|
|
expose :build_timeout
|
2019-05-15 10:17:25 -04:00
|
|
|
expose :auto_cancel_pending_pipelines
|
2019-01-30 23:21:35 -05:00
|
|
|
expose :ci_config_path, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
|
2016-07-08 03:34:36 -04:00
|
|
|
expose :shared_with_groups do |project, options|
|
2021-10-28 14:14:18 -04:00
|
|
|
user = options[:current_user]
|
|
|
|
|
|
|
|
SharedGroupWithProject.represent(project.visible_group_links(for_user: user), options)
|
2016-07-08 03:34:36 -04:00
|
|
|
end
|
2017-02-17 08:56:13 -05:00
|
|
|
expose :only_allow_merge_if_pipeline_succeeds
|
2020-06-10 17:09:29 -04:00
|
|
|
expose :allow_merge_on_skipped_pipeline
|
2021-01-14 07:10:54 -05:00
|
|
|
expose :restrict_user_defined_variables
|
2016-09-14 18:04:27 -04:00
|
|
|
expose :request_access_enabled
|
2016-09-16 07:02:42 -04:00
|
|
|
expose :only_allow_merge_if_all_discussions_are_resolved
|
2019-10-23 17:06:17 -04:00
|
|
|
expose :remove_source_branch_after_merge
|
2017-06-16 14:39:21 -04:00
|
|
|
expose :printing_merge_request_link_enabled
|
2018-04-04 05:56:38 -04:00
|
|
|
expose :merge_method
|
2021-06-12 05:09:51 -04:00
|
|
|
expose :squash_option
|
2020-01-13 07:08:04 -05:00
|
|
|
expose :suggestion_commit_message
|
2021-11-11 04:12:21 -05:00
|
|
|
expose :merge_commit_template
|
2021-11-24 19:10:49 -05:00
|
|
|
expose :squash_commit_template
|
2019-01-30 23:21:35 -05:00
|
|
|
expose :statistics, using: 'API::Entities::ProjectStatistics', if: -> (project, options) {
|
2019-03-22 19:44:35 -04:00
|
|
|
options[:statistics] && Ability.allowed?(options[:current_user], :read_statistics, project)
|
2019-01-30 23:21:35 -05:00
|
|
|
}
|
2019-05-15 10:27:54 -04:00
|
|
|
expose :auto_devops_enabled?, as: :auto_devops_enabled
|
|
|
|
expose :auto_devops_deploy_strategy do |project, options|
|
|
|
|
project.auto_devops.nil? ? 'continuous' : project.auto_devops.deploy_strategy
|
|
|
|
end
|
2020-01-07 19:07:43 -05:00
|
|
|
expose :autoclose_referenced_issues
|
2020-03-02 16:08:01 -05:00
|
|
|
expose :repository_storage, if: ->(project, options) {
|
|
|
|
Ability.allowed?(options[:current_user], :change_repository_storage, project)
|
|
|
|
}
|
2021-06-15 14:09:57 -04:00
|
|
|
expose :keep_latest_artifacts_available?, as: :keep_latest_artifact
|
2022-01-19 07:17:41 -05:00
|
|
|
expose :runner_token_expiration_interval
|
2017-11-30 06:52:38 -05:00
|
|
|
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2021-09-10 05:11:07 -04:00
|
|
|
def self.preload_resource(project)
|
|
|
|
ActiveRecord::Associations::Preloader.new.preload(project, project_group_links: { group: :route })
|
|
|
|
end
|
|
|
|
|
2019-01-16 07:09:29 -05:00
|
|
|
def self.preload_relation(projects_relation, options = {})
|
2021-06-11 02:10:03 -04:00
|
|
|
# Preloading topics, should be done with using only `:topics`,
|
2021-09-28 05:11:19 -04:00
|
|
|
# as `:topics` are defined as: `has_many :topics, through: :project_topics`
|
2021-06-11 02:10:03 -04:00
|
|
|
# N+1 is solved then by using `subject.topics.map(&:name)`
|
2019-09-18 10:02:45 -04:00
|
|
|
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
|
2021-03-31 08:08:55 -04:00
|
|
|
super(projects_relation).preload(group: :namespace_settings)
|
2019-06-07 07:51:42 -04:00
|
|
|
.preload(:ci_cd_settings)
|
2020-06-10 17:09:29 -04:00
|
|
|
.preload(:project_setting)
|
2020-01-08 16:08:08 -05:00
|
|
|
.preload(:container_expiration_policy)
|
2019-05-28 12:09:02 -04:00
|
|
|
.preload(:auto_devops)
|
2021-04-08 08:09:18 -04:00
|
|
|
.preload(:service_desk_setting)
|
2018-12-27 09:37:46 -05:00
|
|
|
.preload(project_group_links: { group: :route },
|
2017-11-30 16:17:17 -05:00
|
|
|
fork_network: :root_project,
|
2018-08-31 13:16:34 -04:00
|
|
|
fork_network_member: :forked_from_project,
|
2021-09-28 05:11:19 -04:00
|
|
|
forked_from_project: [:route, :topics, :group, :project_feature, namespace: [:route, :owner]])
|
2017-11-30 06:52:38 -05:00
|
|
|
end
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2017-11-30 06:52:38 -05:00
|
|
|
|
2021-09-08 08:12:01 -04:00
|
|
|
def self.execute_batch_counting(projects_relation)
|
|
|
|
# Call the count methods on every project, so the BatchLoader would load them all at
|
|
|
|
# once when the entities are rendered
|
|
|
|
projects_relation.each(&:open_issues_count)
|
|
|
|
projects_relation.map(&:forked_from_project).compact.each(&:forks_count)
|
|
|
|
|
|
|
|
super
|
2017-11-30 06:52:38 -05:00
|
|
|
end
|
2021-09-09 23:10:59 -04:00
|
|
|
|
|
|
|
def self.repositories_for_preload(projects_relation)
|
|
|
|
super + projects_relation.map(&:forked_from_project).compact.map(&:repository)
|
|
|
|
end
|
2016-11-22 11:58:10 -05:00
|
|
|
end
|
2012-06-27 07:32:56 -04:00
|
|
|
end
|
|
|
|
end
|
2019-08-27 11:11:15 -04:00
|
|
|
|
2021-05-11 17:10:21 -04:00
|
|
|
API::Entities::Project.prepend_mod_with('API::Entities::Project', with_descendants: true)
|