git: use simpler versioning scheme

This commit is contained in:
Joao Moreno
2018-08-22 15:09:11 +02:00
parent f9982d29d4
commit 78d61d55f4
7 changed files with 23 additions and 114 deletions

View File

@@ -1,55 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { API } from './git';
import * as semver from 'semver';
interface ApiCtor {
new(model: Model): API;
}
const versions: string[] = [];
const apis = new Map<string, ApiCtor>();
export function getAPI(model: Model, range: string): 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);
};
}
export function deprecated(target: any, key: string, descriptor: any): void {
if (typeof descriptor.value !== 'function') {
throw new Error('not supported');
}
const fn = descriptor.value;
descriptor.value = function () {
console.warn(`Git extension API method '${key}' is deprecated.`);
return fn.apply(this, arguments);
};
}

View File

@@ -7,11 +7,9 @@
import { Model } from '../model';
import { Repository as BaseRepository } from '../repository';
import { InputBox, ExecResult, SpawnOptions, Git, API, Repository } from './git';
import { Api } from './api';
import { InputBox, Git, API, Repository } from './git';
import { Event, SourceControlInputBox, Uri } from 'vscode';
import { mapEvent } from '../util';
import * as cp from 'child_process';
class ApiInputBox implements InputBox {
set value(value: string) { this._inputBox.value = value; }
@@ -35,17 +33,8 @@ export class ApiGit implements Git {
get path(): string { return this._model.git.path; }
constructor(private _model: Model) { }
exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>> {
return this._model.git.exec2(args, options);
}
spawn(args: string[], options: SpawnOptions): cp.ChildProcess {
return this._model.git.spawn(args, options);
}
}
@Api('1.0.0')
export class ApiImpl implements API {
readonly git = new ApiGit(this._model);

View File

@@ -7,8 +7,19 @@
import { Model } from '../model';
import { GitExtension, Repository, API } from './git';
import { getAPI, deprecated } from './api';
import { ApiRepository } from './api1';
import { ApiRepository, ApiImpl } from './api1';
export function deprecated(target: any, key: string, descriptor: any): void {
if (typeof descriptor.value !== 'function') {
throw new Error('not supported');
}
const fn = descriptor.value;
descriptor.value = function () {
console.warn(`Git extension API method '${key}' is deprecated.`);
return fn.apply(this, arguments);
};
}
class NoModelGitExtension implements GitExtension {
@@ -41,8 +52,12 @@ class GitExtensionImpl implements GitExtension {
return this._model.repositories.map(repository => new ApiRepository(repository));
}
getAPI(range: string): API {
return getAPI(this._model, range);
getAPI(version: number): API {
if (version !== 1) {
throw new Error(`No API version ${version} found.`);
}
return new ApiImpl(this._model);
}
}

View File

@@ -6,24 +6,8 @@
import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode';
import * as cp from 'child_process';
export interface ExecResult<T extends string | Buffer> {
readonly exitCode: number;
readonly stdout: T;
readonly stderr: string;
}
export interface SpawnOptions extends cp.SpawnOptions {
readonly cwd: string;
readonly input?: string;
readonly encoding?: string;
readonly log?: boolean;
readonly cancellationToken?: CancellationToken;
}
export interface Git {
readonly path: string;
exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>>;
spawn(args: string[], options: SpawnOptions): cp.ChildProcess;
}
export interface API {
@@ -42,30 +26,13 @@ export interface Repository {
readonly inputBox: InputBox;
}
declare module GitExtension { }
export interface GitExtension {
/**
* Returns the latest available API compatible with the
* provided version range.
* Returns a specific API version.
*
* @param range Semver version range for API compatibility.
* @param version Version number.
* @returns API instance
*/
getAPI(range: string): API;
/**
* Returns the collection of active repositories.
*
* @deprecated Use `API.repositories` instead.
*/
getRepositories(): Promise<Repository[]>;
/**
* Returns the path to the current git executable.
*
* @deprecated Use `API.gitPath` instead.
*/
getGitPath(): Promise<string>;
getAPI(version: 1): API;
}