115 lines
3.6 KiB
Ruby
115 lines
3.6 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Gitlab
|
||
|
module GithubImport
|
||
|
module Representation
|
||
|
class PullRequest
|
||
|
include ToHash
|
||
|
include ExposeAttribute
|
||
|
|
||
|
attr_reader :attributes
|
||
|
|
||
|
expose_attribute :iid, :title, :description, :source_branch,
|
||
|
:source_branch_sha, :target_branch, :target_branch_sha,
|
||
|
:milestone_number, :author, :assignee, :created_at,
|
||
|
:updated_at, :merged_at, :source_repository_id,
|
||
|
:target_repository_id, :source_repository_owner
|
||
|
|
||
|
# Builds a PR from a GitHub API response.
|
||
|
#
|
||
|
# issue - An instance of `Sawyer::Resource` containing the PR details.
|
||
|
def self.from_api_response(pr)
|
||
|
assignee =
|
||
|
if pr.assignee
|
||
|
Representation::User.from_api_response(pr.assignee)
|
||
|
end
|
||
|
|
||
|
user = Representation::User.from_api_response(pr.user) if pr.user
|
||
|
hash = {
|
||
|
iid: pr.number,
|
||
|
title: pr.title,
|
||
|
description: pr.body,
|
||
|
source_branch: pr.head.ref,
|
||
|
target_branch: pr.base.ref,
|
||
|
source_branch_sha: pr.head.sha,
|
||
|
target_branch_sha: pr.base.sha,
|
||
|
source_repository_id: pr.head&.repo&.id,
|
||
|
target_repository_id: pr.base&.repo&.id,
|
||
|
source_repository_owner: pr.head&.user&.login,
|
||
|
state: pr.state == 'open' ? :opened : :closed,
|
||
|
milestone_number: pr.milestone&.number,
|
||
|
author: user,
|
||
|
assignee: assignee,
|
||
|
created_at: pr.created_at,
|
||
|
updated_at: pr.updated_at,
|
||
|
merged_at: pr.merged_at
|
||
|
}
|
||
|
|
||
|
new(hash)
|
||
|
end
|
||
|
|
||
|
# Builds a new PR using a Hash that was built from a JSON payload.
|
||
|
def self.from_json_hash(raw_hash)
|
||
|
hash = Representation.symbolize_hash(raw_hash)
|
||
|
|
||
|
hash[:state] = hash[:state].to_sym
|
||
|
hash[:author] &&= Representation::User.from_json_hash(hash[:author])
|
||
|
|
||
|
# Assignees are optional so we only convert it from a Hash if one was
|
||
|
# set.
|
||
|
hash[:assignee] &&= Representation::User
|
||
|
.from_json_hash(hash[:assignee])
|
||
|
|
||
|
new(hash)
|
||
|
end
|
||
|
|
||
|
# attributes - A Hash containing the raw PR details. The keys of this
|
||
|
# Hash (and any nested hashes) must be symbols.
|
||
|
def initialize(attributes)
|
||
|
@attributes = attributes
|
||
|
end
|
||
|
|
||
|
def truncated_title
|
||
|
title.truncate(255)
|
||
|
end
|
||
|
|
||
|
# Returns a formatted source branch.
|
||
|
#
|
||
|
# For cross-project pull requests the branch name will be in the format
|
||
|
# `owner-name:branch-name`.
|
||
|
def formatted_source_branch
|
||
|
if cross_project? && source_repository_owner
|
||
|
"#{source_repository_owner}:#{source_branch}"
|
||
|
elsif source_branch == target_branch
|
||
|
# Sometimes the source and target branch are the same, but GitLab
|
||
|
# doesn't support this. This can happen when both the user and
|
||
|
# source repository have been deleted, and the PR was submitted from
|
||
|
# the fork's master branch.
|
||
|
"#{source_branch}-#{iid}"
|
||
|
else
|
||
|
source_branch
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def state
|
||
|
if merged_at
|
||
|
:merged
|
||
|
else
|
||
|
attributes[:state]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def cross_project?
|
||
|
return true unless source_repository_id
|
||
|
|
||
|
source_repository_id != target_repository_id
|
||
|
end
|
||
|
|
||
|
def issuable_type
|
||
|
'MergeRequest'
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|