Skip to content

Commit bac50cc

Browse files
committed
Adds scheme to remote parsing
1 parent d2ce175 commit bac50cc

File tree

2 files changed

+108
-106
lines changed

2 files changed

+108
-106
lines changed

src/git/models/remote.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
'use strict';
2-
import { RemoteProvider } from '../remotes/factory';
3-
4-
export enum GitRemoteType {
5-
Fetch = 'fetch',
6-
Push = 'push'
7-
}
8-
9-
export class GitRemote {
10-
11-
constructor(
12-
public readonly repoPath: string,
13-
public readonly name: string,
14-
public readonly domain: string,
15-
public readonly path: string,
16-
public readonly provider: RemoteProvider | undefined,
17-
public readonly types: { type: GitRemoteType, url: string }[]
18-
) { }
1+
'use strict';
2+
import { RemoteProvider } from '../remotes/factory';
3+
4+
export enum GitRemoteType {
5+
Fetch = 'fetch',
6+
Push = 'push'
7+
}
8+
9+
export class GitRemote {
10+
11+
constructor(
12+
public readonly repoPath: string,
13+
public readonly name: string,
14+
public readonly scheme: string,
15+
public readonly domain: string,
16+
public readonly path: string,
17+
public readonly provider: RemoteProvider | undefined,
18+
public readonly types: { type: GitRemoteType, url: string }[]
19+
) { }
1920
}

src/git/parsers/remoteParser.ts

Lines changed: 89 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,90 @@
1-
'use strict';
2-
import { GitRemote } from './../git';
3-
import { GitRemoteType } from '../models/remote';
4-
import { RemoteProvider } from '../remotes/factory';
5-
6-
const remoteRegex = /^(.*)\t(.*)\s\((.*)\)$/gm;
7-
const urlRegex = /^(?:git:\/\/(.*?)\/|https?:\/\/(?:.*?@)?(.*?)\/|git@(.*):|ssh:\/\/(?:.*@)?(.*?)(?::.*?)?\/|(?:.*?@)(.*?):)(.*)$/;
8-
9-
// Test git urls
10-
/*
11-
http://host.xz/user/project.git
12-
http://host.xz/path/to/repo.git
13-
http://host.xz/path/to/repo.git/
14-
http://[email protected]/user/project.git
15-
http://username:[email protected]/user/project.git
16-
https://host.xz/user/project.git
17-
https://host.xz/path/to/repo.git
18-
https://host.xz/path/to/repo.git/
19-
https://[email protected]/user/project.git
20-
https://username:[email protected]/user/project.git
21-
22-
[email protected]:user/project.git
23-
git://host.xz/path/to/repo.git/
24-
git://host.xz/~user/path/to/repo.git/
25-
26-
ssh://host.xz/project.git
27-
ssh://host.xz/path/to/repo.git
28-
ssh://host.xz/path/to/repo.git/
29-
ssh://host.xz:port/path/to/repo.git/
30-
ssh://[email protected]/project.git
31-
ssh://[email protected]/path/to/repo.git
32-
ssh://[email protected]/path/to/repo.git/
33-
ssh://[email protected]:port/path/to/repo.git/
34-
ssh://user:[email protected]/project.git
35-
ssh://user:[email protected]/path/to/repo.git
36-
ssh://user:[email protected]/path/to/repo.git/
37-
38-
[email protected]:project.git
39-
[email protected]:path/to/repo.git
40-
[email protected]:/path/to/repo.git/
41-
user:[email protected]:project.git
42-
user:[email protected]:/path/to/repo.git
43-
user:[email protected]:/path/to/repo.git/
44-
*/
45-
46-
export class GitRemoteParser {
47-
48-
static parse(data: string, repoPath: string, providerFactory: (domain: string, path: string) => RemoteProvider | undefined): GitRemote[] {
49-
if (!data) return [];
50-
51-
const remotes: GitRemote[] = [];
52-
const groups = Object.create(null);
53-
54-
let match: RegExpExecArray | null = null;
55-
do {
56-
match = remoteRegex.exec(data);
57-
if (match == null) break;
58-
59-
const url = match[2];
60-
61-
const [domain, path] = this.parseGitUrl(url);
62-
63-
const uniqueness = `${domain}/${path}`;
64-
let remote: GitRemote | undefined = groups[uniqueness];
65-
if (remote === undefined) {
66-
remote = new GitRemote(repoPath, match[1], domain, path, providerFactory(domain, path), [{ url: url, type: match[3] as GitRemoteType }]);
67-
remotes.push(remote);
68-
groups[uniqueness] = remote;
69-
}
70-
else {
71-
remote.types.push({ url: url, type: match[3] as GitRemoteType });
72-
}
73-
} while (match != null);
74-
75-
if (!remotes.length) return [];
76-
77-
return remotes;
78-
}
79-
80-
static parseGitUrl(url: string): [string, string] {
81-
const match = urlRegex.exec(url);
82-
if (match == null) return ['', ''];
83-
84-
return [
85-
match[1] || match[2] || match[3] || match[4] || match[5],
86-
match[6].replace(/\.git\/?$/, '')
87-
];
88-
}
1+
'use strict';
2+
import { GitRemote } from './../git';
3+
import { GitRemoteType } from '../models/remote';
4+
import { RemoteProvider } from '../remotes/factory';
5+
6+
const remoteRegex = /^(.*)\t(.*)\s\((.*)\)$/gm;
7+
const urlRegex = /^(?:(git:\/\/)(.*?)\/|(https?:\/\/)(?:.*?@)?(.*?)\/|git@(.*):|(ssh:\/\/)(?:.*@)?(.*?)(?::.*?)?\/|(?:.*?@)(.*?):)(.*)$/;
8+
9+
// Test git urls
10+
/*
11+
http://host.xz/user/project.git
12+
http://host.xz/path/to/repo.git
13+
http://host.xz/path/to/repo.git/
14+
http://[email protected]/user/project.git
15+
http://username:[email protected]/user/project.git
16+
https://host.xz/user/project.git
17+
https://host.xz/path/to/repo.git
18+
https://host.xz/path/to/repo.git/
19+
https://[email protected]/user/project.git
20+
https://username:[email protected]/user/project.git
21+
22+
[email protected]:user/project.git
23+
git://host.xz/path/to/repo.git/
24+
git://host.xz/~user/path/to/repo.git/
25+
26+
ssh://host.xz/project.git
27+
ssh://host.xz/path/to/repo.git
28+
ssh://host.xz/path/to/repo.git/
29+
ssh://host.xz:port/path/to/repo.git/
30+
ssh://[email protected]/project.git
31+
ssh://[email protected]/path/to/repo.git
32+
ssh://[email protected]/path/to/repo.git/
33+
ssh://[email protected]:port/path/to/repo.git/
34+
ssh://user:[email protected]/project.git
35+
ssh://user:[email protected]/path/to/repo.git
36+
ssh://user:[email protected]/path/to/repo.git/
37+
38+
[email protected]:project.git
39+
[email protected]:path/to/repo.git
40+
[email protected]:/path/to/repo.git/
41+
user:[email protected]:project.git
42+
user:[email protected]:/path/to/repo.git
43+
user:[email protected]:/path/to/repo.git/
44+
*/
45+
46+
export class GitRemoteParser {
47+
48+
static parse(data: string, repoPath: string, providerFactory: (domain: string, path: string) => RemoteProvider | undefined): GitRemote[] {
49+
if (!data) return [];
50+
51+
const remotes: GitRemote[] = [];
52+
const groups = Object.create(null);
53+
54+
let match: RegExpExecArray | null = null;
55+
do {
56+
match = remoteRegex.exec(data);
57+
if (match == null) break;
58+
59+
const url = match[2];
60+
61+
const [scheme, domain, path] = this.parseGitUrl(url);
62+
63+
const uniqueness = `${domain}/${path}`;
64+
let remote: GitRemote | undefined = groups[uniqueness];
65+
if (remote === undefined) {
66+
remote = new GitRemote(repoPath, match[1], scheme, domain, path, providerFactory(domain, path), [{ url: url, type: match[3] as GitRemoteType }]);
67+
remotes.push(remote);
68+
groups[uniqueness] = remote;
69+
}
70+
else {
71+
remote.types.push({ url: url, type: match[3] as GitRemoteType });
72+
}
73+
} while (match != null);
74+
75+
if (!remotes.length) return [];
76+
77+
return remotes;
78+
}
79+
80+
static parseGitUrl(url: string): [string, string, string] {
81+
const match = urlRegex.exec(url);
82+
if (match == null) return ['', '', ''];
83+
84+
return [
85+
match[1] || match[3] || match[6],
86+
match[2] || match[4] || match[5] || match[7] || match[8],
87+
match[9].replace(/\.git\/?$/, '')
88+
];
89+
}
8990
}

0 commit comments

Comments
 (0)