using System; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; namespace Octokit { /// /// A client for GitHub's Pull Requests API. /// /// /// See the Pull Requests API documentation for more information. /// public class PullRequestsClient : ApiClient, IPullRequestsClient { public PullRequestsClient(IApiConnection apiConnection) : base(apiConnection) { Review = new PullRequestReviewsClient(apiConnection); ReviewComment = new PullRequestReviewCommentsClient(apiConnection); ReviewRequest = new PullRequestReviewRequestsClient(apiConnection); } /// /// Client for managing reviews. /// public IPullRequestReviewsClient Review { get; set; } /// /// Client for managing review comments. /// public IPullRequestReviewCommentsClient ReviewComment { get; set; } /// /// Client for managing review requests. /// public IPullRequestReviewRequestsClient ReviewRequest { get; set; } /// /// Get a pull request by number. /// /// /// http://developer.github.com/v3/pulls/#get-a-single-pull-request /// [Preview("shadow-cat")] [ManualRoute("GET", "/repos/{owner}/{repo}/pulls/{pull_number}")] public Task Get(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); return ApiConnection.Get(ApiUrls.PullRequest(owner, name, number), null, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Get a pull request by number. /// /// /// http://developer.github.com/v3/pulls/#get-a-single-pull-request /// [Preview("shadow-cat")] [ManualRoute("GET", "/repositories/{id}/pulls/{number}")] public Task Get(long repositoryId, int number) { return ApiConnection.Get(ApiUrls.PullRequest(repositoryId, number), null, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Get all open pull requests for the repository. /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The owner of the repository /// The name of the repository [ManualRoute("GET", "/repos/{owner}/{repo}/pulls")] public Task> GetAllForRepository(string owner, string name) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); return GetAllForRepository(owner, name, new PullRequestRequest(), ApiOptions.None); } /// /// Get all open pull requests for the repository. /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The Id of the repository [ManualRoute("GET", "/repositories/{id}/pulls")] public Task> GetAllForRepository(long repositoryId) { return GetAllForRepository(repositoryId, new PullRequestRequest(), ApiOptions.None); } /// /// Get all open pull requests for the repository. /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The owner of the repository /// The name of the repository /// Options for changing the API response [ManualRoute("GET", "/repos/{owner}/{repo}/pulls")] public Task> GetAllForRepository(string owner, string name, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(options, nameof(options)); return GetAllForRepository(owner, name, new PullRequestRequest(), options); } /// /// Get all open pull requests for the repository. /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The Id of the repository /// Options for changing the API response [ManualRoute("GET", "/repositories/{id}/pulls")] public Task> GetAllForRepository(long repositoryId, ApiOptions options) { Ensure.ArgumentNotNull(options, nameof(options)); return GetAllForRepository(repositoryId, new PullRequestRequest(), options); } /// /// Query pull requests for the repository based on criteria /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The owner of the repository /// The name of the repository /// Used to filter and sort the list of pull requests returned [ManualRoute("GET", "/repos/{owner}/{repo}/pulls")] public Task> GetAllForRepository(string owner, string name, PullRequestRequest request) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(request, nameof(request)); return GetAllForRepository(owner, name, request, ApiOptions.None); } /// /// Query pull requests for the repository based on criteria /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The Id of the repository /// Used to filter and sort the list of pull requests returned [ManualRoute("GET", "/repositories/{id}/pulls")] public Task> GetAllForRepository(long repositoryId, PullRequestRequest request) { Ensure.ArgumentNotNull(request, nameof(request)); return GetAllForRepository(repositoryId, request, ApiOptions.None); } /// /// Query pull requests for the repository based on criteria /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The owner of the repository /// The name of the repository /// Used to filter and sort the list of pull requests returned /// Options for changing the API response [Preview("shadow-cat")] [ManualRoute("GET", "/repos/{owner}/{repo}/pulls")] public Task> GetAllForRepository(string owner, string name, PullRequestRequest request, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(options, nameof(options)); return ApiConnection.GetAll(ApiUrls.PullRequests(owner, name), request.ToParametersDictionary(), AcceptHeaders.DraftPullRequestApiPreview, options); } /// /// Query pull requests for the repository based on criteria /// /// /// http://developer.github.com/v3/pulls/#list-pull-requests /// /// The Id of the repository /// Used to filter and sort the list of pull requests returned /// Options for changing the API response [Preview("shadow-cat")] [ManualRoute("GET", "/repositories/{id}/pulls")] public Task> GetAllForRepository(long repositoryId, PullRequestRequest request, ApiOptions options) { Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(options, nameof(options)); return ApiConnection.GetAll(ApiUrls.PullRequests(repositoryId), request.ToParametersDictionary(), AcceptHeaders.DraftPullRequestApiPreview, options); } /// /// Create a pull request for the specified repository. /// /// http://developer.github.com/v3/pulls/#create-a-pull-request /// The owner of the repository /// The name of the repository /// A instance describing the new PullRequest to create [Preview("shadow-cat")] [ManualRoute("POST", "/repos/{owner}/{repo}/pulls")] public Task Create(string owner, string name, NewPullRequest newPullRequest) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(newPullRequest, nameof(newPullRequest)); return ApiConnection.Post(ApiUrls.PullRequests(owner, name), newPullRequest, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Create a pull request for the specified repository. /// /// http://developer.github.com/v3/pulls/#create-a-pull-request /// The Id of the repository /// A instance describing the new PullRequest to create [Preview("shadow-cat")] [ManualRoute("POST", "/repositories/{id}/pulls")] public Task Create(long repositoryId, NewPullRequest newPullRequest) { Ensure.ArgumentNotNull(newPullRequest, nameof(newPullRequest)); return ApiConnection.Post(ApiUrls.PullRequests(repositoryId), newPullRequest, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Create a pull request for the specified repository. /// /// http://developer.github.com/v3/pulls/#update-a-pull-request /// The owner of the repository /// The name of the repository /// The PullRequest number /// An instance describing the changes to make to the PullRequest /// [Preview("shadow-cat")] [ManualRoute("PATCH", "/repos/{owner}/{repo}/pulls/{pull_number}")] public Task Update(string owner, string name, int number, PullRequestUpdate pullRequestUpdate) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(pullRequestUpdate, nameof(pullRequestUpdate)); return ApiConnection.Patch(ApiUrls.PullRequest(owner, name, number), pullRequestUpdate, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Create a pull request for the specified repository. /// /// http://developer.github.com/v3/pulls/#update-a-pull-request /// The Id of the repository /// The PullRequest number /// An instance describing the changes to make to the PullRequest /// [Preview("shadow-cat")] [ManualRoute("PATCH", "/repositories/{id}/pulls/{number}")] public Task Update(long repositoryId, int number, PullRequestUpdate pullRequestUpdate) { Ensure.ArgumentNotNull(pullRequestUpdate, nameof(pullRequestUpdate)); return ApiConnection.Patch(ApiUrls.PullRequest(repositoryId, number), pullRequestUpdate, AcceptHeaders.DraftPullRequestApiPreview); } /// /// Merge a pull request. /// /// http://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade /// The owner of the repository /// The name of the repository /// The pull request number /// A instance describing a pull request merge [ManualRoute("PUT", "/repos/{owner}/{repo}/pulls/{pull_number}/merge")] public async Task Merge(string owner, string name, int number, MergePullRequest mergePullRequest) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); Ensure.ArgumentNotNull(mergePullRequest, nameof(mergePullRequest)); try { var endpoint = ApiUrls.MergePullRequest(owner, name, number); return await ApiConnection.Put(endpoint, mergePullRequest).ConfigureAwait(false); } catch (ApiException ex) { if (ex.StatusCode == HttpStatusCode.MethodNotAllowed) { throw new PullRequestNotMergeableException(ex.HttpResponse); } if (ex.StatusCode == HttpStatusCode.Conflict) { throw new PullRequestMismatchException(ex.HttpResponse); } throw; } } /// /// Merge a pull request. /// /// http://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade /// The Id of the repository /// The pull request number /// A instance describing a pull request merge [ManualRoute("PUT", "/repositories/{id}/pulls/{number}/merge")] public async Task Merge(long repositoryId, int number, MergePullRequest mergePullRequest) { Ensure.ArgumentNotNull(mergePullRequest, nameof(mergePullRequest)); try { var endpoint = ApiUrls.MergePullRequest(repositoryId, number); return await ApiConnection.Put(endpoint, mergePullRequest).ConfigureAwait(false); } catch (ApiException ex) { if (ex.StatusCode == HttpStatusCode.MethodNotAllowed) { throw new PullRequestNotMergeableException(ex.HttpResponse); } if (ex.StatusCode == HttpStatusCode.Conflict) { throw new PullRequestMismatchException(ex.HttpResponse); } throw; } } /// /// Get the pull request merge status. /// /// http://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged /// The owner of the repository /// The name of the repository /// The pull request number [ManualRoute("GET", "/repos/{owner}/{repo}/pulls/{pull_number}/merge")] public async Task Merged(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); try { var endpoint = ApiUrls.MergePullRequest(owner, name, number); var response = await Connection.Get(endpoint, null, null).ConfigureAwait(false); return response.HttpResponse.IsTrue(); } catch (NotFoundException) { return false; } } /// /// Get the pull request merge status. /// /// http://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged /// The Id of the repository /// The pull request number [ManualRoute("GET", "/repositories/{id}/pulls/{number}/merge")] public async Task Merged(long repositoryId, int number) { try { var endpoint = ApiUrls.MergePullRequest(repositoryId, number); var response = await Connection.Get(endpoint, null, null).ConfigureAwait(false); return response.HttpResponse.IsTrue(); } catch (NotFoundException) { return false; } } /// /// Get the list of commits on a pull request. /// /// http://developer.github.com/v3/pulls/#list-commits-on-a-pull-request /// The owner of the repository /// The name of the repository /// The pull request number [ManualRoute("GET", "/repos/{owner}/{repo}/pulls/{pull_number}/commits")] public Task> Commits(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); return ApiConnection.GetAll(ApiUrls.PullRequestCommits(owner, name, number)); } /// /// Get the list of commits on a pull request. /// /// http://developer.github.com/v3/pulls/#list-commits-on-a-pull-request /// The Id of the repository /// The pull request number [ManualRoute("GET", "/repositories/{id}/pulls/{number}/commits")] public Task> Commits(long repositoryId, int number) { return ApiConnection.GetAll(ApiUrls.PullRequestCommits(repositoryId, number)); } /// /// Get the list of files on a pull request. /// /// https://developer.github.com/v3/pulls/#list-pull-requests-files /// The owner of the repository /// The name of the repository /// The pull request number [ManualRoute("GET", "/repos/{owner}/{repo}/pulls/{pull_number}/files")] public Task> Files(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); return ApiConnection.GetAll(ApiUrls.PullRequestFiles(owner, name, number)); } /// /// Get the list of files on a pull request. /// /// https://developer.github.com/v3/pulls/#list-pull-requests-files /// The Id of the repository /// The pull request number [ManualRoute("GET", "/repositories/{id}/pulls/{number}/files")] public Task> Files(long repositoryId, int number) { return ApiConnection.GetAll(ApiUrls.PullRequestFiles(repositoryId, number)); } } }