提交 1f38d8e8 编写于 作者: J Joao Moreno

git: output channel

上级 3ac3b7a1
...@@ -11,6 +11,7 @@ import * as cp from 'child_process'; ...@@ -11,6 +11,7 @@ import * as cp from 'child_process';
import * as denodeify from 'denodeify'; import * as denodeify from 'denodeify';
import { IDisposable, toDisposable, dispose } from './util'; import { IDisposable, toDisposable, dispose } from './util';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { EventEmitter, Event } from 'vscode';
const readdir = denodeify(fs.readdir); const readdir = denodeify(fs.readdir);
...@@ -252,12 +253,15 @@ function encodingExists(encoding) { ...@@ -252,12 +253,15 @@ function encodingExists(encoding) {
export class Git { export class Git {
gitPath: string; private gitPath: string;
version: string; private version: string;
env: any; private env: any;
private defaultEncoding: string; private defaultEncoding: string;
private outputListeners: { (output: string): void; }[]; private outputListeners: { (output: string): void; }[];
private _onOutput = new EventEmitter<string>();
get onOutput(): Event<string> { return this._onOutput.event; }
constructor(options: IGitOptions) { constructor(options: IGitOptions) {
this.gitPath = options.gitPath; this.gitPath = options.gitPath;
this.version = options.version; this.version = options.version;
...@@ -276,11 +280,11 @@ export class Git { ...@@ -276,11 +280,11 @@ export class Git {
stream(cwd: string, args: string[], options: any = {}): cp.ChildProcess { stream(cwd: string, args: string[], options: any = {}): cp.ChildProcess {
options = _.assign({ cwd: cwd }, options || {}); options = _.assign({ cwd: cwd }, options || {});
return this.spawn(args, options); return this._spawn(args, options);
} }
private _exec(args: string[], options: any = {}): Promise<IExecutionResult> { private _exec(args: string[], options: any = {}): Promise<IExecutionResult> {
const child = this.spawn(args, options); const child = this._spawn(args, options);
if (options.input) { if (options.input) {
child.stdin.end(options.input, 'utf8'); child.stdin.end(options.input, 'utf8');
...@@ -304,6 +308,10 @@ export class Git { ...@@ -304,6 +308,10 @@ export class Git {
gitErrorCode = GitErrorCodes.CantAccessRemote; gitErrorCode = GitErrorCodes.CantAccessRemote;
} }
if (options.log !== false) {
this.log(result.stderr);
}
return Promise.reject<IExecutionResult>(new GitError({ return Promise.reject<IExecutionResult>(new GitError({
message: 'Failed to execute git', message: 'Failed to execute git',
stdout: result.stdout, stdout: result.stdout,
...@@ -318,7 +326,7 @@ export class Git { ...@@ -318,7 +326,7 @@ export class Git {
}); });
} }
spawn(args: string[], options: any = {}): cp.ChildProcess { private _spawn(args: string[], options: any = {}): cp.ChildProcess {
if (!this.gitPath) { if (!this.gitPath) {
throw new Error('git could not be found in the system.'); throw new Error('git could not be found in the system.');
} }
...@@ -340,12 +348,7 @@ export class Git { ...@@ -340,12 +348,7 @@ export class Git {
return cp.spawn(this.gitPath, args, options); return cp.spawn(this.gitPath, args, options);
} }
onOutput(listener: (output: string) => void): () => void {
this.outputListeners.push(listener);
return () => this.outputListeners.splice(this.outputListeners.indexOf(listener), 1);
}
private log(output: string): void { private log(output: string): void {
this.outputListeners.forEach(l => l(output)); this._onOutput.fire(output);
} }
} }
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
'use strict'; 'use strict';
import { scm, ExtensionContext, workspace, Uri } from 'vscode'; import { scm, ExtensionContext, workspace, Uri, window, Disposable } from 'vscode';
import * as path from 'path'; import * as path from 'path';
import { findGit, Git } from './git'; import { findGit, Git } from './git';
import { registerCommands } from './commands'; import { registerCommands } from './commands';
...@@ -27,6 +27,23 @@ class GitSCMProvider { ...@@ -27,6 +27,23 @@ class GitSCMProvider {
} }
} }
class TextDocumentContentProvider {
constructor(private git: Git, private rootPath: string) { }
provideTextDocumentContent(uri: Uri) {
const relativePath = path.relative(this.rootPath, uri.fsPath);
return this.git.exec(this.rootPath, ['show', `HEAD:${relativePath}`]).then(result => {
if (result.exitCode !== 0) {
return null;
}
return result.stdout;
});
}
}
export function activate(context: ExtensionContext): any { export function activate(context: ExtensionContext): any {
if (!workspace.rootPath) { if (!workspace.rootPath) {
return; return;
...@@ -36,28 +53,20 @@ export function activate(context: ExtensionContext): any { ...@@ -36,28 +53,20 @@ export function activate(context: ExtensionContext): any {
const pathHint = workspace.getConfiguration('git').get<string>('path'); const pathHint = workspace.getConfiguration('git').get<string>('path');
findGit(pathHint).then(info => { findGit(pathHint).then(info => {
log(`Using git ${info.version} from ${info.path}`);
const git = new Git({ gitPath: info.path, version: info.version }); const git = new Git({ gitPath: info.path, version: info.version });
const provider = new GitSCMProvider(); const disposables: Disposable[] = [];
const providerDisposable = scm.registerSCMProvider('git', provider);
const contentProvider = workspace.registerTextDocumentContentProvider('git-index', {
provideTextDocumentContent: uri => {
const relativePath = path.relative(rootPath, uri.fsPath);
return git.exec(rootPath, ['show', `HEAD:${relativePath}`]).then(result => { const outputChannel = window.createOutputChannel('git');
if (result.exitCode !== 0) { outputChannel.appendLine(`Using git ${info.version} from ${info.path}`);
return null; git.onOutput(str => outputChannel.append(str), null, disposables);
}
return result.stdout;
});
}
});
const commands = registerCommands(); disposables.push(
registerCommands(),
scm.registerSCMProvider('git', new GitSCMProvider()),
workspace.registerTextDocumentContentProvider('git-index', new TextDocumentContentProvider(git, rootPath)),
outputChannel
);
context.subscriptions.push(providerDisposable, contentProvider, commands); context.subscriptions.push(...disposables);
}); });
} }
\ No newline at end of file
...@@ -34,4 +34,4 @@ export function filterEvent<T>(event: Event<T>, filter: (e: T) => boolean): Even ...@@ -34,4 +34,4 @@ export function filterEvent<T>(event: Event<T>, filter: (e: T) => boolean): Even
export function anyEvent<T>(...events: Event<T>[]): Event<T> { export function anyEvent<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = null, disposables?) => combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i), disposables))); return (listener, thisArgs = null, disposables?) => combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i), disposables)));
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册