import { getCollaborators } from './collaborators.js';
import { ReviewAnalyzer } from './reviews.js';
import {
FIRST_TIME_CONTRIBUTOR, FIRST_TIMER
} from './user_status.js';
// lib/queries/*.gql file names
const PR_QUERY = 'PR';
const REVIEWS_QUERY = 'Reviews';
const COMMENTS_QUERY = 'PRComments';
const COMMITS_QUERY = 'PRCommits';
export default class PRData {
/**
* @param {Object} argv
* @param {Object} cli
* @param {Object} request
*/
constructor(argv, cli, request) {
const { prid, owner, repo } = argv;
this.prid = prid;
this.owner = owner;
this.repo = repo;
this.cli = cli;
this.argv = argv;
this.request = request;
this.prStr = `${owner}/${repo}/pull/${prid}`;
// Data
this.collaborators = new Map();
this.pr = {};
this.reviews = [];
this.comments = [];
this.commits = [];
this.reviewers = [];
}
getThread() {
const { pr, comments, reviews } = this;
const prNode = {
publishedAt: pr.createdAt,
bodyText: pr.bodyText
};
return comments.concat([prNode]).concat(reviews);
}
async getThreadData() {
return Promise.all([
this.getPR(),
this.getReviews(),
this.getComments()
]);
}
async getAll(argv) {
const { prStr } = this;
this.cli.startSpinner(`Loading data for ${prStr}`);
await Promise.all([
this.getCollaborators(),
this.getThreadData(),
this.getCommits()
]).then(() => {
this.mergeHeadCommitChecks();
this.cli.stopSpinner(`Done loading data for ${prStr}`);
});
this.analyzeReviewers();
}
mergeHeadCommitChecks() {
const headCommit = this.pr.headCommit?.nodes?.[0]?.commit;
delete this.pr.headCommit;
const lastCommit = this.commits.at(-1)?.commit;
if (headCommit === undefined && lastCommit === undefined) {
return;
}
if (headCommit?.oid !== lastCommit?.oid) {
throw new Error(
'Unable to match pull request head commit while loading data');
}
lastCommit.checkSuites = headCommit.checkSuites;
lastCommit.status = headCommit.status;
}
analyzeReviewers() {
this.reviewers = new ReviewAnalyzer(this).getReviewers();
}
async getCollaborators() {
const { cli, request, argv } = this;
this.collaborators = await getCollaborators(cli, request, argv);
}
async getPR() {
const { prid, owner, repo, cli, request, prStr } = this;
cli.updateSpinner(`Getting PR from ${prStr}`);
const prData = await request.gql(PR_QUERY, { prid, owner, repo });
this.pr = prData.repository.pullRequest;
}
async getReviews() {
const { prid, owner, repo, cli, request, prStr } = this;
const vars = { prid, owner, repo };
cli.updateSpinner(`Getting reviews from ${prStr}`);
this.reviews = await request.gql(REVIEWS_QUERY, vars, [
'repository', 'pullRequest', 'reviews'
]);
}
async getComments() {
const { prid, owner, repo, cli, request, prStr } = this;
const vars = { prid, owner, repo };
cli.updateSpinner(`Getting comments from ${prStr}`);
this.comments = await request.gql(COMMENTS_QUERY, vars, [
'repository', 'pullRequest', 'comments'
]);
}
async getCommits() {
const { prid, owner, repo, cli, request, prStr } = this;
const vars = { prid, owner, repo };
cli.updateSpinner(`Getting commits from ${prStr}`);
this.commits = await request.gql(COMMITS_QUERY, vars, [
'repository', 'pullRequest', 'commits'
]);
}
authorIsNew() {
const assoc = this.pr.authorAssociation;
return assoc === FIRST_TIME_CONTRIBUTOR || assoc === FIRST_TIMER;
}
}