/* * Copycat. Copyright (C) 2020 selfisekai and other contributors. * * This is free software, and you are welcome to redistribute it * under the GNU General Public License 3.0 or later; see the LICENSE file for details, * or, if the file is unavailable, visit . */ import { RepoManager, Issue, Repo, ACTOR_TYPE, ISSUE_STATE, MergeRequest, MERGE_REQUEST_STATE, MERGE_REQUEST_MERGABILITY, } from '../../types'; import GitHubVendorManager from './vendormgr'; import assert from 'assert'; export default class GitHubRepoManager implements RepoManager { vendorMgr: GitHubVendorManager; repo: Repo; constructor(vendorMgr: GitHubVendorManager, repoPath: string) { this.vendorMgr = vendorMgr; const mobj = /^([^/\s]+)\/([^/\s]+)$/.exec(repoPath); assert(mobj, 'invalid repo path'); const [, owner, repoName] = mobj; this.repo = { vendor: this.vendorMgr.vendor, owner: { type: ACTOR_TYPE.UNKNOWN, username: owner, vendor: this.vendorMgr.vendor, }, name: repoName, }; } public async initialize() { const meta = await this.vendorMgr._doRequest( ` query Query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { name owner { login __typename } } } `, { owner: this.repo.owner.username, name: this.repo.name, }, ); console.log(meta); assert(meta.repository); assert(meta.repository.owner); this.repo.name = meta.repository.name; this.repo.owner.username = meta.repository.owner.login; // @ts-ignore graphql-codegen ignores built-in graphql values switch (meta.repository.owner.__typename) { case 'Organization': this.repo.owner.type = ACTOR_TYPE.ORG; break; case 'User': this.repo.owner.type = ACTOR_TYPE.USER; break; } return this; } public async getIssue(number: string): Promise { const resp = await this.vendorMgr._doRequest( ` query Query($owner: String!, $name: String!, $number: Int!) { repository(owner: $owner, name: $name) { issue(number: $number) { number title body closed closedAt labels(first: 0) { nodes { name color description } } } } } `, { owner: this.repo.owner.username, name: this.repo.name, number: parseInt(number, 10), }, ); assert(resp.repository, 'no repository'); assert(resp.repository.issue, 'no issue'); const { issue } = resp.repository; return { id: number, content: issue.body, title: issue.title, repo: this.repo, state: issue.closed ? ISSUE_STATE.CLOSED : ISSUE_STATE.OPEN, }; } public async getMergeRequest(number: string): Promise { const resp = await this.vendorMgr._doRequest( ` query Query($owner: String!, $name: String!, $number: Int!) { repository(owner: $owner, name: $name) { pullRequest(number: $number) { title body isDraft closed closedAt mergeable merged mergedAt mergedBy { login } labels(first: 0) { nodes { name color description } } } } } `, { owner: this.repo.owner.username, name: this.repo.name, number: parseInt(number, 10), }, ); assert(resp.repository, 'no repository'); assert(resp.repository.pullRequest, 'no pull request'); const { pullRequest } = resp.repository; return { id: number, content: pullRequest.body, title: pullRequest.title, repo: this.repo, state: pullRequest.closed ? MERGE_REQUEST_STATE.CLOSED : MERGE_REQUEST_STATE.OPEN, mergability: { MERGEABLE: MERGE_REQUEST_MERGABILITY.MERGEABLE, CONFLICTING: MERGE_REQUEST_MERGABILITY.CONFLICTING, UNKNOWN: null, }[pullRequest.mergeable], isDraft: pullRequest.isDraft, }; } }