use events for git output

This commit is contained in:
Joao Moreno 2016-04-21 15:29:43 +02:00
parent bd90379f39
commit b1a5f7fb31
6 changed files with 48 additions and 57 deletions

View file

@ -2,18 +2,19 @@
* 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 winjs = require('vs/base/common/winjs.base');
import {IGitService, ServiceEvents} from 'vs/workbench/parts/git/common/git';
import ext = require('vs/workbench/common/contributions');
import {IOutputService} from 'vs/workbench/parts/output/common/output';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IGitService, ServiceEvents } from 'vs/workbench/parts/git/common/git';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IOutputService } from 'vs/workbench/parts/output/common/output';
export class GitOutput implements ext.IWorkbenchContribution {
export class GitOutput implements IWorkbenchContribution {
static ID = 'Monaco.IDE.UI.Viewlets.GitViewlet.Workbench.GitOutput';
private promise: winjs.Promise;
private outputListener: IDisposable;
private gitService: IGitService;
private outputService: IOutputService;
@ -21,39 +22,21 @@ export class GitOutput implements ext.IWorkbenchContribution {
this.gitService = gitService;
this.outputService = outputService;
// we must make sure onOutput is the first thing the git service is asked,
// so before any service operation, we call onOutput first
gitService.addListener2(ServiceEvents.OPERATION_START, () => this.setup());
const listener = gitService.addListener2(ServiceEvents.OPERATION_START, () => {
this.outputListener = this.gitService.onOutput(output => this.onOutput(output));
listener.dispose();
});
}
public getId(): string {
getId(): string {
return GitOutput.ID;
}
private setup(): void {
if (this.promise) {
return;
}
this.promise = this.gitService.onOutput().then(() => {
this.promise = null;
}, (e: any) => {
if (e && e.name === 'Canceled') {
this.promise = null;
} else {
console.error(e);
}
}, (o: string) => this.onOutput(o));
}
private onOutput(output: string): void {
this.outputService.getChannel('Git').append(output);
}
public dispose(): void {
if (this.promise) {
this.promise.cancel();
this.promise = null;
}
dispose(): void {
this.outputListener = dispose(this.outputListener);
}
}

View file

@ -36,6 +36,7 @@ import URI from 'vs/base/common/uri';
import * as semver from 'semver';
import { shell } from 'electron';
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
import Event from 'vs/base/common/event';
function toReadablePath(path: string): string {
if (!platform.isWindows) {
@ -397,6 +398,8 @@ export class GitService extends ee.EventEmitter
private refreshDelayer: async.ThrottledDelayer<void>;
private autoFetcher: AutoFetcher;
get onOutput(): Event<string> { return this.raw.onOutput; }
constructor(
raw: git.IRawGitService,
@IInstantiationService instantiationService: IInstantiationService,
@ -771,10 +774,6 @@ export class GitService extends ee.EventEmitter
return this.operations;
}
public onOutput(): winjs.Promise {
return this.raw.onOutput();
}
public getAutoFetcher(): git.IAutoFetcher {
return this.autoFetcher;
}

View file

@ -8,6 +8,7 @@ import WinJS = require('vs/base/common/winjs.base');
import WorkbenchEditorCommon = require('vs/workbench/common/editor');
import EventEmitter = require('vs/base/common/eventEmitter');
import Lifecycle = require('vs/base/common/lifecycle');
import Event from 'vs/base/common/event';
import {createDecorator, ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation';
// Model raw interfaces
@ -257,6 +258,7 @@ export interface IPushOptions {
}
export interface IRawGitService {
onOutput: Event<string>;
getVersion(): WinJS.TPromise<string>;
serviceState(): WinJS.TPromise<RawServiceState>;
status(): WinJS.TPromise<IRawStatus>;
@ -276,7 +278,6 @@ export interface IRawGitService {
commit(message:string, amend?: boolean, stage?: boolean): WinJS.TPromise<IRawStatus>;
detectMimetypes(path: string, treeish?: string): WinJS.TPromise<string[]>;
show(path: string, treeish?: string): WinJS.TPromise<string>;
onOutput(): WinJS.Promise; // TODO: make this an event
}
export var GIT_SERVICE_ID = 'gitService';
@ -285,6 +286,7 @@ export var IGitService = createDecorator<IGitService>(GIT_SERVICE_ID);
export interface IGitService extends EventEmitter.IEventEmitter {
serviceId: ServiceIdentifier<any>;
onOutput: Event<string>;
status(): WinJS.TPromise<IModel>;
init(): WinJS.TPromise<IModel>;
add(files?: IFileStatus[]): WinJS.TPromise<IModel>;
@ -311,8 +313,6 @@ export interface IGitService extends EventEmitter.IEventEmitter {
isIdle(): boolean;
getRunningOperations(): IGitOperation[];
getAutoFetcher(): IAutoFetcher;
onOutput(): WinJS.Promise;
}
export interface IAskpassService {

View file

@ -6,7 +6,8 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc';
import Event from 'vs/base/common/event';
import { IRawGitService, RawServiceState, IRawStatus, IPushOptions, IAskpassService, ICredentials } from './git';
export interface IGitChannel extends IChannel {
@ -59,7 +60,7 @@ export class GitChannel implements IGitChannel {
case 'commit': return this.service.then(s => s.commit(args[0], args[1], args[2]));
case 'detectMimetypes': return this.service.then(s => s.detectMimetypes(args[0], args[1]));
case 'show': return this.service.then(s => s.show(args[0], args[1]));
case 'onOutput': return this.service.then(s => s.onOutput());
case 'onOutput': return this.service.then(s => eventToCall(s.onOutput));
}
}
}
@ -78,6 +79,9 @@ export class GitChannelClient implements IRawGitService {
constructor(private channel: IGitChannel) { }
private _onOutput = eventFromCall(this.channel, 'onOutput');
get onOutput(): Event<string> { return this._onOutput; }
getVersion(): TPromise<string> {
return this.channel.call('getVersion');
}
@ -153,10 +157,6 @@ export class GitChannelClient implements IRawGitService {
show(path: string, treeish?: string): TPromise<string> {
return this.channel.call('show', [path, treeish]);
}
onOutput(): TPromise<void> {
return this.channel.call('onOutput');
}
}
export interface IAskpassChannel extends IChannel {

View file

@ -5,9 +5,15 @@
'use strict';
import git = require('vs/workbench/parts/git/common/git');
import { Promise, TPromise } from 'vs/base/common/winjs.base';
import { TPromise } from 'vs/base/common/winjs.base';
import Event, { Emitter } from 'vs/base/common/event';
// TODO: remove
export class NoOpGitService implements git.IRawGitService {
private _onOutput = new Emitter<string>();
get onOutput(): Event<string> { return this._onOutput.event; }
private static STATUS:git.IRawStatus = {
repositoryRoot: null,
state: git.ServiceState.NotAWorkspace,
@ -93,8 +99,4 @@ export class NoOpGitService implements git.IRawGitService {
public show(path: string, treeish?: string): TPromise<string> {
return TPromise.as(null);
}
public onOutput(): Promise {
return TPromise.as(() => null);
}
}

View file

@ -10,14 +10,29 @@ import mime = require('vs/base/node/mime');
import pfs = require('vs/base/node/pfs');
import { Repository, GitError } from 'vs/workbench/parts/git/node/git.lib';
import { IRawGitService, RawServiceState, IRawStatus, IHead, GitErrorCodes, IPushOptions } from 'vs/workbench/parts/git/common/git';
import Event, { Emitter } from 'vs/base/common/event';
export class RawGitService implements IRawGitService {
private repo: Repository;
private _repositoryRoot: TPromise<string>;
private _onOutput: Emitter<string>;
get onOutput(): Event<string> { return this._onOutput.event; }
constructor(repo: Repository) {
this.repo = repo;
let listener: () => void;
this._onOutput = new Emitter<string>({
onFirstListenerAdd: () => {
listener = this.repo.onOutput(output => this._onOutput.fire(output));
},
onLastListenerRemove: () => {
listener();
listener = null;
}
});
}
getVersion(): TPromise<string> {
@ -169,12 +184,4 @@ export class RawGitService implements IRawGitService {
return TPromise.wrapError<string>(e);
});
}
onOutput(): Promise {
let cancel: () => void;
return new Promise((c, e, p) => {
cancel = this.repo.onOutput(p);
}, () => cancel());
}
}