Browse Source

Closes #214 - Allows better remote detection with gitlab & bitbucket

main
Eric Amodio 6 years ago
parent
commit
5e4b049c2f
3 changed files with 38 additions and 32 deletions
  1. +6
    -6
      src/git/gitService.ts
  2. +6
    -6
      src/git/models/repository.ts
  3. +26
    -20
      src/git/remotes/factory.ts

+ 6
- 6
src/git/gitService.ts View File

@ -59,7 +59,7 @@ import {
RepositoryChange RepositoryChange
} from './git'; } from './git';
import { GitUri } from './gitUri'; import { GitUri } from './gitUri';
import { RemoteProviderFactory, RemoteProviderMap } from './remotes/factory';
import { RemoteProviderFactory, RemoteProviders } from './remotes/factory';
export * from './gitUri'; export * from './gitUri';
export * from './models/models'; export * from './models/models';
@ -1490,20 +1490,20 @@ export class GitService implements Disposable {
return (await remotes).filter(r => r.provider !== undefined); return (await remotes).filter(r => r.provider !== undefined);
} }
async getRemotesCore(repoPath: string | undefined, providerMap?: RemoteProviderMap): Promise<GitRemote[]> {
async getRemotesCore(repoPath: string | undefined, providers?: RemoteProviders): Promise<GitRemote[]> {
if (repoPath === undefined) return []; if (repoPath === undefined) return [];
Logger.log(`getRemotesCore('${repoPath}')`); Logger.log(`getRemotesCore('${repoPath}')`);
providerMap =
providerMap ||
RemoteProviderFactory.createMap(
providers =
providers ||
RemoteProviderFactory.loadProviders(
configuration.get<RemotesConfig[] | null | undefined>(configuration.name('remotes').value, null) configuration.get<RemotesConfig[] | null | undefined>(configuration.name('remotes').value, null)
); );
try { try {
const data = await Git.remote(repoPath); const data = await Git.remote(repoPath);
return GitRemoteParser.parse(data, repoPath, RemoteProviderFactory.factory(providerMap));
return GitRemoteParser.parse(data, repoPath, RemoteProviderFactory.factory(providers));
} }
catch (ex) { catch (ex) {
Logger.error(ex, 'GitService.getRemotesCore'); Logger.error(ex, 'GitService.getRemotesCore');

+ 6
- 6
src/git/models/repository.ts View File

@ -15,7 +15,7 @@ import { Container } from '../../container';
import { Functions } from '../../system'; import { Functions } from '../../system';
import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git'; import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git';
import { GitUri } from '../gitUri'; import { GitUri } from '../gitUri';
import { RemoteProviderFactory, RemoteProviderMap } from '../remotes/factory';
import { RemoteProviderFactory, RemoteProviders } from '../remotes/factory';
export enum RepositoryChange { export enum RepositoryChange {
Config = 'config', Config = 'config',
@ -83,7 +83,7 @@ export class Repository implements Disposable {
private _fsWatchCounter = 0; private _fsWatchCounter = 0;
private _fsWatcherDisposable: Disposable | undefined; private _fsWatcherDisposable: Disposable | undefined;
private _pendingChanges: { repo?: RepositoryChangeEvent; fs?: RepositoryFileSystemChangeEvent } = {}; private _pendingChanges: { repo?: RepositoryChangeEvent; fs?: RepositoryFileSystemChangeEvent } = {};
private _providerMap: RemoteProviderMap | undefined;
private _providers: RemoteProviders | undefined;
private _remotes: Promise<GitRemote[]> | undefined; private _remotes: Promise<GitRemote[]> | undefined;
private _suspended: boolean; private _suspended: boolean;
@ -154,7 +154,7 @@ export class Repository implements Disposable {
const section = configuration.name('remotes').value; const section = configuration.name('remotes').value;
if (initializing || configuration.changed(e, section, this.folder.uri)) { if (initializing || configuration.changed(e, section, this.folder.uri)) {
this._providerMap = RemoteProviderFactory.createMap(
this._providers = RemoteProviderFactory.loadProviders(
configuration.get<RemotesConfig[] | null | undefined>(section, this.folder.uri) configuration.get<RemotesConfig[] | null | undefined>(section, this.folder.uri)
); );
@ -243,15 +243,15 @@ export class Repository implements Disposable {
getRemotes(): Promise<GitRemote[]> { getRemotes(): Promise<GitRemote[]> {
if (this._remotes === undefined) { if (this._remotes === undefined) {
if (this._providerMap === undefined) {
if (this._providers === undefined) {
const remotesCfg = configuration.get<RemotesConfig[] | null | undefined>( const remotesCfg = configuration.get<RemotesConfig[] | null | undefined>(
configuration.name('remotes').value, configuration.name('remotes').value,
this.folder.uri this.folder.uri
); );
this._providerMap = RemoteProviderFactory.createMap(remotesCfg);
this._providers = RemoteProviderFactory.loadProviders(remotesCfg);
} }
this._remotes = Container.git.getRemotesCore(this.path, this._providerMap);
this._remotes = Container.git.getRemotesCore(this.path, this._providers);
} }
return this._remotes; return this._remotes;

+ 26
- 20
src/git/remotes/factory.ts View File

@ -10,33 +10,36 @@ import { GitLabRemote } from './gitlab';
import { RemoteProvider } from './provider'; import { RemoteProvider } from './provider';
export { RemoteProvider }; export { RemoteProvider };
export type RemoteProviders = [string | RegExp, ((domain: string, path: string) => RemoteProvider)][];
const defaultProviderMapspan> = new Map<string, (domain: string, path: string) => RemoteProvider>="p">([
const defaultProviders: RemoteProviders = [
['bitbucket.org', (domain: string, path: string) => new BitbucketRemote(domain, path)], ['bitbucket.org', (domain: string, path: string) => new BitbucketRemote(domain, path)],
['github.com', (domain: string, path: string) => new GitHubRemote(domain, path)], ['github.com', (domain: string, path: string) => new GitHubRemote(domain, path)],
['gitlab.com', (domain: string, path: string) => new GitLabRemote(domain, path)], ['gitlab.com', (domain: string, path: string) => new GitLabRemote(domain, path)],
['visualstudio.com', (domain: string, path: string) => new AzureDevOpsRemote(domain, path)],
['dev.azure.com', (domain: string, path: string) => new AzureDevOpsRemote(domain, path)]
]);
export type RemoteProviderMap = Map<string, (domain: string, path: string) => RemoteProvider>;
['dev.azure.com', (domain: string, path: string) => new AzureDevOpsRemote(domain, path)],
[/\bbitbucket\b/i, (domain: string, path: string) => new BitbucketServerRemote(domain, path)],
[/\bgitlab\b/i, (domain: string, path: string) => new GitLabRemote(domain, path)],
[/\bvisualstudio.com$/i, (domain: string, path: string) => new AzureDevOpsRemote(domain, path)]
];
export class RemoteProviderFactory { export class RemoteProviderFactory {
static factory(providerMap: RemoteProviderMap): (domain: string, path: string) => RemoteProvider | undefined {
return (domain: string, path: string) => this.create(providerMap, domain, path);
static factory(providers: RemoteProviders): (domain: string, path: string) => RemoteProvider | undefined {
return (domain: string, path: string) => this.create(providers, domain, path);
} }
static create(providerMap: RemoteProviderMap, domain: string, path: string): RemoteProvider | undefined {
static create(providers: RemoteProviders, domain: string, path: string): RemoteProvider | undefined {
try { try {
let key = domain.toLowerCase();
if (key.endsWith('visualstudio.com')) {
key = 'visualstudio.com';
const key = domain.toLowerCase();
for (const [matcher, creator] of providers) {
if (
(typeof matcher === 'string' && matcher === key) ||
(typeof matcher !== 'string' && matcher.test(key))
) {
return creator(domain, path);
}
} }
const creator = providerMap.get(key);
if (creator === undefined) return undefined;
return creator(domain, path);
return undefined;
} }
catch (ex) { catch (ex) {
Logger.error(ex, 'RemoteProviderFactory'); Logger.error(ex, 'RemoteProviderFactory');
@ -44,17 +47,20 @@ export class RemoteProviderFactory {
} }
} }
static createMap(cfg: RemotesConfig[] | null | undefined): RemoteProviderMap {
const providerMap = new Map(defaultProviderMap);
static loadProviders(cfg: RemotesConfig[] | null | undefined): RemoteProviders {
const providers: RemoteProviders = [];
if (cfg != null && cfg.length > 0) { if (cfg != null && cfg.length > 0) {
for (const rc of cfg) { for (const rc of cfg) {
const provider = this.getCustomProvider(rc); const provider = this.getCustomProvider(rc);
if (provider === undefined) continue; if (provider === undefined) continue;
providerMap.set(rc.domain.toLowerCase(), provider);
providers.push([rc.domain.toLowerCase(), provider]);
} }
} }
return providerMap;
providers.push(...defaultProviders);
return providers;
} }
private static getCustomProvider(cfg: RemotesConfig) { private static getCustomProvider(cfg: RemotesConfig) {

Loading…
Cancel
Save