From e3351fe344897909e71c6b7ac5ad6c6d2e352f4a Mon Sep 17 00:00:00 2001 From: ssube Date: Sun, 23 Aug 2020 12:13:52 -0500 Subject: [PATCH] feat(remote): implement issue, label update methods for gitlab, add dryrun support --- ...autious-journey.githubremote.formatbody.md | 22 ----- docs/api/cautious-journey.githubremote.md | 16 +--- .../cautious-journey.githubremote.options.md | 11 --- .../cautious-journey.githubremote.request.md | 13 --- ...tious-journey.githubremote.resolvepath.md} | 6 +- ...tious-journey.githubremote.writecapable.md | 11 --- ...tious-journey.githubremote.writerequest.md | 11 --- .../cautious-journey.gitlabremote.client.md | 11 --- ...ious-journey.gitlabremote.createcomment.md | 9 +- ...utious-journey.gitlabremote.createlabel.md | 9 +- ...utious-journey.gitlabremote.deletelabel.md | 9 +- docs/api/cautious-journey.gitlabremote.md | 21 ++--- .../cautious-journey.gitlabremote.options.md | 11 --- ...utious-journey.gitlabremote.updateissue.md | 9 +- ...utious-journey.gitlabremote.updatelabel.md | 9 +- src/config/schema.yml | 2 +- src/remote/base.ts | 68 ++++++++++++++ src/remote/github.ts | 94 +++++-------------- src/remote/gitlab.ts | 79 +++++++++++----- 19 files changed, 204 insertions(+), 217 deletions(-) delete mode 100644 docs/api/cautious-journey.githubremote.formatbody.md delete mode 100644 docs/api/cautious-journey.githubremote.options.md delete mode 100644 docs/api/cautious-journey.githubremote.request.md rename docs/api/{cautious-journey.githubremote.splitproject.md => cautious-journey.githubremote.resolvepath.md} (73%) delete mode 100644 docs/api/cautious-journey.githubremote.writecapable.md delete mode 100644 docs/api/cautious-journey.githubremote.writerequest.md delete mode 100644 docs/api/cautious-journey.gitlabremote.client.md delete mode 100644 docs/api/cautious-journey.gitlabremote.options.md create mode 100644 src/remote/base.ts diff --git a/docs/api/cautious-journey.githubremote.formatbody.md b/docs/api/cautious-journey.githubremote.formatbody.md deleted file mode 100644 index 357e14b..0000000 --- a/docs/api/cautious-journey.githubremote.formatbody.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [formatBody](./cautious-journey.githubremote.formatbody.md) - -## GithubRemote.formatBody() method - -Signature: - -```typescript -formatBody(options: CommentUpdate): string; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| options | CommentUpdate | | - -Returns: - -string - diff --git a/docs/api/cautious-journey.githubremote.md b/docs/api/cautious-journey.githubremote.md index 5115ca0..0ead375 100644 --- a/docs/api/cautious-journey.githubremote.md +++ b/docs/api/cautious-journey.githubremote.md @@ -9,8 +9,10 @@ Github/Octokit API implementation of the `Remote` contract. Signature: ```typescript -export declare class GithubRemote implements Remote +export declare class GithubRemote extends BaseRemote implements Remote ``` +Extends: BaseRemote<Octokit, [RemoteOptions](./cautious-journey.remoteoptions.md)> + Implements: [Remote](./cautious-journey.remote.md) ## Constructors @@ -19,15 +21,6 @@ export declare class GithubRemote implements Remote | --- | --- | --- | | [(constructor)(options)](./cautious-journey.githubremote._constructor_.md) | | Constructs a new instance of the GithubRemote class | -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [options](./cautious-journey.githubremote.options.md) | | [RemoteOptions](./cautious-journey.remoteoptions.md) | | -| [request](./cautious-journey.githubremote.request.md) | | Octokit | Github API client. Will not be set for a dry run. | -| [writeCapable](./cautious-journey.githubremote.writecapable.md) | | boolean | | -| [writeRequest](./cautious-journey.githubremote.writerequest.md) | | Octokit | | - ## Methods | Method | Modifiers | Description | @@ -36,12 +29,11 @@ export declare class GithubRemote implements Remote | [createComment(options)](./cautious-journey.githubremote.createcomment.md) | | | | [createLabel(options)](./cautious-journey.githubremote.createlabel.md) | | | | [deleteLabel(options)](./cautious-journey.githubremote.deletelabel.md) | | | -| [formatBody(options)](./cautious-journey.githubremote.formatbody.md) | | | | [getIssue()](./cautious-journey.githubremote.getissue.md) | | | | [getLabel()](./cautious-journey.githubremote.getlabel.md) | | | | [listIssues(options)](./cautious-journey.githubremote.listissues.md) | | | | [listLabels(options)](./cautious-journey.githubremote.listlabels.md) | | | -| [splitProject(project)](./cautious-journey.githubremote.splitproject.md) | | | +| [resolvePath(project)](./cautious-journey.githubremote.resolvepath.md) | | | | [updateIssue(options)](./cautious-journey.githubremote.updateissue.md) | | | | [updateLabel(options)](./cautious-journey.githubremote.updatelabel.md) | | | diff --git a/docs/api/cautious-journey.githubremote.options.md b/docs/api/cautious-journey.githubremote.options.md deleted file mode 100644 index 6e69588..0000000 --- a/docs/api/cautious-journey.githubremote.options.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [options](./cautious-journey.githubremote.options.md) - -## GithubRemote.options property - -Signature: - -```typescript -protected options: RemoteOptions; -``` diff --git a/docs/api/cautious-journey.githubremote.request.md b/docs/api/cautious-journey.githubremote.request.md deleted file mode 100644 index 2275f59..0000000 --- a/docs/api/cautious-journey.githubremote.request.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [request](./cautious-journey.githubremote.request.md) - -## GithubRemote.request property - -Github API client. Will not be set for a dry run. - -Signature: - -```typescript -protected request?: Octokit; -``` diff --git a/docs/api/cautious-journey.githubremote.splitproject.md b/docs/api/cautious-journey.githubremote.resolvepath.md similarity index 73% rename from docs/api/cautious-journey.githubremote.splitproject.md rename to docs/api/cautious-journey.githubremote.resolvepath.md index 54b4c7a..2ae379e 100644 --- a/docs/api/cautious-journey.githubremote.splitproject.md +++ b/docs/api/cautious-journey.githubremote.resolvepath.md @@ -1,13 +1,13 @@ -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [splitProject](./cautious-journey.githubremote.splitproject.md) +[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [resolvePath](./cautious-journey.githubremote.resolvepath.md) -## GithubRemote.splitProject() method +## GithubRemote.resolvePath() method Signature: ```typescript -splitProject(project: string): Promise<{ +resolvePath(project: string): Promise<{ owner: string; repo: string; }>; diff --git a/docs/api/cautious-journey.githubremote.writecapable.md b/docs/api/cautious-journey.githubremote.writecapable.md deleted file mode 100644 index fc837b6..0000000 --- a/docs/api/cautious-journey.githubremote.writecapable.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [writeCapable](./cautious-journey.githubremote.writecapable.md) - -## GithubRemote.writeCapable property - -Signature: - -```typescript -protected get writeCapable(): boolean; -``` diff --git a/docs/api/cautious-journey.githubremote.writerequest.md b/docs/api/cautious-journey.githubremote.writerequest.md deleted file mode 100644 index e743157..0000000 --- a/docs/api/cautious-journey.githubremote.writerequest.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GithubRemote](./cautious-journey.githubremote.md) > [writeRequest](./cautious-journey.githubremote.writerequest.md) - -## GithubRemote.writeRequest property - -Signature: - -```typescript -protected get writeRequest(): Octokit; -``` diff --git a/docs/api/cautious-journey.gitlabremote.client.md b/docs/api/cautious-journey.gitlabremote.client.md deleted file mode 100644 index c5b5ccd..0000000 --- a/docs/api/cautious-journey.gitlabremote.client.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GitlabRemote](./cautious-journey.gitlabremote.md) > [client](./cautious-journey.gitlabremote.client.md) - -## GitlabRemote.client property - -Signature: - -```typescript -protected client?: RemoteBundle; -``` diff --git a/docs/api/cautious-journey.gitlabremote.createcomment.md b/docs/api/cautious-journey.gitlabremote.createcomment.md index e3913e1..0a4082e 100644 --- a/docs/api/cautious-journey.gitlabremote.createcomment.md +++ b/docs/api/cautious-journey.gitlabremote.createcomment.md @@ -7,8 +7,15 @@ Signature: ```typescript -createComment(): Promise; +createComment(options: CommentUpdate): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | CommentUpdate | | + Returns: Promise<void> diff --git a/docs/api/cautious-journey.gitlabremote.createlabel.md b/docs/api/cautious-journey.gitlabremote.createlabel.md index f54fad8..cb9896e 100644 --- a/docs/api/cautious-journey.gitlabremote.createlabel.md +++ b/docs/api/cautious-journey.gitlabremote.createlabel.md @@ -7,8 +7,15 @@ Signature: ```typescript -createLabel(): Promise; +createLabel(options: LabelUpdate): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | LabelUpdate | | + Returns: Promise<LabelUpdate> diff --git a/docs/api/cautious-journey.gitlabremote.deletelabel.md b/docs/api/cautious-journey.gitlabremote.deletelabel.md index 56ff93f..e7e8f64 100644 --- a/docs/api/cautious-journey.gitlabremote.deletelabel.md +++ b/docs/api/cautious-journey.gitlabremote.deletelabel.md @@ -7,8 +7,15 @@ Signature: ```typescript -deleteLabel(): Promise; +deleteLabel(options: LabelUpdate): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | LabelUpdate | | + Returns: Promise<LabelUpdate> diff --git a/docs/api/cautious-journey.gitlabremote.md b/docs/api/cautious-journey.gitlabremote.md index f9110cc..6ec5be3 100644 --- a/docs/api/cautious-journey.gitlabremote.md +++ b/docs/api/cautious-journey.gitlabremote.md @@ -9,8 +9,10 @@ Gitlab API implementation of the `Remote` contract. Signature: ```typescript -export declare class GitlabRemote implements Remote +export declare class GitlabRemote extends BaseRemote implements Remote ``` +Extends: BaseRemote<RemoteBundle, [RemoteOptions](./cautious-journey.remoteoptions.md)> + Implements: [Remote](./cautious-journey.remote.md) ## Constructors @@ -19,26 +21,19 @@ export declare class GitlabRemote implements Remote | --- | --- | --- | | [(constructor)(options)](./cautious-journey.gitlabremote._constructor_.md) | | Constructs a new instance of the GitlabRemote class | -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [client](./cautious-journey.gitlabremote.client.md) | | RemoteBundle | | -| [options](./cautious-journey.gitlabremote.options.md) | | [RemoteOptions](./cautious-journey.remoteoptions.md) | | - ## Methods | Method | Modifiers | Description | | --- | --- | --- | | [connect()](./cautious-journey.gitlabremote.connect.md) | | | -| [createComment()](./cautious-journey.gitlabremote.createcomment.md) | | | -| [createLabel()](./cautious-journey.gitlabremote.createlabel.md) | | | -| [deleteLabel()](./cautious-journey.gitlabremote.deletelabel.md) | | | +| [createComment(options)](./cautious-journey.gitlabremote.createcomment.md) | | | +| [createLabel(options)](./cautious-journey.gitlabremote.createlabel.md) | | | +| [deleteLabel(options)](./cautious-journey.gitlabremote.deletelabel.md) | | | | [getIssue()](./cautious-journey.gitlabremote.getissue.md) | | | | [getLabel()](./cautious-journey.gitlabremote.getlabel.md) | | | | [listIssues(options)](./cautious-journey.gitlabremote.listissues.md) | | | | [listLabels(options)](./cautious-journey.gitlabremote.listlabels.md) | | | | [resolvePath(path)](./cautious-journey.gitlabremote.resolvepath.md) | | | -| [updateIssue()](./cautious-journey.gitlabremote.updateissue.md) | | | -| [updateLabel()](./cautious-journey.gitlabremote.updatelabel.md) | | | +| [updateIssue(options)](./cautious-journey.gitlabremote.updateissue.md) | | | +| [updateLabel(options)](./cautious-journey.gitlabremote.updatelabel.md) | | | diff --git a/docs/api/cautious-journey.gitlabremote.options.md b/docs/api/cautious-journey.gitlabremote.options.md deleted file mode 100644 index dc048bc..0000000 --- a/docs/api/cautious-journey.gitlabremote.options.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [GitlabRemote](./cautious-journey.gitlabremote.md) > [options](./cautious-journey.gitlabremote.options.md) - -## GitlabRemote.options property - -Signature: - -```typescript -protected options: RemoteOptions; -``` diff --git a/docs/api/cautious-journey.gitlabremote.updateissue.md b/docs/api/cautious-journey.gitlabremote.updateissue.md index 1602b41..bd66e8f 100644 --- a/docs/api/cautious-journey.gitlabremote.updateissue.md +++ b/docs/api/cautious-journey.gitlabremote.updateissue.md @@ -7,8 +7,15 @@ Signature: ```typescript -updateIssue(): Promise; +updateIssue(options: IssueUpdate): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | IssueUpdate | | + Returns: Promise<IssueUpdate> diff --git a/docs/api/cautious-journey.gitlabremote.updatelabel.md b/docs/api/cautious-journey.gitlabremote.updatelabel.md index 84fa7da..fbe2a0b 100644 --- a/docs/api/cautious-journey.gitlabremote.updatelabel.md +++ b/docs/api/cautious-journey.gitlabremote.updatelabel.md @@ -7,8 +7,15 @@ Signature: ```typescript -updateLabel(): Promise; +updateLabel(options: LabelUpdate): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | LabelUpdate | | + Returns: Promise<LabelUpdate> diff --git a/src/config/schema.yml b/src/config/schema.yml index d2b99cb..b98c6fa 100644 --- a/src/config/schema.yml +++ b/src/config/schema.yml @@ -3,7 +3,7 @@ $id: cautious-journey definitions: hex-string: type: string - pattern: "[0-9a-fA-F]{6}" + pattern: "^[0-9a-fA-F]{6}$" label-ref: type: object diff --git a/src/remote/base.ts b/src/remote/base.ts new file mode 100644 index 0000000..309231e --- /dev/null +++ b/src/remote/base.ts @@ -0,0 +1,68 @@ +import { doesExist, InvalidArgumentError } from '@apextoaster/js-utils'; + +import { CommentUpdate, IssueQuery, IssueUpdate, LabelQuery, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.'; +import { ChangeVerb } from '../resolve'; +import { VERSION_INFO } from '../version'; + +export abstract class BaseRemote implements Remote { + protected client?: TClient; + protected options: TOptions; + + constructor(options: TOptions) { + this.options = options; + } + + public abstract connect(): Promise; + public abstract createComment(options: CommentUpdate): Promise; + public abstract createLabel(options: LabelUpdate): Promise; + public abstract deleteLabel(options: LabelQuery): Promise; + public abstract getIssue(options: IssueQuery): Promise>; + public abstract getLabel(options: LabelQuery): Promise>; + public abstract listIssues(options: ProjectQuery): Promise>; + public abstract listLabels(options: ProjectQuery): Promise>; + public abstract updateIssue(options: IssueUpdate): Promise; + public abstract updateLabel(options: LabelUpdate): Promise; + + 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 { + return this.options.dryrun === false; + } + + protected get writeClient(): TClient { + if (doesExist(this.client)) { + return this.client; + } else { + throw new InvalidArgumentError(); + } + } +} diff --git a/src/remote/github.ts b/src/remote/github.ts index 449defd..0a41993 100644 --- a/src/remote/github.ts +++ b/src/remote/github.ts @@ -1,24 +1,17 @@ -import { doesExist, InvalidArgumentError, mustExist, NotImplementedError } from '@apextoaster/js-utils'; +import { InvalidArgumentError, mustExist, NotImplementedError } from '@apextoaster/js-utils'; import { createAppAuth } from '@octokit/auth-app'; import { Octokit } from '@octokit/rest'; import { CommentUpdate, IssueUpdate, LabelQuery, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.'; -import { ChangeVerb } from '../resolve'; -import { VERSION_INFO } from '../version'; +import { BaseRemote } from './base'; /** * Github/Octokit API implementation of the `Remote` contract. */ -export class GithubRemote implements Remote { - protected options: RemoteOptions; - - /** - * Github API client. Will not be set for a dry run. - */ - protected request?: Octokit; - +export class GithubRemote extends BaseRemote implements Remote { constructor(options: RemoteOptions) { - this.options = options; + super(options); + this.options.logger.debug(options, 'created github remote'); } @@ -30,7 +23,7 @@ export class GithubRemote implements Remote { switch (type) { case 'app': this.options.logger.info('using app auth'); - this.request = new Octokit({ + this.client = new Octokit({ auth: { id: parseInt(mustExist(this.options.data.id), 10), installationId: parseInt(mustExist(this.options.data.installationId), 10), @@ -41,7 +34,7 @@ export class GithubRemote implements Remote { break; case 'token': this.options.logger.info('using token auth'); - this.request = new Octokit({ + this.client = new Octokit({ auth: mustExist(this.options.data.token), }); break; @@ -52,7 +45,7 @@ export class GithubRemote implements Remote { return true; } - public async splitProject(project: string): Promise<{ + public async resolvePath(project: string): Promise<{ owner: string; repo: string; }> { @@ -64,7 +57,7 @@ export class GithubRemote implements Remote { } public async createComment(options: CommentUpdate): Promise { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); const body = this.formatBody(options); this.options.logger.debug({ @@ -74,7 +67,7 @@ export class GithubRemote implements Remote { }, 'creating issue comment'); if (this.writeCapable) { - await this.writeRequest.issues.createComment({ + await this.writeClient.issues.createComment({ body, /* eslint-disable-next-line camelcase */ issue_number: parseInt(options.issue, 10), @@ -87,11 +80,11 @@ export class GithubRemote implements Remote { } public async createLabel(options: LabelUpdate): Promise { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); // TODO: check if the label already exists if (this.writeCapable) { - await this.writeRequest.issues.createLabel({ + await this.writeClient.issues.createLabel({ color: options.color, description: options.desc, name: options.name, @@ -104,11 +97,11 @@ export class GithubRemote implements Remote { } public async deleteLabel(options: LabelQuery): Promise { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); // TODO: check if the label is in use if (this.writeCapable) { - await this.writeRequest.issues.deleteLabel({ + await this.writeClient.issues.deleteLabel({ name: options.name, owner: path.owner, repo: path.repo, @@ -127,11 +120,11 @@ export class GithubRemote implements Remote { } public async listIssues(options: ProjectQuery): Promise> { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); const issues: Array = []; - const repo = await mustExist(this.request).issues.listForRepo(path); + const repo = await mustExist(this.client).issues.listForRepo(path); for (const issue of repo.data) { issues.push({ issue: issue.number.toString(), @@ -145,11 +138,11 @@ export class GithubRemote implements Remote { } public async listLabels(options: ProjectQuery): Promise> { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); const labels: Array = []; - const repo = await mustExist(this.request).issues.listLabelsForRepo(path); + const repo = await mustExist(this.client).issues.listLabelsForRepo(path); for (const label of repo.data) { labels.push({ color: label.color, @@ -163,10 +156,10 @@ export class GithubRemote implements Remote { } public async updateIssue(options: IssueUpdate): Promise { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); if (this.writeCapable) { - const data = await this.writeRequest.issues.setLabels({ + const data = await this.writeClient.issues.setLabels({ /* eslint-disable-next-line camelcase */ issue_number: parseInt(options.issue, 10), labels: options.labels, @@ -181,10 +174,10 @@ export class GithubRemote implements Remote { } public async updateLabel(options: LabelUpdate): Promise { - const path = await this.splitProject(options.project); + const path = await this.resolvePath(options.project); if (this.writeCapable) { - const data = await this.writeRequest.issues.updateLabel({ + const data = await this.writeClient.issues.updateLabel({ color: options.color, description: options.desc, name: options.name, @@ -202,47 +195,4 @@ export class GithubRemote implements Remote { return options; } } - - 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 { - return this.options.dryrun === false; - } - - protected get writeRequest(): Octokit { - if (doesExist(this.request)) { - return this.request; - } else { - throw new InvalidArgumentError(); - } - } } diff --git a/src/remote/gitlab.ts b/src/remote/gitlab.ts index 9c1fa12..c8ae89a 100644 --- a/src/remote/gitlab.ts +++ b/src/remote/gitlab.ts @@ -1,16 +1,20 @@ import { mustExist, NotImplementedError } from '@apextoaster/js-utils'; import { GetResponse } from '@gitbeaker/core/dist/types/infrastructure/RequestHelper'; import { Bundle } from '@gitbeaker/core/dist/types/infrastructure/Utils'; -import { Issues, Labels, Projects, ProjectsBundle } from '@gitbeaker/node'; +import { IssueNotes, Issues, Labels, Projects, ProjectsBundle } from '@gitbeaker/node'; -import { IssueQuery, IssueUpdate, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.'; +import { CommentUpdate, IssueQuery, IssueUpdate, LabelUpdate, ProjectQuery, Remote, RemoteOptions } from '.'; +import { BaseRemote } from './base'; + +/* eslint-disable no-console */ // gitbeaker exports the bundle types as const, breaking typeof type RemoteBundle = InstanceType>; +}, 'Issues' | 'IssueNotes' | 'Labels' | 'Projects'>>; export function unwrapResponse(resp: GetResponse): T { return (resp as unknown) as T; @@ -19,13 +23,10 @@ export function unwrapResponse(resp: GetResponse): T { /** * Gitlab API implementation of the `Remote` contract. */ -export class GitlabRemote implements Remote { - protected client?: RemoteBundle; - protected options: RemoteOptions; - - /* eslint-disable-next-line no-useless-constructor */ +export class GitlabRemote extends BaseRemote implements Remote { constructor(options: RemoteOptions) { - this.options = options; + super(options); + this.options.logger.debug(options, 'created gitlab remote'); } @@ -38,16 +39,35 @@ export class GitlabRemote implements Remote { return true; } - public async createComment(): Promise { - throw new NotImplementedError(); + public async createComment(options: CommentUpdate): Promise { + const project = await this.resolvePath(options.project); + const body = this.formatBody(options); + + if (this.writeCapable) { + await this.writeClient.IssueNotes.create(project.projectId, parseInt(options.issue, 10), body); + } } - public async createLabel(): Promise { - throw new NotImplementedError(); + public async createLabel(options: LabelUpdate): Promise { + const project = await this.resolvePath(options.project); + + if (this.writeCapable) { + await this.writeClient.Labels.create(project.projectId, options.name, '#' + options.color, { + description: options.desc, + }); + } + + return options; } - public async deleteLabel(): Promise { - throw new NotImplementedError(); + public async deleteLabel(options: LabelUpdate): Promise { + const project = await this.resolvePath(options.project); + + if (this.writeCapable) { + await this.writeClient.Labels.remove(project.projectId, options.name); + } + + return options; } public async getIssue(): Promise> { @@ -65,7 +85,7 @@ export class GitlabRemote implements Remote { })); return data.map((issue) => ({ - issue: issue.id.toString(), + issue: issue.iid.toString(), labels: issue.labels, name: issue.title, project: options.project, @@ -77,19 +97,36 @@ export class GitlabRemote implements Remote { const data = unwrapResponse>(await mustExist(this.client).Labels.all(project.projectId)); return data.map((label) => ({ - color: label.color, + color: label.color.replace(/^#/, ''), desc: label.description, name: label.name, project: options.project, })); } - public async updateIssue(): Promise { - throw new NotImplementedError(); + public async updateIssue(options: IssueUpdate): Promise { + const project = await this.resolvePath(options.project); + + if (this.writeCapable) { + await this.writeClient.Issues.edit(project.projectId, parseInt(options.issue, 10), { + labels: options.labels, + }); + } + + return options; } - public async updateLabel(): Promise { - throw new NotImplementedError(); + public async updateLabel(options: LabelUpdate): Promise { + const project = await this.resolvePath(options.project); + + if (this.writeCapable) { + await this.writeClient.Labels.edit(project.projectId, options.name, { + color: '#' + options.color, + description: options.desc, + }); + } + + return options; } public async resolvePath(path: string): Promise<{