Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit f17eb3c

Browse files
committed
feat: add update pull request command
Add command to update pull request title and body.
1 parent 6faa4a2 commit f17eb3c

File tree

9 files changed

+128
-25
lines changed

9 files changed

+128
-25
lines changed

src/command.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export abstract class Command {
2626
export abstract class TokenCommand extends Command {
2727

2828
@inject
29-
protected githubManager: WorkflowManager;
29+
protected workflowManager: WorkflowManager;
3030

3131
@inject('vscode.WorkspaceFolder')
3232
protected folder: vscode.WorkspaceFolder;
@@ -35,7 +35,7 @@ export abstract class TokenCommand extends Command {
3535
private channel: vscode.OutputChannel;
3636

3737
public async run(...args: any[]): Promise<void> {
38-
if (!(this.githubManager && this.githubManager.connected && this.folder)) {
38+
if (!(this.workflowManager && this.workflowManager.connected && this.folder)) {
3939
this.track('execute without token');
4040
vscode.window.showWarningMessage('Please setup your Github Personal Access Token '
4141
+ 'and open a GitHub project in your workspace');

src/commands/browse.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class BrowseProject extends TokenCommand {
1111

1212
@showProgress
1313
protected async runWithToken(): Promise<void> {
14-
const url = await this.githubManager.getRepositoryUrl();
14+
const url = await this.workflowManager.getRepositoryUrl();
1515
await vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url));
1616
}
1717

@@ -24,7 +24,7 @@ export class BrowseOpenIssues extends TokenCommand {
2424

2525
@showProgress
2626
protected async runWithToken(): Promise<void> {
27-
const issues = await this.githubManager.issues();
27+
const issues = await this.workflowManager.issues();
2828
if (issues.length > 0) {
2929
const selected = await vscode.window.showQuickPick(issues.map(issue => ({
3030
label: `${issue.title}`,
@@ -52,7 +52,7 @@ export class BrowseCurrentFile extends TokenCommand {
5252
if (vscode.workspace.workspaceFolders && editor) {
5353
const file = editor.document.fileName.substring(vscode.workspace.workspaceFolders[0].uri.fsPath.length);
5454
const line = editor.selection.active.line;
55-
const uri = vscode.Uri.parse(await this.githubManager.getGithubFileUrl(file, line));
55+
const uri = vscode.Uri.parse(await this.workflowManager.getGithubFileUrl(file, line));
5656
vscode.commands.executeCommand('vscode.open', uri);
5757
}
5858
}

src/commands/pull-requests.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ abstract class PullRequestCommand extends TokenCommand {
1414
protected git: Git;
1515

1616
protected async selectPullRequest(): Promise<PullRequest | undefined> {
17-
const pullRequests = await this.githubManager.listPullRequests();
17+
const pullRequests = await this.workflowManager.listPullRequests();
1818
const items = pullRequests.map(pullRequest => ({
1919
label: pullRequest.title,
2020
description: `#${pullRequest.number}`,
@@ -81,7 +81,7 @@ export class BrowseSimpleRequest extends PullRequestCommand {
8181

8282
@showProgress
8383
protected async runWithToken(): Promise<void> {
84-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
84+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
8585
if (pullRequest) {
8686
await vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(pullRequest.url));
8787
} else {
@@ -124,7 +124,7 @@ export class CreatePullRequestWithParameters extends PullRequestCommand {
124124
if (!this.requireRemoteTrackingBranch()) {
125125
return;
126126
}
127-
const pullRequest = await this.githubManager.createPullRequestFromData({
127+
const pullRequest = await this.workflowManager.createPullRequestFromData({
128128
sourceBranch,
129129
targetBranch,
130130
title,
@@ -151,7 +151,7 @@ export class CreateSimplePullRequest extends PullRequestCommand {
151151
if (!this.requireRemoteTrackingBranch()) {
152152
return;
153153
}
154-
const pullRequest = await this.githubManager.createPullRequest();
154+
const pullRequest = await this.workflowManager.createPullRequest();
155155
if (pullRequest) {
156156
this.statusBarManager.updateStatus();
157157
this.showPullRequestNotification(pullRequest);
@@ -183,7 +183,7 @@ export class CreatePullRequest extends PullRequestCommand {
183183
if (!branch) {
184184
return;
185185
}
186-
const pullRequest = await this.githubManager.createPullRequest({
186+
const pullRequest = await this.workflowManager.createPullRequest({
187187
owner,
188188
repository: repo,
189189
branch
@@ -195,7 +195,7 @@ export class CreatePullRequest extends PullRequestCommand {
195195
}
196196

197197
private async getRepository(): Promise<{label: string, repo: { defaultBranch: string }} | undefined> {
198-
const repository = await this.githubManager.getRepository();
198+
const repository = await this.workflowManager.getRepository();
199199
const items = [{
200200
label: repository.name,
201201
description: '',
@@ -249,7 +249,7 @@ export class MergePullRequest extends PullRequestCommand {
249249
return config.preferedMergeMethod;
250250
}
251251
const items: { label: string; description: string; method: MergeMethod; }[] = [];
252-
const enabledMethods = await this.githubManager.getEnabledMergeMethods();
252+
const enabledMethods = await this.workflowManager.getEnabledMergeMethods();
253253
if (enabledMethods.has('merge')) {
254254
items.push({
255255
label: 'Create merge commit',
@@ -277,11 +277,11 @@ export class MergePullRequest extends PullRequestCommand {
277277

278278
@showProgress
279279
protected async runWithToken(): Promise<void> {
280-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
280+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
281281
if (pullRequest && pullRequest.mergeable) {
282282
const method = await this.getMergeMethdod();
283283
if (method) {
284-
if (await this.githubManager.mergePullRequest(pullRequest, method)) {
284+
if (await this.workflowManager.mergePullRequest(pullRequest, method)) {
285285
this.statusBarManager.updateStatus();
286286
vscode.window.showInformationMessage(`Successfully merged`);
287287
} else {
@@ -295,3 +295,20 @@ export class MergePullRequest extends PullRequestCommand {
295295
}
296296

297297
}
298+
299+
@component({eager: true})
300+
export class UpdatePullRequest extends PullRequestCommand {
301+
302+
public id = 'vscode-github.updatePullRequest';
303+
304+
@showProgress
305+
protected async runWithToken(): Promise<void> {
306+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
307+
if (pullRequest) {
308+
await this.workflowManager.updatePullRequest(pullRequest);
309+
} else {
310+
vscode.window.showInformationMessage('No pull request for current branch found');
311+
}
312+
}
313+
314+
}

src/commands/user.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ export class AddAssignee extends UserCommand {
2020

2121
@showProgress
2222
protected async runWithToken(): Promise<void> {
23-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
23+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
2424
if (pullRequest) {
2525
const user = await this.getUser();
2626
if (user) {
27-
await this.githubManager.addAssignee(pullRequest, user);
27+
await this.workflowManager.addAssignee(pullRequest, user);
2828
vscode.window.showInformationMessage(`Successfully assigned ${user} to the pull request`);
2929
}
3030
} else {
@@ -41,9 +41,9 @@ export class RemoveAssignee extends UserCommand {
4141

4242
@showProgress
4343
protected async runWithToken(): Promise<void> {
44-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
44+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
4545
if (pullRequest) {
46-
await this.githubManager.removeAssignee(pullRequest);
46+
await this.workflowManager.removeAssignee(pullRequest);
4747
vscode.window.showInformationMessage(`Successfully unassigned the pull request`);
4848
} else {
4949
vscode.window.showWarningMessage('No pull request for current brach');
@@ -59,11 +59,11 @@ export class RequestReview extends UserCommand {
5959

6060
@showProgress
6161
protected async runWithToken(): Promise<void> {
62-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
62+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
6363
if (pullRequest) {
6464
const user = await this.getUser();
6565
if (user) {
66-
await this.githubManager.requestReview(pullRequest.number, user);
66+
await this.workflowManager.requestReview(pullRequest.number, user);
6767
vscode.window.showInformationMessage(`Successfully requested review from ${user}`);
6868
}
6969
} else {
@@ -80,11 +80,11 @@ export class DeleteReviewRequest extends UserCommand {
8080

8181
@showProgress
8282
protected async runWithToken(): Promise<void> {
83-
const pullRequest = await this.githubManager.getPullRequestForCurrentBranch();
83+
const pullRequest = await this.workflowManager.getPullRequestForCurrentBranch();
8484
if (pullRequest) {
8585
const user = await this.getUser();
8686
if (user) {
87-
await this.githubManager.deleteReviewRequest(pullRequest.number, user);
87+
await this.workflowManager.deleteReviewRequest(pullRequest.number, user);
8888
vscode.window.showInformationMessage(`Successfully canceled review request from ${user}`);
8989
}
9090
} else {

src/provider/github/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export interface GitHub {
1414
createPullRequest(owner: string, repo: string, body: CreatePullRequestBody):
1515
Promise<GitHubResponse<PullRequestStruct>>;
1616

17+
updatePullRequest(owner: string, repo: string, number: number, body: UpdatePullRequestBody): Promise<void>;
18+
1719
getStatusForRef(owner: string, repo: string, ref: string): Promise<GitHubResponse<CombinedStatus>>;
1820

1921
mergePullRequest(owner: string, repo: string, number: number, body: Merge): Promise<GitHubResponse<MergeResult>>;
@@ -41,6 +43,12 @@ export interface GitHubResponse<T> {
4143
body: T;
4244
}
4345

46+
export interface UpdatePullRequestBody {
47+
title?: string;
48+
body?: string;
49+
state?: 'open' | 'closed';
50+
}
51+
4452
export interface UserResponse {
4553
id: number;
4654
login: string;
@@ -257,6 +265,9 @@ namespace impl {
257265
@Post('/repos/:owner/:repo/pulls')
258266
public createPullRequest(): any {/* */}
259267

268+
@Patch('/repos/:owner/:repo/pulls/:number')
269+
public updatePullRequest(): any {/* */}
270+
260271
@Get('/repos/:owner/:repo/commits/:ref/status')
261272
public getStatusForRef(): any {/* */}
262273

src/provider/github/pull-request.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
MergeResult,
66
RequestReviewBody,
77
CancelReviewBody,
8-
Comment
8+
Comment,
9+
UpdateBody
910
} from '../pull-request';
1011
import { GitHub, PullRequestStruct } from './index';
1112
import { GithubRepository } from './repository';
@@ -59,6 +60,19 @@ export class GithubPullRequest implements PullRequest {
5960
this.struct = struct;
6061
}
6162

63+
public async update(body: UpdateBody): Promise<void> {
64+
await this.client.updatePullRequest(
65+
this.repository.owner,
66+
this.repository.repository,
67+
this.number,
68+
{
69+
title: body.title,
70+
body: body.body,
71+
state: body.state
72+
}
73+
);
74+
}
75+
6276
public async getComments(): Promise<Response<Comment[]>> {
6377
const response = await this.client.getPullRequestComments(
6478
this.repository.owner,

src/provider/gitlab/merge-request.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import {
55
MergeResult,
66
RequestReviewBody,
77
CancelReviewBody,
8-
Comment
8+
Comment,
9+
UpdateBody
910
} from '../pull-request';
10-
import { GitLab, MergeRequest } from './api';
11+
import { GitLab, MergeRequest, UpdateMergeRequestBody } from './api';
1112
import { GitLabRepository } from './repository';
1213
import { GitLabUser } from './user';
1314

@@ -68,6 +69,34 @@ export class GitLabMergeRequest implements PullRequest {
6869
this.mergeRequest = mergeRequest;
6970
}
7071

72+
public async update(body: UpdateBody): Promise<void> {
73+
const gitlabBody: UpdateMergeRequestBody = {};
74+
if (body.title) {
75+
gitlabBody.title = body.title;
76+
}
77+
if (body.body) {
78+
gitlabBody.description = body.body;
79+
}
80+
if (body.state) {
81+
const mapState = (state: UpdateBody['state']): UpdateMergeRequestBody['state_event'] => {
82+
switch (state) {
83+
case 'open':
84+
return 'reopen';
85+
case 'closed':
86+
return 'close';
87+
default:
88+
return undefined;
89+
}
90+
};
91+
gitlabBody.state_event = mapState(body.state);
92+
}
93+
await this.client.updateMergeRequest(
94+
encodeURIComponent(this.repository.pathWithNamespace),
95+
this.mergeRequest.iid,
96+
gitlabBody
97+
);
98+
}
99+
71100
public async getComments(): Promise<Response<Comment[]>> {
72101
throw new Error('Method not implemented.');
73102
}

src/provider/pull-request.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface PullRequest {
1212
targetBranch: string;
1313
mergeable?: boolean|null;
1414

15+
update(body: UpdateBody): Promise<void>;
1516
getComments(): Promise<Response<Comment[]>>;
1617
merge(body: MergeBody): Promise<Response<MergeResult>>;
1718
assign(assignees: User[]): Promise<void>;
@@ -32,6 +33,12 @@ export interface MergeResult {
3233
message: string;
3334
}
3435

36+
export interface UpdateBody {
37+
title?: string;
38+
body?: string;
39+
state?: 'open' | 'closed';
40+
}
41+
3542
export interface RequestReviewBody {
3643
reviewers: string[];
3744
}

src/workflow-manager.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,31 @@ export class WorkflowManager {
169169
}
170170
}
171171

172+
public async updatePullRequest(pullRequest: PullRequest): Promise<void> {
173+
if (await this.hasPullRequestForCurrentBranch()) {
174+
return undefined;
175+
}
176+
const branch = await this.git.getCurrentBranch();
177+
if (!branch) {
178+
throw new Error('No current branch');
179+
}
180+
this.log(`Update pull request on branch '${branch}'`);
181+
const firstCommit = await this.git.getFirstCommitOnBranch(branch, pullRequest.targetBranch);
182+
this.log(`First commit on branch '${firstCommit}'`);
183+
const requestBody = await this.git.getPullRequestBody(firstCommit);
184+
if (requestBody === undefined) {
185+
vscode.window.showWarningMessage(
186+
`For some unknown reason no pull request body could be build; Aborting operation`);
187+
return undefined;
188+
}
189+
if (requestBody !== pullRequest.body) {
190+
await pullRequest.update({
191+
title: await this.git.getCommitMessage(firstCommit),
192+
body: requestBody
193+
});
194+
}
195+
}
196+
172197
public async listPullRequests(): Promise<PullRequest[]> {
173198
const repository = await this.getRepository();
174199
const parameters: ListPullRequestsParameters = {

0 commit comments

Comments
 (0)