2018-05-10 08:56:07 -04:00
|
|
|
import {assert, assertNotMissingOrEmpty} from '../common/utils';
|
2017-02-06 13:40:28 -05:00
|
|
|
import {GithubApi} from './github-api';
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
export interface PullRequest {
|
2017-02-06 13:40:28 -05:00
|
|
|
number: number;
|
2017-02-28 14:10:46 -05:00
|
|
|
user: {login: string};
|
2017-06-18 18:15:07 -04:00
|
|
|
labels: {name: string}[];
|
2017-02-06 13:40:28 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
export interface FileInfo {
|
|
|
|
sha: string;
|
|
|
|
filename: string;
|
|
|
|
}
|
|
|
|
|
2017-02-06 13:40:28 -05:00
|
|
|
export type PullRequestState = 'all' | 'closed' | 'open';
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Access pull requests on GitHub.
|
|
|
|
*/
|
|
|
|
export class GithubPullRequests {
|
|
|
|
public repoSlug: string;
|
2017-02-28 07:17:20 -05:00
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Create an instance of this helper
|
|
|
|
* @param api An instance of the Github API helper.
|
|
|
|
* @param githubOrg The organisation on GitHub whose repo we will interrogate.
|
|
|
|
* @param githubRepo The repository on Github with whose PRs we will interact.
|
|
|
|
*/
|
|
|
|
constructor(private api: GithubApi, githubOrg: string, githubRepo: string) {
|
|
|
|
assertNotMissingOrEmpty('githubOrg', githubOrg);
|
|
|
|
assertNotMissingOrEmpty('githubRepo', githubRepo);
|
|
|
|
this.repoSlug = `${githubOrg}/${githubRepo}`;
|
|
|
|
}
|
2017-02-06 13:40:28 -05:00
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Post a comment on a PR.
|
|
|
|
* @param pr The number of the PR on which to comment.
|
|
|
|
* @param body The body of the comment to post.
|
|
|
|
* @returns A promise that resolves when the comment has been posted.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public addComment(pr: number, body: string): Promise<any> {
|
2018-05-10 08:56:07 -04:00
|
|
|
assert(pr > 0, `Invalid PR number: ${pr}`);
|
|
|
|
assert(!!body, `Invalid or empty comment body: ${body}`);
|
|
|
|
return this.api.post<any>(`/repos/${this.repoSlug}/issues/${pr}/comments`, null, {body});
|
2017-02-06 13:40:28 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Request information about a PR.
|
|
|
|
* @param pr The number of the PR for which to request info.
|
|
|
|
* @returns A promise that is resolves with information about the specified PR.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public fetch(pr: number): Promise<PullRequest> {
|
2018-05-10 08:56:07 -04:00
|
|
|
assert(pr > 0, `Invalid PR number: ${pr}`);
|
2017-06-18 18:15:07 -04:00
|
|
|
// Using the `/issues/` URL, because the `/pulls/` one does not provide labels.
|
2018-05-10 08:56:07 -04:00
|
|
|
return this.api.get<PullRequest>(`/repos/${this.repoSlug}/issues/${pr}`);
|
2017-02-28 14:10:46 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Request information about all PRs that match the given state.
|
|
|
|
* @param state Only retrieve PRs that have this state.
|
|
|
|
* @returns A promise that is resolved with information about the requested PRs.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public fetchAll(state: PullRequestState = 'all'): Promise<PullRequest[]> {
|
2017-02-06 13:40:28 -05:00
|
|
|
const pathname = `/repos/${this.repoSlug}/pulls`;
|
2017-02-28 07:01:20 -05:00
|
|
|
const params = {state};
|
2017-02-06 13:40:28 -05:00
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
return this.api.getPaginated<PullRequest>(pathname, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request a list of files for the given PR.
|
|
|
|
* @param pr The number of the PR for which to request files.
|
|
|
|
* @returns A promise that resolves to an array of file information
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public fetchFiles(pr: number): Promise<FileInfo[]> {
|
2018-05-10 08:56:07 -04:00
|
|
|
assert(pr > 0, `Invalid PR number: ${pr}`);
|
|
|
|
return this.api.get<FileInfo[]>(`/repos/${this.repoSlug}/pulls/${pr}/files`);
|
2017-02-06 13:40:28 -05:00
|
|
|
}
|
|
|
|
}
|