copykitku/src/vendor/github/repomgr.ts
2020-08-21 11:53:55 +02:00

171 lines
4.5 KiB
TypeScript

/*
* Copycat. Copyright (C) 2020 selfisekai <laura@selfisekai.rocks> 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*/
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<Issue> {
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<MergeRequest> {
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,
};
}
}