diff --git a/src/git/gitService.ts b/src/git/gitService.ts index bcce65d..02758fc 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -59,7 +59,7 @@ import { RepositoryChange } from './git'; import { GitUri } from './gitUri'; -import { RemoteProviderFactory, RemoteProviderMap } from './remotes/factory'; +import { RemoteProviderFactory, RemoteProviders } from './remotes/factory'; export * from './gitUri'; export * from './models/models'; @@ -1490,20 +1490,20 @@ export class GitService implements Disposable { return (await remotes).filter(r => r.provider !== undefined); } - async getRemotesCore(repoPath: string | undefined, providerMap?: RemoteProviderMap): Promise { + async getRemotesCore(repoPath: string | undefined, providers?: RemoteProviders): Promise { if (repoPath === undefined) return []; Logger.log(`getRemotesCore('${repoPath}')`); - providerMap = - providerMap || - RemoteProviderFactory.createMap( + providers = + providers || + RemoteProviderFactory.loadProviders( configuration.get(configuration.name('remotes').value, null) ); try { const data = await Git.remote(repoPath); - return GitRemoteParser.parse(data, repoPath, RemoteProviderFactory.factory(providerMap)); + return GitRemoteParser.parse(data, repoPath, RemoteProviderFactory.factory(providers)); } catch (ex) { Logger.error(ex, 'GitService.getRemotesCore'); diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index c35f9c3..6769ef7 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -15,7 +15,7 @@ import { Container } from '../../container'; import { Functions } from '../../system'; import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git'; import { GitUri } from '../gitUri'; -import { RemoteProviderFactory, RemoteProviderMap } from '../remotes/factory'; +import { RemoteProviderFactory, RemoteProviders } from '../remotes/factory'; export enum RepositoryChange { Config = 'config', @@ -83,7 +83,7 @@ export class Repository implements Disposable { private _fsWatchCounter = 0; private _fsWatcherDisposable: Disposable | undefined; private _pendingChanges: { repo?: RepositoryChangeEvent; fs?: RepositoryFileSystemChangeEvent } = {}; - private _providerMap: RemoteProviderMap | undefined; + private _providers: RemoteProviders | undefined; private _remotes: Promise | undefined; private _suspended: boolean; @@ -154,7 +154,7 @@ export class Repository implements Disposable { const section = configuration.name('remotes').value; if (initializing || configuration.changed(e, section, this.folder.uri)) { - this._providerMap = RemoteProviderFactory.createMap( + this._providers = RemoteProviderFactory.loadProviders( configuration.get(section, this.folder.uri) ); @@ -243,15 +243,15 @@ export class Repository implements Disposable { getRemotes(): Promise { if (this._remotes === undefined) { - if (this._providerMap === undefined) { + if (this._providers === undefined) { const remotesCfg = configuration.get( configuration.name('remotes').value, 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; diff --git a/src/git/remotes/factory.ts b/src/git/remotes/factory.ts index 883ba73..3f595f6 100644 --- a/src/git/remotes/factory.ts +++ b/src/git/remotes/factory.ts @@ -10,33 +10,36 @@ import { GitLabRemote } from './gitlab'; import { RemoteProvider } from './provider'; export { RemoteProvider }; +export type RemoteProviders = [string | RegExp, ((domain: string, path: string) => RemoteProvider)][]; -const defaultProviderMap = new Map RemoteProvider>([ +const defaultProviders: RemoteProviders = [ ['bitbucket.org', (domain: string, path: string) => new BitbucketRemote(domain, path)], ['github.com', (domain: string, path: string) => new GitHubRemote(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 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 { - 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 { - 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) { 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) { for (const rc of cfg) { const provider = this.getCustomProvider(rc); 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) {