Skip to content

Commit 92b5758

Browse files
committed
Fixes #120 - Adds custom remotes support
1 parent e400f27 commit 92b5758

File tree

4 files changed

+96
-7
lines changed

4 files changed

+96
-7
lines changed

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,34 @@
447447
],
448448
"description": "Specifies the starting view (mode) of the `GitLens` custom view\n `history` - shows the commit history of the active file\n `repository` - shows a repository explorer"
449449
},
450+
"gitlens.remotes": {
451+
"type": "array",
452+
"default": null,
453+
"items": {
454+
"type": "object",
455+
"required": [
456+
"type",
457+
"domain"
458+
],
459+
"properties": {
460+
"type": {
461+
"type": "string",
462+
"enum": [
463+
"Bitbucket",
464+
"GitHub",
465+
"GitLab"
466+
],
467+
"description": "Specifies the type of the custom remote service\n `Bitbucket`, `GitHub`, or `GitLab`"
468+
},
469+
"domain": {
470+
"type": "string",
471+
"description": "Specifies the domain name of the custom remote service"
472+
}
473+
}
474+
},
475+
"uniqueItems": true,
476+
"description": "Specifies the custom remote services (code-hosting)"
477+
},
450478
"gitlens.statusBar.enabled": {
451479
"type": "boolean",
452480
"default": true,

src/configuration.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import { OutputLevel } from './logger';
77

88
export { ExtensionKey } from './constants';
99

10-
export type CodeLensCommand = 'gitlens.toggleFileBlame' |
10+
export type CodeLensCommand =
11+
'gitlens.toggleFileBlame' |
1112
'gitlens.showBlameHistory' |
1213
'gitlens.showFileHistory' |
1314
'gitlens.diffWithPrevious' |
@@ -41,7 +42,18 @@ export const LineHighlightLocations = {
4142
OverviewRuler: 'overviewRuler' as LineHighlightLocations
4243
};
4344

44-
export type StatusBarCommand = 'gitlens.toggleFileBlame' |
45+
export type CustomRemoteType =
46+
'Bitbucket' |
47+
'GitHub' |
48+
'GitLab';
49+
export const CustomRemoteType = {
50+
Bitbucket: 'Bitbucket' as CustomRemoteType,
51+
GitHub: 'GitHub' as CustomRemoteType,
52+
GitLab: 'GitLab' as CustomRemoteType
53+
};
54+
55+
export type StatusBarCommand =
56+
'gitlens.toggleFileBlame' |
4557
'gitlens.showBlameHistory' |
4658
'gitlens.showFileHistory' |
4759
'gitlens.toggleCodeLens' |
@@ -119,6 +131,11 @@ export interface ICodeLensLanguageLocation {
119131
customSymbols?: string[];
120132
}
121133

134+
export interface IRemotesConfig {
135+
type: CustomRemoteType;
136+
domain: string;
137+
}
138+
122139
export interface IThemeConfig {
123140
annotations: {
124141
file: {
@@ -307,6 +324,8 @@ export interface IConfig {
307324
// dateFormat: string | null;
308325
};
309326

327+
remotes: IRemotesConfig[];
328+
310329
statusBar: {
311330
enabled: boolean;
312331
alignment: 'left' | 'right';

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { CodeLensLocations, IConfig, LineHighlightLocations } from './configurat
1919
import { ApplicationInsightsKey, CommandContext, ExtensionKey, QualifiedExtensionId, setCommandContext, WorkspaceState } from './constants';
2020
import { CodeLensController } from './codeLensController';
2121
import { CurrentLineController, LineAnnotationType } from './currentLineController';
22+
import { RemoteProviderFactory } from './git/remotes/factory';
2223
import { GitContentProvider } from './gitContentProvider';
2324
import { GitExplorer } from './views/gitExplorer';
2425
import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider';
@@ -33,6 +34,7 @@ export async function activate(context: ExtensionContext) {
3334
Logger.configure(context);
3435
Messages.configure(context);
3536
Telemetry.configure(ApplicationInsightsKey);
37+
RemoteProviderFactory.configure(context);
3638

3739
const gitlens = extensions.getExtension(QualifiedExtensionId)!;
3840
const gitlensVersion = gitlens.packageJSON.version;

src/git/remotes/factory.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,64 @@
11
'use strict';
2-
import { RemoteProvider } from './provider';
2+
import { ExtensionContext, workspace } from 'vscode';
33
import { BitbucketService } from './bitbucket';
4+
import { CustomRemoteType, IConfig, IRemotesConfig } from '../../configuration';
5+
import { ExtensionKey } from '../../constants';
46
import { GitHubService } from './github';
57
import { GitLabService } from './gitlab';
6-
import { VisualStudioService } from './visualStudio';
78
import { Logger } from '../../logger';
9+
import { RemoteProvider } from './provider';
10+
import { VisualStudioService } from './visualStudio';
11+
import { Objects } from '../../system';
812

913
export { RemoteProvider };
1014

11-
const providerMap = new Map<string, (domain: string, path: string) => RemoteProvider>([
15+
const UrlRegex = /^(?:git:\/\/(.*?)\/|https:\/\/(.*?)\/|http:\/\/(.*?)\/|git@(.*):|ssh:\/\/(?:.*@)?(.*?)(?::.*?)?\/)(.*)$/;
16+
17+
function getProviderKey(type: CustomRemoteType) {
18+
switch (type) {
19+
case CustomRemoteType.Bitbucket: return 'bitbucket.org';
20+
case CustomRemoteType.GitHub: return 'github.com';
21+
case CustomRemoteType.GitLab: return 'gitlab.com';
22+
}
23+
return undefined;
24+
}
25+
26+
const defaultProviderMap = new Map<string, (domain: string, path: string) => RemoteProvider>([
1227
['bitbucket.org', (domain: string, path: string) => new BitbucketService(domain, path)],
1328
['github.com', (domain: string, path: string) => new GitHubService(domain, path)],
1429
['gitlab.com', (domain: string, path: string) => new GitLabService(domain, path)],
1530
['visualstudio.com', (domain: string, path: string) => new VisualStudioService(domain, path)]
1631
]);
1732

18-
const UrlRegex = /^(?:git:\/\/(.*?)\/|https:\/\/(.*?)\/|http:\/\/(.*?)\/|git@(.*):|ssh:\/\/(?:.*@)?(.*?)(?::.*?)?\/)(.*)$/;
33+
let providerMap: Map<string, (domain: string, path: string) => RemoteProvider>;
34+
let remotesCfg: IRemotesConfig[];
35+
36+
function onConfigurationChanged() {
37+
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey);
38+
if (cfg === undefined) return;
39+
40+
if (!Objects.areEquivalent(cfg.remotes, remotesCfg)) {
41+
providerMap = new Map(defaultProviderMap);
42+
43+
remotesCfg = cfg.remotes;
44+
if (remotesCfg != null && remotesCfg.length > 0) {
45+
for (const svc of remotesCfg) {
46+
const key = getProviderKey(svc.type);
47+
if (key === undefined) continue;
48+
49+
providerMap.set(svc.domain.toLowerCase(), providerMap.get(key)!);
50+
}
51+
}
52+
}
53+
}
1954

2055
export class RemoteProviderFactory {
2156

57+
static configure(context: ExtensionContext) {
58+
context.subscriptions.push(workspace.onDidChangeConfiguration(onConfigurationChanged));
59+
onConfigurationChanged();
60+
}
61+
2262
static getRemoteProvider(url: string): RemoteProvider | undefined {
2363
try {
2464
const match = UrlRegex.exec(url);
@@ -32,7 +72,7 @@ export class RemoteProviderFactory {
3272
: domain;
3373

3474
const creator = providerMap.get(key.toLowerCase());
35-
if (!creator) return undefined;
75+
if (creator === undefined) return undefined;
3676

3777
return creator(domain, path);
3878
}

0 commit comments

Comments
 (0)