# 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, :merged_by # Builds a PR from a GitHub API response. # # issue - An instance of `Hash` containing the PR details. def self.from_api_response(pr, additional_data = {}) assignee = Representation::User.from_api_response(pr[:assignee]) if pr[:assignee] user = Representation::User.from_api_response(pr[:user]) if pr[:user] merged_by = Representation::User.from_api_response(pr[:merged_by]) if pr[:merged_by] hash = { iid: pr[:number], title: pr[:title], description: pr[:body], source_branch: pr.dig(:head, :ref), target_branch: pr.dig(:base, :ref), source_branch_sha: pr.dig(:head, :sha), target_branch_sha: pr.dig(:base, :sha), source_repository_id: pr.dig(:head, :repo, :id), target_repository_id: pr.dig(:base, :repo, :id), source_repository_owner: pr.dig(:head, :user, :login), state: pr[:state] == 'open' ? :opened : :closed, milestone_number: pr.dig(:milestone, :number), author: user, assignee: assignee, created_at: pr[:created_at], updated_at: pr[:updated_at], merged_at: pr[:merged_at], merged_by: merged_by } 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]) hash[:merged_by] &&= Representation::User.from_json_hash(hash[:merged_by]) 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 # `github/fork/owner-name/branch-name`. def formatted_source_branch if cross_project? && source_repository_owner "github/fork/#{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 def github_identifiers { iid: iid, issuable_type: issuable_type, title: title } end end end end end