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

Commit f7735fc

Browse files
authored
fix(vscode-github): stabilized input of personal access token (#3)
1 parent 6453a15 commit f7735fc

8 files changed

+91
-99
lines changed

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
# vscode-github README
22

3+
[![Current Version](http://vsmarketplacebadge.apphb.com/version/vscode-github.svg)](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-github)
4+
[![Install Count](http://vsmarketplacebadge.apphb.com/installs/vscode-github.svg)](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-github)
5+
36
This vscode extension integrates with GitHub.
47

58
## Features
69

710
Current it is possible to do the following:
811

12+
* Store your GitHub Personal Access Token
13+
14+
To use this extension one needs to create a new GitHub Personal Access Token and registers it in the extension.
15+
The 'GitHub: Set Personal Access Token' should be executed for that.
16+
17+
![GitHub Personal Access Token](./images/github-personal-access-token.png)
18+
19+
![GitHub Personal Access Token](./images/github-personal-access-token2.png)
20+
21+
![Set GitHub Personal Access Token](./images/set-personal-access-token.png)
22+
923
* Create a new pull request based on the current branch and the last commit
1024
The current branch will be requested to merge into master and the pull request title is the commit message summary.
11-
* Checkout one of the open pull requests
1225

13-
## Requirements
26+
![Create pull request](./images/create-pull-request.png)
1427

15-
To use this extension one needs to create a new GitHub Personal Access Token and registers it in the extension.
16-
The 'GitHub: Set Personal Access Token' should be executed for that.
28+
* Checkout one of the open pull requests

images/create-pull-request.png

105 KB
Loading
68.7 KB
Loading
93.8 KB
Loading

images/set-personal-access-token.png

93.9 KB
Loading

src/extension.ts

Lines changed: 42 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
11
'use strict';
22
import * as vscode from 'vscode';
3-
import * as execa from 'execa';
3+
4+
import * as git from './git';
45

56
import {getClient, GitHub, GitHubError, ListPullRequestsParameters, CreatePullRequestBody} from './github';
67

7-
let github: GitHub;
88
let cwd: string;
9+
let token: string;
10+
let github: GitHub;
911

1012
export function activate(context: vscode.ExtensionContext): void {
1113
cwd = vscode.workspace.rootPath;
12-
getToken(context).then(token => {
13-
if (!github) {
14-
github = getClient(token);
15-
}
14+
getToken(context).then(_token => {
15+
token = _token;
1616
});
1717

1818
context.subscriptions.push(
1919
vscode.commands.registerCommand('extension.setGitHubToken',
2020
createGithubTokenCommand(context)));
2121
context.subscriptions.push(
2222
vscode.commands.registerCommand('extension.createPullRequest',
23-
createPullRequest));
23+
wrapCommand(createPullRequest)));
2424
context.subscriptions.push(
2525
vscode.commands.registerCommand('extension.checkoutPullRequests',
26-
checkoutPullRequests));
26+
wrapCommand(checkoutPullRequests)));
27+
}
28+
29+
function wrapCommand<T>(command: T): T {
30+
const wrap: any = (...args: any[]) => {
31+
if (Boolean(token) && Boolean(cwd)) {
32+
return (command as any).apply(null, args);
33+
} else {
34+
vscode.window.showWarningMessage('Please setup your Github Personal Access Token '
35+
+ 'and open a GitHub project in your workspace');
36+
}
37+
};
38+
return wrap;
2739
}
2840

2941
function getToken(context: vscode.ExtensionContext): PromiseLike<string> {
30-
let token = context.globalState.get<string>('token');
31-
if (token) {
32-
return Promise.resolve(token);
42+
return Promise.resolve(context.globalState.get<string>('token'));
43+
}
44+
45+
function getGitHubClient(): GitHub {
46+
if (!github) {
47+
github = getClient(token);
3348
}
34-
return createGithubTokenCommand(context)().then(() => {
35-
return context.globalState.get<string>('token');
36-
});
49+
return github;
3750
}
3851

3952
function createGithubTokenCommand(context: vscode.ExtensionContext): () => PromiseLike<void> {
@@ -44,69 +57,36 @@ function createGithubTokenCommand(context: vscode.ExtensionContext): () => Promi
4457
placeHolder: 'GitHub Personal Access Token'
4558
};
4659
return vscode.window.showInputBox(options)
47-
.then(input => context.globalState.update('token', input))
48-
.then(() => getToken(context))
49-
.then(token => {
50-
github = getClient(token);
60+
.then(input => {
61+
context.globalState.update('token', input);
62+
token = input;
5163
});
5264
};
5365
}
5466

55-
async function getGitHubOwnerAndRepository(): Promise<string[]> {
56-
return execa('git', ['config', '--get-regexp', 'remote\\.origin\\.url'], {cwd})
57-
.then(result => {
58-
const match = result.stdout.match(/^remote.origin.url git@github.com:(.*?)\/(.*?)(?:.git)?$/);
59-
if (!match) {
60-
throw new Error('Not a github project?');
61-
}
62-
return [match[1], match[2]];
63-
});
64-
}
65-
66-
async function getCurrentBranch(): Promise<string|undefined> {
67-
return execa('git', ['status', '--porcelain', '--branch'], {cwd})
68-
.then(result => {
69-
const match = result.stdout.match(/^## (.+?)(?:\.\.\..*)?/);
70-
return match ? match[1] : undefined;
71-
});
72-
}
73-
74-
async function getCommitMessage(): Promise<string> {
75-
return execa('git', ['log', '--oneline', '-1'], {cwd})
76-
.then(result => {
77-
const match = result.stdout.match(/^(?:.+?) (.*)/);
78-
return match ? match[1] : result.stdout;
79-
});
80-
}
81-
82-
async function checkout(branch: string): Promise<void> {
83-
return execa('git', ['checkout', branch], {cwd})
84-
.then(() => undefined);
85-
}
86-
87-
async function hasPullRequests(): Promise<boolean> {
88-
const [owner, repository] = await getGitHubOwnerAndRepository();
89-
const branch = await getCurrentBranch();
67+
async function hasPullRequestForCurrentBranch(): Promise<boolean> {
68+
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
69+
const branch = await git.getCurrentBranch(cwd);
9070
const parameters: ListPullRequestsParameters = {
9171
state: 'open',
9272
head: `${owner}:${branch}`
9373
};
94-
const response = await github.listPullRequests(owner, repository, parameters);
74+
const response = await getGitHubClient().listPullRequests(owner, repository, parameters);
9575
return response.body.length > 0;
9676
}
9777

9878
async function createPullRequest(): Promise<void> {
9979
try {
100-
if (!await hasPullRequests()) {
101-
const [owner, repository] = await getGitHubOwnerAndRepository();
102-
const branch = await getCurrentBranch();
80+
if (!await hasPullRequestForCurrentBranch()) {
81+
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
82+
const branch = await git.getCurrentBranch(cwd);
10383
console.log('orb', owner, repository, branch);
10484
const body: CreatePullRequestBody = {
105-
title: await getCommitMessage(),
85+
title: await git.getCommitMessage(cwd),
10686
head: `${owner}:${branch}`,
10787
base: `master`
10888
};
109-
const result = await github.createPullRequest(owner, repository, body);
89+
const result = await getGitHubClient().createPullRequest(owner, repository, body);
11090
console.log('result', result);
11191
}
11292
} catch (e) {
@@ -120,18 +100,18 @@ async function createPullRequest(): Promise<void> {
120100

121101
async function checkoutPullRequests(): Promise<void> {
122102
try {
123-
const [owner, repository] = await getGitHubOwnerAndRepository();
103+
const [owner, repository] = await git.getGitHubOwnerAndRepository(cwd);
124104
const parameters: ListPullRequestsParameters = {
125105
state: 'open'
126106
};
127-
const response = await github.listPullRequests(owner, repository, parameters);
107+
const response = await getGitHubClient().listPullRequests(owner, repository, parameters);
128108
vscode.window.showQuickPick(response.body.map(pullRequest => ({
129109
label: pullRequest.title,
130110
description: `#${pullRequest.number}`,
131111
pullRequest
132112
}))).then(selected => {
133113
if (selected) {
134-
checkout(selected.pullRequest.head.ref);
114+
git.checkout(cwd, selected.pullRequest.head.ref);
135115
}
136116
});
137117
} catch (e) {

src/git.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as execa from 'execa';
2+
3+
export async function getGitHubOwnerAndRepository(cwd: string): Promise<string[]> {
4+
return execa('git', ['config', '--get-regexp', 'remote\\.origin\\.url'], {cwd})
5+
.then(result => {
6+
const match = result.stdout.match(/^remote.origin.url git@github.com:(.*?)\/(.*?)(?:.git)?$/);
7+
if (!match) {
8+
throw new Error('Not a github project?');
9+
}
10+
return [match[1], match[2]];
11+
});
12+
}
13+
14+
export async function getCurrentBranch(cwd: string): Promise<string|undefined> {
15+
return execa('git', ['status', '--porcelain', '--branch'], {cwd})
16+
.then(result => {
17+
const match = result.stdout.match(/^## (.+?)(?:\.\.\..*)?/);
18+
return match ? match[1] : undefined;
19+
});
20+
}
21+
22+
export async function getCommitMessage(cwd: string): Promise<string> {
23+
return execa('git', ['log', '--oneline', '-1'], {cwd})
24+
.then(result => {
25+
const match = result.stdout.match(/^(?:.+?) (.*)/);
26+
return match ? match[1] : result.stdout;
27+
});
28+
}
29+
30+
export async function checkout(cwd: string, branch: string): Promise<void> {
31+
return execa('git', ['checkout', branch], {cwd})
32+
.then(() => undefined);
33+
}

vsc-extension-quickstart.md

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)