All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codacy.client.bitbucket.v2.service.PullRequestServices.scala Maven / Gradle / Ivy

The newest version!
package com.codacy.client.bitbucket.v2.service

import java.net.URLEncoder
import com.codacy.client.bitbucket.client.{BitbucketClient, PageRequest, RequestResponse}
import com.codacy.client.bitbucket.util.UrlHelper
import com.codacy.client.bitbucket.v2.{PullRequest, PullRequestComment, PullRequestReviewers, SimpleCommit}
import play.api.libs.json._

class PullRequestServices(client: BitbucketClient) {

  private val DEFAULT_PAGE_LENGTH = 50

  /**
    * Returns all pull requests on the specified repository.
    * By default only open pull requests are returned. This can be controlled using the states parameter.
    *
    * @param workspace This can either be the workspace ID (slug) or the workspace UUID surrounded by curly-braces, for example: {workspace UUID}
    * @param repositorySlug This can either be the repository slug or the UUID of the repository, surrounded by curly-braces, for example: {repository UUID}
    * @param pageLength The number of items of the page to be returned, it defaults to [[DEFAULT_PAGE_LENGTH]]
    * @param pageRequest The cursor to get a page of repositories
    * @param states Only return pull requests that are in these states. Valid values: MERGED, SUPERSEDED, OPEN, DECLINED
    */
  def getPullRequests(
      workspace: String,
      repositorySlug: String,
      pageLength: Int = DEFAULT_PAGE_LENGTH,
      pageRequest: Option[PageRequest] = None,
      states: Seq[String] = Seq("OPEN")
  ): RequestResponse[Seq[PullRequest]] = {
    val pullRequestsUrl = generatePullRequestsUrl(workspace, repositorySlug)
    val statesParams = states.map(state => s"state=$state")
    val url = UrlHelper.joinQueryParameters(pullRequestsUrl, statesParams: _*)

    pageRequest match {
      case Some(request) => client.executeWithCursor[PullRequest](url, request, Some(pageLength))
      case None => client.executePaginated[PullRequest](UrlHelper.joinQueryParameters(url, s"pagelen=$pageLength"))
    }
  }

  /**
    * Returns a specific pullRequest for a specified repository.
    * @param workspace      This can either be the workspace ID (slug) or the workspace UUID surrounded by curly-braces, for example: {workspace UUID}
    * @param repositorySlug This can either be the repository slug or the UUID of the repository, surrounded by curly-braces, for example: {repository UUID}
    * @param prId           The id of the specific pr to retrieve.
    * @return               The PullRequest that contains the data for the required id, the result is wrapped in a RequestResponse type.
    */
  def getPullRequest(workspace: String, repositorySlug: String, prId: Int): RequestResponse[PullRequest] =
    client.execute[PullRequest](generateSpecificPullRequestUrl(workspace, repositorySlug, prId))

  /*
   * Gets the list of commits of a pull request
   *
   */
  def getPullRequestCommits(
      owner: String,
      repository: String,
      prId: Long,
      size: Int = 100
  ): RequestResponse[Seq[SimpleCommit]] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/commits?pagelen=$size"

    client.executePaginated[SimpleCommit](url)
  }

  private[this] def postNewComment(
      owner: String,
      repository: String,
      prId: Int,
      values: JsObject
  ): RequestResponse[PullRequestComment] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/comments"
    client.postJson[PullRequestComment](url, values)
  }

  def create(
      owner: String,
      repository: String,
      title: String,
      sourceBranch: String,
      destinationBranch: String
  ): RequestResponse[JsObject] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)

    val payload = Json.obj(
      "title" -> title,
      "source" -> Json.obj("branch" -> Json.obj("name" -> sourceBranch)),
      "destination" -> Json.obj("branch" -> Json.obj("name" -> destinationBranch))
    )

    client.postJson[JsObject](pullRequestsUrl, payload)
  }

  def postApprove(owner: String, repository: String, prId: Long): RequestResponse[JsObject] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/approve"
    client.postJson[JsObject](url, JsNull)
  }

  def deleteApprove(owner: String, repository: String, prId: Long): RequestResponse[Boolean] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/approve"
    client.delete(url)
  }

  def merge(owner: String, repository: String, prId: Long): RequestResponse[JsObject] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/merge"
    client.postJson[JsObject](url, JsNull)
  }

  def decline(owner: String, repository: String, prId: Long): RequestResponse[JsObject] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId/decline"
    client.postJson[JsObject](url, JsNull)
  }

  def createLineComment(
      author: String,
      repo: String,
      prId: Int,
      body: String,
      file: Option[String],
      line: Option[Int]
  ): RequestResponse[PullRequestComment] = {
    val params = for {
      filename <- file
      lineTo <- line
    } yield {
      "inline" -> Json.obj("path" -> JsString(filename), "to" -> JsNumber(lineTo))
    }

    val values = JsObject(params.toSeq :+ "content" -> Json.obj("raw" -> JsString(body)))
    postNewComment(author, repo, prId, values)
  }

  def createPullRequestComment(
      author: String,
      repo: String,
      prId: Int,
      content: String
  ): RequestResponse[PullRequestComment] = {
    val values = Json.obj("content" -> Json.obj("raw" -> JsString(content)))
    postNewComment(author, repo, prId, values)
  }

  def deleteComment(
      author: String,
      repository: String,
      pullRequestId: Int,
      commentId: Long
  ): RequestResponse[Boolean] = {
    val pullRequestsUrl = generatePullRequestsUrl(author, repository)
    val url = s"$pullRequestsUrl/$pullRequestId/comments/$commentId"

    client.delete(url)
  }

  def listComments(author: String, repository: String, pullRequestId: Int): RequestResponse[Seq[PullRequestComment]] = {
    val pullRequestsUrl = generatePullRequestsUrl(author, repository)
    val url = s"$pullRequestsUrl/$pullRequestId/comments"

    client
      .executePaginated[PullRequestComment](url)
      .map(_.filterNot(_.deleted))
  }

  def getPullRequestsReviewers(owner: String, repository: String, prId: Long): RequestResponse[PullRequestReviewers] = {
    val pullRequestsUrl = generatePullRequestsUrl(owner, repository)
    val url = s"$pullRequestsUrl/$prId"

    client.execute[PullRequestReviewers](url)
  }

  private def generatePullRequestsUrl(workspace: String, repoSlug: String): String = {
    val encodedWorkspace = URLEncoder.encode(workspace, "UTF-8")
    val encodedSlug = URLEncoder.encode(repoSlug, "UTF-8")
    s"${client.repositoriesBaseUrl}/$encodedWorkspace/$encodedSlug/pullrequests"
  }

  private def generateSpecificPullRequestUrl(workspace: String, repoSlug: String, pullRequestId: Int): String = {
    val encodedWorkspace = URLEncoder.encode(workspace, "UTF-8")
    val encodedSlug = URLEncoder.encode(repoSlug, "UTF-8")
    s"${client.repositoriesBaseUrl}/$encodedWorkspace/$encodedSlug/pullrequests/$pullRequestId"
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy