|
1 | 1 | import * as execa from 'execa'; |
2 | 2 |
|
| 3 | +import { parse } from 'url'; |
| 4 | + |
| 5 | +/** |
| 6 | + * Look in .git/config for a remote origin and parses it to get username and repository. |
| 7 | + * |
| 8 | + * @param {string} cwd The directory to find the .git/config file in. |
| 9 | + * @return {Promise<string[]>} A tuple of username and repository (e.g. KnisterPeter/vscode-github) |
| 10 | + * @throws Throws if the could not be parsed as a github url |
| 11 | + */ |
3 | 12 | 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( |
7 | | - /^remote\.origin\.url (?:git@github\.com:|https:\/\/github.com\/)(.*?)\/(.*?)(?:.git)?$/); |
8 | | - if (!match) { |
9 | | - throw new Error('Not a github project?'); |
10 | | - } |
11 | | - return [match[1], match[2]]; |
12 | | - }); |
| 13 | + // as we expect this function to throw on non-Github repos we can chain |
| 14 | + // whatever calls and they will thrown on non-correct remotes |
| 15 | + const remote = (await execa('git', 'config --local --get remote.origin.url'.split(' '), {cwd})).stdout.trim(); |
| 16 | + if (!remote.length) { |
| 17 | + throw new Error('Git remote is empty!'); |
| 18 | + } |
| 19 | + |
| 20 | + // git protocol remotes, may be git@github:username/repo.git |
| 21 | + // or git://github/user/repo.git, GITHUB domain name is not case-sensetive |
| 22 | + if (remote.startsWith('git')) { |
| 23 | + return remote.match(/^git(?:@|\:\/\/)github.com[\/:](.*?)\/(.*?)(?:.git)?$/i)!.slice(1, 3); |
| 24 | + } |
| 25 | + |
| 26 | + // it must be http or https based remote |
| 27 | + const { hostname, pathname } = parse(remote); |
| 28 | + // github.com domain name is not case-sensetive |
| 29 | + if (!pathname || !hostname || !/^github\.com$/i.test(hostname)) { |
| 30 | + throw new Error('Not a Github remote!'); |
| 31 | + } |
| 32 | + return pathname.match(/\/(.*?)\/(.*?)(?:.git)?$/)!.slice(1, 3); |
13 | 33 | } |
14 | 34 |
|
15 | 35 | export async function getCurrentBranch(cwd: string): Promise<string|undefined> { |
|
0 commit comments