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

Commit ab24371

Browse files
committed
refactor: rework for maintainability
1 parent 4733b87 commit ab24371

File tree

4 files changed

+154
-112
lines changed

4 files changed

+154
-112
lines changed

src/extension.ts

Lines changed: 30 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,31 @@ import {join} from 'path';
22
import * as sander from 'sander';
33
import * as vscode from 'vscode';
44
import * as git from './git';
5-
import {getClient, GitHub, GitHubError, ListPullRequestsParameters, CreatePullRequestBody} from './github';
5+
import {GitHubError} from './github';
6+
import {StatusBarManager} from './status-bar-manager';
7+
import {GitHubManager} from './github-manager';
68

79
let cwd: string;
8-
let storedToken: string;
9-
let github: GitHub;
1010
let channel: vscode.OutputChannel;
11-
let statusBar: vscode.StatusBarItem;
11+
let githubManager: GitHubManager;
12+
let statusBarManager: StatusBarManager;
1213

1314
export function activate(context: vscode.ExtensionContext): void {
14-
checkVersionAndToken(context);
15-
1615
cwd = vscode.workspace.rootPath;
17-
getToken(context)
18-
.then(_token => {
19-
storedToken = _token;
20-
refreshPullRequestStatus();
21-
});
2216

2317
channel = vscode.window.createOutputChannel('github');
2418
context.subscriptions.push(channel);
2519
channel.appendLine('Visual Studio Code GitHub Extension');
2620

21+
githubManager = new GitHubManager(cwd, channel);
22+
statusBarManager = new StatusBarManager(context, githubManager);
23+
24+
const token = getToken(context);
25+
if (token) {
26+
githubManager.connect(token);
27+
}
28+
checkVersionAndToken(context, token);
29+
2730
context.subscriptions.push(
2831
vscode.commands.registerCommand('extension.setGitHubToken',
2932
createGithubTokenCommand(context)));
@@ -36,23 +39,13 @@ export function activate(context: vscode.ExtensionContext): void {
3639
context.subscriptions.push(
3740
vscode.commands.registerCommand('extension.browserPullRequest',
3841
wrapCommand(browserPullRequest)));
39-
40-
statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
41-
statusBar.command = '';
42-
statusBar.text = '$(git-pull-request)';
43-
statusBar.color = '#888';
44-
context.subscriptions.push(statusBar);
4542
}
4643

47-
function checkVersionAndToken(context: vscode.ExtensionContext): void {
44+
function checkVersionAndToken(context: vscode.ExtensionContext, token: string|undefined): void {
4845
sander.readFile(join(context.extensionPath, 'package.json'))
4946
.then(content => JSON.parse(content))
5047
.then(json => json.version as string)
51-
.then(version => {
52-
return getToken(context)
53-
.then(token => ({token, version}));
54-
})
55-
.then(({version, token}) => {
48+
.then((version) => {
5649
const storedVersion = context.globalState.get('version-test');
5750
if (version !== storedVersion && !Boolean(token)) {
5851
context.globalState.update('version-test', version);
@@ -62,41 +55,9 @@ function checkVersionAndToken(context: vscode.ExtensionContext): void {
6255
});
6356
}
6457

65-
async function refreshPullRequestStatus(): Promise<void> {
66-
if (storedToken) {
67-
await updatePullRequestStatus();
68-
}
69-
setTimeout(refreshPullRequestStatus, 5000);
70-
}
71-
72-
async function updatePullRequestStatus(forceState?: boolean): Promise<void> {
73-
const hasPullRequest = await hasPullRequestForCurrentBranch();
74-
statusBar.show();
75-
if (forceState || hasPullRequest) {
76-
const status = await getCombinedStatusForPullRequest();
77-
switch (status) {
78-
case 'failure':
79-
statusBar.color = '#f00';
80-
break;
81-
case 'success':
82-
statusBar.color = '#0f0';
83-
break;
84-
default:
85-
statusBar.color = '#fff';
86-
break;
87-
}
88-
statusBar.tooltip = '';
89-
statusBar.command = '';
90-
} else {
91-
statusBar.color = '#888';
92-
statusBar.tooltip = 'Create pull-request for current branch';
93-
statusBar.command = 'extension.createPullRequest';
94-
}
95-
}
96-
9758
function wrapCommand<T>(command: T): T {
9859
const wrap: any = (...args: any[]) => {
99-
if (Boolean(storedToken) && Boolean(cwd)) {
60+
if (githubManager.connected && cwd) {
10061
return (command as any).apply(null, args);
10162
} else {
10263
vscode.window.showWarningMessage('Please setup your Github Personal Access Token '
@@ -106,15 +67,8 @@ function wrapCommand<T>(command: T): T {
10667
return wrap;
10768
}
10869

109-
function getToken(context: vscode.ExtensionContext): PromiseLike<string> {
110-
return Promise.resolve(context.globalState.get<string>('token'));
111-
}
112-
113-
function getGitHubClient(): GitHub {
114-
if (!github) {
115-
github = getClient(storedToken);
116-
}
117-
return github;
70+
function getToken(context: vscode.ExtensionContext): string|undefined {
71+
return context.globalState.get<string|undefined>('token');
11872
}
11973

12074
function logAndShowError(e: Error): void {
@@ -137,46 +91,16 @@ function createGithubTokenCommand(context: vscode.ExtensionContext): () => Promi
13791
return vscode.window.showInputBox(options)
13892
.then(input => {
13993
context.globalState.update('token', input);
140-
storedToken = input;
94+
githubManager.connect(input);
14195
});
14296
};
14397
}
14498

145-
async function hasPullRequestForCurrentBranch(): Promise<boolean> {
146-
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
147-
const branch = await git.getCurrentBranch(cwd);
148-
const parameters: ListPullRequestsParameters = {
149-
state: 'open',
150-
head: `${owner}:${branch}`
151-
};
152-
const response = await getGitHubClient().listPullRequests(owner, repository, parameters);
153-
return response.length > 0;
154-
}
155-
156-
async function getCombinedStatusForPullRequest(): Promise<'failure' | 'pending' | 'success' |undefined> {
157-
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
158-
const branch = await git.getCurrentBranch(cwd);
159-
if (!branch) {
160-
return undefined;
161-
}
162-
const response = await getGitHubClient().getStatusForRef(owner, repository, branch);
163-
return response.state;
164-
}
165-
16699
async function createPullRequest(): Promise<void> {
167100
try {
168-
if (!await hasPullRequestForCurrentBranch()) {
169-
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
170-
const branch = await git.getCurrentBranch(cwd);
171-
const body: CreatePullRequestBody = {
172-
title: await git.getCommitMessage(cwd),
173-
head: `${owner}:${branch}`,
174-
base: `master`
175-
};
176-
channel.appendLine('Create pull request:');
177-
channel.appendLine(JSON.stringify(body, undefined, ' '));
178-
const pullRequest = await getGitHubClient().createPullRequest(owner, repository, body);
179-
updatePullRequestStatus(true);
101+
const pullRequest = await githubManager.createPullRequest();
102+
if (pullRequest) {
103+
statusBarManager.updatePullRequestStatus(true);
180104
vscode.window.showInformationMessage(`Successfully created #${pullRequest.number}`);
181105
}
182106
} catch (e) {
@@ -186,18 +110,17 @@ async function createPullRequest(): Promise<void> {
186110

187111
async function checkoutPullRequests(): Promise<void> {
188112
try {
189-
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
190-
const parameters: ListPullRequestsParameters = {
191-
state: 'open'
192-
};
193-
const response = await getGitHubClient().listPullRequests(owner, repository, parameters);
194-
vscode.window.showQuickPick(response.map(pullRequest => ({
113+
const pullRequests = await githubManager.listPullRequests();
114+
vscode.window.showQuickPick(pullRequests.map(pullRequest => ({
195115
label: pullRequest.title,
196116
description: `#${pullRequest.number}`,
197117
pullRequest
198118
}))).then(selected => {
199119
if (selected) {
200-
git.checkout(cwd, selected.pullRequest.head.ref);
120+
git.checkout(cwd, selected.pullRequest.head.ref)
121+
.then(() => {
122+
statusBarManager.updatePullRequestStatus();
123+
});
201124
}
202125
});
203126
} catch (e) {
@@ -207,11 +130,7 @@ async function checkoutPullRequests(): Promise<void> {
207130

208131
async function browserPullRequest(): Promise<void> {
209132
try {
210-
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
211-
const parameters: ListPullRequestsParameters = {
212-
state: 'open'
213-
};
214-
const response = await getGitHubClient().listPullRequests(owner, repository, parameters);
133+
const response = await githubManager.listPullRequests();
215134
vscode.window.showQuickPick(response.map(pullRequest => ({
216135
label: pullRequest.title,
217136
description: `#${pullRequest.number}`,

src/github-manager.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import * as vscode from 'vscode';
2+
import * as git from './git';
3+
import {getClient, GitHub, PullRequest, ListPullRequestsParameters, CreatePullRequestBody} from './github';
4+
5+
export class GitHubManager {
6+
7+
private cwd: string;
8+
9+
private channel: vscode.OutputChannel;
10+
11+
private github: GitHub;
12+
13+
constructor(cwd: string, channel: vscode.OutputChannel) {
14+
this.cwd = cwd;
15+
this.channel = channel;
16+
}
17+
18+
get connected(): boolean {
19+
return Boolean(this.github);
20+
}
21+
22+
public connect(token: string): void {
23+
this.github = getClient(token);
24+
}
25+
26+
public async hasPullRequestForCurrentBranch(): Promise<boolean> {
27+
const [owner, repository] = await git.getGitHubOwnerAndRepository(this.cwd);
28+
const branch = await git.getCurrentBranch(this.cwd);
29+
const parameters: ListPullRequestsParameters = {
30+
state: 'open',
31+
head: `${owner}:${branch}`
32+
};
33+
const response = await this.github.listPullRequests(owner, repository, parameters);
34+
return response.length > 0;
35+
}
36+
37+
public async getCombinedStatusForPullRequest(): Promise<'failure' | 'pending' | 'success' |undefined> {
38+
const [owner, repository] = await git.getGitHubOwnerAndRepository(this.cwd);
39+
const branch = await git.getCurrentBranch(this.cwd);
40+
if (!branch) {
41+
return undefined;
42+
}
43+
const response = await this.github.getStatusForRef(owner, repository, branch);
44+
return response.state;
45+
}
46+
47+
public async createPullRequest(): Promise<PullRequest|undefined> {
48+
if (await this.hasPullRequestForCurrentBranch()) {
49+
return undefined;
50+
}
51+
const [owner, repository] = await git.getGitHubOwnerAndRepository(this.cwd);
52+
const branch = await git.getCurrentBranch(this.cwd);
53+
const body: CreatePullRequestBody = {
54+
title: await git.getCommitMessage(this.cwd),
55+
head: `${owner}:${branch}`,
56+
base: `master`
57+
};
58+
this.channel.appendLine('Create pull request:');
59+
this.channel.appendLine(JSON.stringify(body, undefined, ' '));
60+
return this.github.createPullRequest(owner, repository, body);
61+
}
62+
63+
public async listPullRequests(): Promise<PullRequest[]> {
64+
const [owner, repository] = await git.getGitHubOwnerAndRepository(this.cwd);
65+
const parameters: ListPullRequestsParameters = {
66+
state: 'open'
67+
};
68+
return await this.github.listPullRequests(owner, repository, parameters);
69+
}
70+
71+
}

src/github.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface CreatePullRequestBody {
3030
body?: string;
3131
}
3232

33-
interface PullRequest {
33+
export interface PullRequest {
3434
id: number;
3535
number: number;
3636
state: 'open' | 'closed';

src/status-bar-manager.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import * as vscode from 'vscode';
2+
import {GitHubManager} from './github-manager';
3+
4+
const colors = {
5+
'none': '#888',
6+
'success': '#0f0',
7+
'failure': '#f00',
8+
'pending': '#fff',
9+
'unknown': '#fff'
10+
};
11+
12+
export class StatusBarManager {
13+
14+
private statusBar: vscode.StatusBarItem;
15+
16+
private githubManager: GitHubManager;
17+
18+
constructor(context: vscode.ExtensionContext, githubManager: GitHubManager) {
19+
this.githubManager = githubManager;
20+
21+
this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
22+
this.statusBar.command = '';
23+
this.statusBar.text = '$(git-pull-request)';
24+
this.statusBar.color = colors.none;
25+
context.subscriptions.push(this.statusBar);
26+
27+
this.refreshPullRequestStatus();
28+
}
29+
30+
private async refreshPullRequestStatus(): Promise<void> {
31+
if (this.githubManager.connected) {
32+
await this.updatePullRequestStatus();
33+
}
34+
setTimeout(() => { this.refreshPullRequestStatus(); }, 5000);
35+
}
36+
37+
public async updatePullRequestStatus(forceState?: boolean): Promise<void> {
38+
const hasPullRequest = await this.githubManager.hasPullRequestForCurrentBranch();
39+
this.statusBar.show();
40+
if (forceState || hasPullRequest) {
41+
const status = await this.githubManager.getCombinedStatusForPullRequest();
42+
this.statusBar.color = colors[status || 'unknown'];
43+
this.statusBar.tooltip = '';
44+
this.statusBar.command = '';
45+
} else {
46+
this.statusBar.color = colors.none;
47+
this.statusBar.tooltip = 'Create pull-request for current branch';
48+
this.statusBar.command = 'extension.createPullRequest';
49+
}
50+
}
51+
52+
}

0 commit comments

Comments
 (0)