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

com.spotify.github.v3.clients.PullRequestClient Maven / Gradle / Ivy

/*-
 * -\-\-
 * github-api
 * --
 * Copyright (C) 2016 - 2020 Spotify AB
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * -/-/-
 */

package com.spotify.github.v3.clients;

import static com.spotify.github.v3.clients.GitHubClient.IGNORE_RESPONSE_CONSUMER;
import static com.spotify.github.v3.clients.GitHubClient.LIST_COMMIT_TYPE_REFERENCE;
import static com.spotify.github.v3.clients.GitHubClient.LIST_PR_TYPE_REFERENCE;
import static com.spotify.github.v3.clients.GitHubClient.LIST_REVIEW_REQUEST_TYPE_REFERENCE;
import static com.spotify.github.v3.clients.GitHubClient.LIST_REVIEW_TYPE_REFERENCE;

import com.google.common.base.Strings;
import com.spotify.github.async.AsyncPage;
import com.spotify.github.v3.prs.*;
import com.spotify.github.v3.prs.requests.PullRequestCreate;
import com.spotify.github.v3.prs.requests.PullRequestParameters;
import com.spotify.github.v3.prs.requests.PullRequestUpdate;
import com.spotify.github.v3.repos.CommitItem;
import java.lang.invoke.MethodHandles;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Pull call API client */
public class PullRequestClient {

  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
  private static final String PR_TEMPLATE = "/repos/%s/%s/pulls";
  private static final String PR_NUMBER_TEMPLATE = "/repos/%s/%s/pulls/%s";
  private static final String PR_COMMITS_TEMPLATE = "/repos/%s/%s/pulls/%s/commits";
  private static final String PR_REVIEWS_TEMPLATE = "/repos/%s/%s/pulls/%s/reviews";
  private static final String PR_REVIEW_REQUESTS_TEMPLATE = "/repos/%s/%s/pulls/%s/requested_reviewers";

  private final GitHubClient github;
  private final String owner;
  private final String repo;

  PullRequestClient(final GitHubClient github, final String owner, final String repo) {
    this.github = github;
    this.owner = owner;
    this.repo = repo;
  }

  static PullRequestClient create(
      final GitHubClient github, final String owner, final String repo) {
    return new PullRequestClient(github, owner, repo);
  }

  /**
   * List repository pull request.
   *
   * @return pull requests
   */
  public CompletableFuture> list() {
    return list("");
  }

  /**
   * List repository pull requests using given parameters.
   *
   * @param parameters request parameters
   * @return pull requests
   */
  public CompletableFuture> list(final PullRequestParameters parameters) {
    final String serial = parameters.serialize();
    final String path = Strings.isNullOrEmpty(serial) ? "" : "?" + serial;
    return list(path);
  }

  /**
   * Get a specific pull request.
   *
   * @param number pull request number
   * @return pull request
   */
  public CompletableFuture get(final int number) {
    final String path = String.format(PR_NUMBER_TEMPLATE, owner, repo, number);
    log.debug("Fetching pull request from " + path);
    return github.request(path, PullRequest.class);
  }

  /**
   * Create a pull request.
   *
   * @param request create request
   * @return pull request
   */
  public CompletableFuture create(final PullRequestCreate request) {
    final String path = String.format(PR_TEMPLATE, owner, repo);
    return github.post(path, github.json().toJsonUnchecked(request), PullRequest.class);
  }

  /**
   * Update given pull request.
   *
   * @param number pull request number
   * @param request update request
   * @return pull request
   */
  public CompletableFuture update(final int number, final PullRequestUpdate request) {
    final String path = String.format(PR_NUMBER_TEMPLATE, owner, repo, number);
    return github.patch(path, github.json().toJsonUnchecked(request), PullRequest.class);
  }

  /**
   * List pull request commits.
   *
   * @param number pull request number
   * @return commits
   */
  public CompletableFuture> listCommits(final int number) {
    final String path = String.format(PR_COMMITS_TEMPLATE, owner, repo, number);
    log.debug("Fetching pull request commits from " + path);
    return github.request(path, LIST_COMMIT_TYPE_REFERENCE);
  }

  /**
   * List pull request reviews. Reviews are returned in chronological order.
   *
   * @param number pull request number
   * @return list of reviews
   */
   public CompletableFuture> listReviews(final int number) {
   final String path = String.format(PR_REVIEWS_TEMPLATE, owner, repo, number);
   log.debug("Fetching pull request reviews from " + path);
   return github.request(path, LIST_REVIEW_TYPE_REFERENCE);
  }

  /**
   * List pull request reviews paginated. Reviews are returned in chronological order.
   *
   * @param number pull request number
   * @param itemsPerPage number of items per page
   * @return iterator of reviews
   */
  public Iterator> listReviews(final int number, final int itemsPerPage) {
    // FIXME Use itemsPerPage property
    final String path = String.format(PR_REVIEWS_TEMPLATE, owner, repo, number);
    log.debug("Fetching pull request reviews from " + path);
    return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_REVIEW_TYPE_REFERENCE));
  }

  /**
   * Creates a review for a pull request.
   *
   * @param number pull request number
   * @param properties properties for reviewing the PR, such as sha, body and event
   * @see "https://developer.github.com/v3/pulls/reviews/#create-a-review-for-a-pull-request"
   */
  public CompletableFuture createReview(final int number, final ReviewParameters properties) {
    final String path = String.format(PR_REVIEWS_TEMPLATE, owner, repo, number);
    final String jsonPayload = github.json().toJsonUnchecked(properties);
    log.debug("Creating review for PR: " + path);
    return github.post(path, jsonPayload, Review.class);
  }

  /**
   * List pull request requested reviews.
   *
   * @param number pull request number
   * @return list of reviews
   */
  public CompletableFuture listReviewRequests(final int number) {
    final String path = String.format(PR_REVIEW_REQUESTS_TEMPLATE, owner, repo, number);
    log.debug("Fetching pull request requested reviews from " + path);
    return github.request(path, LIST_REVIEW_REQUEST_TYPE_REFERENCE);
  }

  /**
   * Requests a review for a pull request.
   *
   * @param number pull request number
   * @param properties properties for reviewing the PR, such as reviewers and team_reviewers.
   * @see "https://docs.github.com/en/rest/reference/pulls#request-reviewers-for-a-pull-request"
   */
  public CompletableFuture requestReview(final int number, final RequestReviewParameters properties) {
    final String path = String.format(PR_REVIEW_REQUESTS_TEMPLATE, owner, repo, number);
    final String jsonPayload = github.json().toJsonUnchecked(properties);
    log.debug("Requesting reviews for PR: " + path);
    return github.post(path, jsonPayload, PullRequest.class);
  }

  /**
   * Remove a request for review for a pull request.
   *
   * @param number pull request number
   * @param properties properties for reviewing the PR, such as reviewers and team_reviewers.
   * @see "https://docs.github.com/en/rest/reference/pulls#request-reviewers-for-a-pull-request"
   */
  public CompletableFuture removeRequestedReview(final int number, final RequestReviewParameters properties) {
    final String path = String.format(PR_REVIEW_REQUESTS_TEMPLATE, owner, repo, number);
    final String jsonPayload = github.json().toJsonUnchecked(properties);
    log.debug("Removing requested reviews for PR: " + path);
    return github.delete(path, jsonPayload).thenAccept(IGNORE_RESPONSE_CONSUMER);
  }

  /**
   * Merges a pull request.
   *
   * @param number pull request number
   * @param properties the properties on merging the PR, such as title, message and sha
   * @see "https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button"
   */
  public CompletableFuture merge(final int number, final MergeParameters properties) {
    final String path = String.format(PR_NUMBER_TEMPLATE + "/merge", owner, repo, number);
    final String jsonPayload = github.json().toJsonUnchecked(properties);
    log.debug("Merging pr, running: {}", path);
    return github.put(path, jsonPayload).thenAccept(IGNORE_RESPONSE_CONSUMER);
  }

  private CompletableFuture> list(final String parameterPath) {
    final String path = String.format(PR_TEMPLATE + parameterPath, owner, repo);
    log.debug("Fetching pull requests from " + path);
    return github.request(path, LIST_PR_TYPE_REFERENCE);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy