1
0
Fork 0

feat(sync): leave comment with changes

This commit is contained in:
ssube 2020-08-16 17:07:07 -05:00 committed by BZ Libby
parent 9bd41aacac
commit 8edcd03873
6 changed files with 103 additions and 11 deletions

View File

@ -7,9 +7,16 @@
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
createComment(): Promise<void>; createComment(options: CommentUpdate): Promise<unknown>;
``` ```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| options | CommentUpdate | |
<b>Returns:</b> <b>Returns:</b>
Promise&lt;void&gt; Promise&lt;unknown&gt;

View File

@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [cautious-journey](./cautious-journey.md) &gt; [GithubRemote](./cautious-journey.githubremote.md) &gt; [formatBody](./cautious-journey.githubremote.formatbody.md)
## GithubRemote.formatBody() method
<b>Signature:</b>
```typescript
formatBody(options: CommentUpdate): string;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| options | CommentUpdate | |
<b>Returns:</b>
string

View File

@ -33,9 +33,10 @@ export declare class GithubRemote implements Remote
| Method | Modifiers | Description | | Method | Modifiers | Description |
| --- | --- | --- | | --- | --- | --- |
| [connect()](./cautious-journey.githubremote.connect.md) | | | | [connect()](./cautious-journey.githubremote.connect.md) | | |
| [createComment()](./cautious-journey.githubremote.createcomment.md) | | | | [createComment(options)](./cautious-journey.githubremote.createcomment.md) | | |
| [createLabel(options)](./cautious-journey.githubremote.createlabel.md) | | | | [createLabel(options)](./cautious-journey.githubremote.createlabel.md) | | |
| [deleteLabel(options)](./cautious-journey.githubremote.deletelabel.md) | | | | [deleteLabel(options)](./cautious-journey.githubremote.deletelabel.md) | | |
| [formatBody(options)](./cautious-journey.githubremote.formatbody.md) | | |
| [getIssue()](./cautious-journey.githubremote.getissue.md) | | | | [getIssue()](./cautious-journey.githubremote.getissue.md) | | |
| [getLabel()](./cautious-journey.githubremote.getlabel.md) | | | | [getLabel()](./cautious-journey.githubremote.getlabel.md) | | |
| [listIssues(options)](./cautious-journey.githubremote.listissues.md) | | | | [listIssues(options)](./cautious-journey.githubremote.listissues.md) | | |

View File

@ -2,7 +2,9 @@ import { doesExist, InvalidArgumentError, mustExist, NotImplementedError } from
import { createAppAuth } from '@octokit/auth-app'; import { createAppAuth } from '@octokit/auth-app';
import { Octokit } from '@octokit/rest'; import { Octokit } from '@octokit/rest';
import { IssueUpdate, LabelQuery, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.'; import { CommentUpdate, IssueUpdate, LabelQuery, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.';
import { ChangeVerb } from '../resolve';
import { VERSION_INFO } from '../version';
/** /**
* Github/Octokit API implementation of the `Remote` contract. * Github/Octokit API implementation of the `Remote` contract.
@ -17,8 +19,7 @@ export class GithubRemote implements Remote {
constructor(options: RemoteOptions) { constructor(options: RemoteOptions) {
this.options = options; this.options = options;
this.options.logger.debug(options, 'created github remote');
options.logger.debug(options, 'github remote');
} }
public async connect() { public async connect() {
@ -60,8 +61,27 @@ export class GithubRemote implements Remote {
}; };
} }
public async createComment() { public async createComment(options: CommentUpdate): Promise<unknown> {
throw new NotImplementedError(); const path = await this.splitProject(options.project);
const body = this.formatBody(options);
this.options.logger.debug({
body,
issue: options.issue,
project: options.project,
}, 'creating issue comment');
if (this.writeCapable) {
await this.writeRequest.issues.createComment({
body,
/* eslint-disable-next-line camelcase */
issue_number: parseInt(options.issue, 10),
owner: path.owner,
repo: path.repo,
});
}
return options;
} }
public async createLabel(options: LabelUpdate): Promise<LabelUpdate> { public async createLabel(options: LabelUpdate): Promise<LabelUpdate> {
@ -181,6 +201,37 @@ export class GithubRemote implements Remote {
} }
} }
public formatBody(options: CommentUpdate): string {
const lines = [];
lines.push(`${VERSION_INFO.package.name} v${VERSION_INFO.package.version} has updated the labels on this issue!`);
lines.push('');
for (const change of options.changes) {
switch (change.effect) {
case ChangeVerb.CONFLICTED:
lines.push(`- \`${change.label}\` conflicted with \`${change.cause}\`.`);
break;
case ChangeVerb.CREATED:
lines.push(`- \`${change.label}\` was created by \`${change.cause}\`.`);
break;
case ChangeVerb.EXISTING:
lines.push(`- \`${change.label}\` already existed.`);
break;
case ChangeVerb.REMOVED:
lines.push(`- \`${change.label}\` was removed by \`${change.cause}\`.`);
break;
case ChangeVerb.REQUIRED:
lines.push(`- \`${change.label}\` was removed because it requires \`${change.cause}\`.`);
break;
default:
lines.push(`- an unknown change occurred: \`${JSON.stringify(change)}\`.`);
break;
}
}
return lines.join('\n');
}
protected get writeCapable(): boolean { protected get writeCapable(): boolean {
return this.options.dryrun === false; return this.options.dryrun === false;
} }

View File

@ -1,4 +1,5 @@
import { Logger } from 'noicejs'; import { Logger } from 'noicejs';
import { ChangeRecord, ErrorRecord } from '../resolve';
export interface ProjectQuery { export interface ProjectQuery {
project: string; project: string;
@ -12,8 +13,13 @@ export interface IssueQuery extends ProjectQuery {
issue: string; issue: string;
} }
/**
* Changes to be recorded in a project comment. This takes an abstract set of change/error
* records and allows the remote implementation to handle formatting and localization.
*/
export interface CommentUpdate extends IssueQuery { export interface CommentUpdate extends IssueQuery {
comment: string; changes: Array<ChangeRecord>;
errors: Array<ErrorRecord>;
} }
export interface IssueUpdate extends IssueQuery { export interface IssueUpdate extends IssueQuery {

View File

@ -48,13 +48,18 @@ export async function syncIssueLabels(options: SyncOptions): Promise<unknown> {
options.logger.debug({ changes, errors, issue, labels }, 'resolved labels'); options.logger.debug({ changes, errors, issue, labels }, 'resolved labels');
// TODO: prompt user to update this particular issue // TODO: prompt user to update this particular issue
const sameLabels = !compareItems(issue.labels, labels) || changes.length > 0; const sameLabels = compareItems(issue.labels, labels) || changes.length === 0;
if (sameLabels && errors.length === 0) { if (sameLabels === false && errors.length === 0) {
options.logger.info({ issue, labels }, 'updating issue'); options.logger.info({ issue, labels }, 'updating issue');
await options.remote.updateIssue({ await options.remote.updateIssue({
...issue, ...issue,
labels, labels,
}); });
await options.remote.createComment({
...issue,
changes,
errors,
});
} }
} }