This commit is contained in:
Joao Moreno
2018-11-01 15:00:36 +01:00
parent b31b07741b
commit 349e31fee9
4 changed files with 63 additions and 33 deletions

View File

@@ -6,6 +6,8 @@
import { Model } from '../model';
import { GitExtension, Repository, API } from './git';
import { ApiRepository, ApiImpl } from './api1';
import { Event, EventEmitter } from 'vscode';
import { latchEvent } from '../util';
export function deprecated(_target: any, key: string, descriptor: any): void {
if (typeof descriptor.value !== 'function') {
@@ -19,50 +21,56 @@ export function deprecated(_target: any, key: string, descriptor: any): void {
};
}
class NoModelGitExtension implements GitExtension {
export class GitExtensionImpl implements GitExtension {
enabled: boolean = false;
private _onDidChangeEnablement = new EventEmitter<boolean>();
readonly onDidChangeEnablement: Event<boolean> = latchEvent(this._onDidChangeEnablement.event);
private _model: Model | undefined = undefined;
set model(model: Model | undefined) {
this._model = model;
this.enabled = !!model;
this._onDidChangeEnablement.fire(this.enabled);
}
constructor(model?: Model) {
if (model) {
this.enabled = true;
this._model = model;
}
}
@deprecated
async getGitPath(): Promise<string> {
throw new Error('Git model not found');
}
if (!this._model) {
throw new Error('Git model not found');
}
@deprecated
async getRepositories(): Promise<Repository[]> {
throw new Error('Git model not found');
}
getAPI(): API {
throw new Error('Git model not found');
}
}
class GitExtensionImpl implements GitExtension {
constructor(private _model: Model) { }
@deprecated
async getGitPath(): Promise<string> {
return this._model.git.path;
}
@deprecated
async getRepositories(): Promise<Repository[]> {
if (!this._model) {
throw new Error('Git model not found');
}
return this._model.repositories.map(repository => new ApiRepository(repository));
}
getAPI(version: number): API {
if (!this._model) {
throw new Error('Git model not found');
}
if (version !== 1) {
throw new Error(`No API version ${version} found.`);
}
return new ApiImpl(this._model);
}
}
export function createGitExtension(model?: Model): GitExtension {
if (!model) {
return new NoModelGitExtension();
}
return new GitExtensionImpl(model);
}
}

View File

@@ -164,9 +164,16 @@ export interface API {
export interface GitExtension {
readonly enabled: boolean;
readonly onDidChangeEnablement: Event<boolean>;
/**
* Returns a specific API version.
*
* Throws error if git extension is disabled. You can listed to the
* [GitExtension.onDidChangeEnablement](#GitExtension.onDidChangeEnablement) event
* to know when the extension becomes enabled/disabled.
*
* @param version Version number.
* @returns API instance
*/

View File

@@ -17,7 +17,7 @@ import { toDisposable, filterEvent, eventToPromise } from './util';
import TelemetryReporter from 'vscode-extension-telemetry';
import { GitExtension } from './api/git';
import { GitProtocolHandler } from './protocolHandler';
import { createGitExtension } from './api/extension';
import { GitExtensionImpl } from './api/extension';
import * as path from 'path';
import * as fs from 'fs';
@@ -137,12 +137,15 @@ export async function activate(context: ExtensionContext): Promise<GitExtension>
if (!enabled) {
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
await eventToPromise(onEnabled);
const result = new GitExtensionImpl();
eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannel, telemetryReporter, disposables));
return result;
}
try {
const model = await createModel(context, outputChannel, telemetryReporter, disposables);
return createGitExtension(model);
return new GitExtensionImpl(model);
} catch (err) {
if (!/Git installation not found/.test(err.message || '')) {
throw err;
@@ -151,9 +154,9 @@ export async function activate(context: ExtensionContext): Promise<GitExtension>
console.warn(err.message);
outputChannel.appendLine(err.message);
await warnAboutMissingGit();
warnAboutMissingGit();
return createGitExtension();
return new GitExtensionImpl();
}
}

View File

@@ -44,6 +44,18 @@ export function filterEvent<T>(event: Event<T>, filter: (e: T) => boolean): Even
return (listener, thisArgs = null, disposables?) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables);
}
export function latchEvent<T>(event: Event<T>): Event<T> {
let firstCall = true;
let cache: T;
return filterEvent(event, value => {
let shouldEmit = firstCall || value !== cache;
firstCall = false;
cache = value;
return shouldEmit;
});
}
export function anyEvent<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = null, disposables?) => {
const result = combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i))));