diff --git a/extensions/git/package.json b/extensions/git/package.json index 712f071eb3a..41f2020898c 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1197,6 +1197,7 @@ "file-type": "^7.2.0", "iconv-lite": "0.4.19", "jschardet": "^1.6.0", + "semver": "^5.5.1", "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", "which": "^1.3.0" diff --git a/extensions/git/src/api/api.ts b/extensions/git/src/api/api.ts new file mode 100644 index 00000000000..6244f0580e6 --- /dev/null +++ b/extensions/git/src/api/api.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { Model } from '../model'; +import { GitExtension } from './git'; +import * as semver from 'semver'; + +interface ApiCtor { + new(model: Model): GitExtension.API; +} + +const versions: string[] = []; +const apis = new Map(); + +export function getAPI(model: Model, range: string): GitExtension.API { + if (!range) { + throw new Error(`Please provide a Git extension API version range. Available versions: [${versions.join(', ')}]`); + } + + const version = semver.maxSatisfying(versions, range); + + if (!version) { + throw new Error(`There's no available Git extension API for the given range: '${range}'. Available versions: [${versions.join(', ')}]`); + } + + const api = apis.get(version)!; + return new api(model); +} + +export function Api(version: string): Function { + return function (ctor: ApiCtor) { + if (apis.has(version)) { + throw new Error(`Git extension API version ${version} already registered.`); + } + + versions.push(version); + apis.set(version, ctor); + }; +} \ No newline at end of file diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api0.ts new file mode 100644 index 00000000000..95dd53446dc --- /dev/null +++ b/extensions/git/src/api/api0.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { Model } from '../model'; +import { GitExtension } from './git'; +import { Api } from './api'; + +@Api('0.1.0') +export class ApiImpl implements GitExtension.API { + + constructor(model: Model) { + // console.log(model); + } +} diff --git a/extensions/git/src/api.impl.ts b/extensions/git/src/api/extension.ts similarity index 79% rename from extensions/git/src/api.impl.ts rename to extensions/git/src/api/extension.ts index ff702cf52e8..0f6386693ce 100644 --- a/extensions/git/src/api.impl.ts +++ b/extensions/git/src/api/extension.ts @@ -5,10 +5,11 @@ 'use strict'; -import { Model } from './model'; -import { Repository as ModelRepository } from './repository'; +import { Model } from '../model'; +import { Repository as ModelRepository } from '../repository'; import { Uri, SourceControlInputBox } from 'vscode'; -import { GitExtension } from './api'; +import { GitExtension } from './git'; +import { getAPI } from './api'; class InputBoxImpl implements GitExtension.InputBox { set value(value: string) { this.inputBox.value = value; } @@ -31,12 +32,14 @@ export function createGitExtension(model?: Model): GitExtension { if (!model) { return { getGitPath() { throw new Error('Git model not found'); }, - getRepositories() { throw new Error('Git model not found'); } + getRepositories() { throw new Error('Git model not found'); }, + getAPI() { throw new Error('Git model not found'); } }; } return { async getGitPath() { return model.git.path; }, - async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); } + async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); }, + getAPI(range: string) { return getAPI(model, range); } }; } diff --git a/extensions/git/src/api.d.ts b/extensions/git/src/api/git.d.ts similarity index 94% rename from extensions/git/src/api.d.ts rename to extensions/git/src/api/git.d.ts index 3273c7e4c00..f8a22cb1c4b 100644 --- a/extensions/git/src/api.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -10,9 +10,6 @@ declare module GitExtension { } - // export const availableVersions: string[]; - // export function getAPI(version: string): API; - //#region Deprecated API export interface InputBox { value: string; @@ -28,4 +25,6 @@ declare module GitExtension { export interface GitExtension { getRepositories(): Promise; getGitPath(): Promise; + // export const availableVersions: string[]; + getAPI(range: string): GitExtension.API; } \ No newline at end of file diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index f4833c8985f..82e98d2cea9 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -17,9 +17,11 @@ import { GitDecorations } from './decorationProvider'; import { Askpass } from './askpass'; import { toDisposable, filterEvent, eventToPromise } from './util'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { GitExtension } from './api'; +import { GitExtension } from './api/git'; import { GitProtocolHandler } from './protocolHandler'; -import { createGitExtension } from './api.impl'; +import { createGitExtension } from './api/extension'; + +import './api/api0'; const deactivateTasks: { (): Promise; }[] = []; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index cf3f64be853..d47f44ccf7a 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -251,6 +251,10 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +semver@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"