Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const debugInstall = require('./out/coreclr-debug/install.js');
const fs_extra = require('fs-extra-promise');
const omnisharp = require('./out/omnisharp/omnisharp');
const download = require('./out/omnisharp/download');
const logger = require('./out/omnisharp/logger');
const platform = require('./out/platform');
const child_process = require('child_process');

Expand All @@ -35,8 +36,11 @@ gulp.task('clean', ['omnisharp:clean', 'debugger:clean', 'package:clean'], () =

/// Omnisharp Tasks
function installOmnisharp(omnisharps) {
const logger = (message) => { console.log(message); };
const promises = omnisharps.map((omni) => download.go(omni.flavor, omni.platform, logger));
const promises = omnisharps.map((omni, index) => {
const log = new logger.Logger(message => process.stdout.write(message), index.toString());

return download.go(omni.flavor, omni.platform, log);
});

return Promise.all(promises);
}
Expand Down
27 changes: 14 additions & 13 deletions src/omnisharp/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {parse} from 'url';
import {Flavor, getInstallDirectory} from './omnisharp';
import {Platform} from '../platform';
import {getProxyAgent} from '../proxy';
import {Logger} from './logger';

const decompress = require('decompress');

Expand Down Expand Up @@ -108,20 +109,17 @@ function download(urlString: string, proxy?: string, strictSSL?: boolean): Promi
});
}

export function go(flavor: Flavor, platform: Platform, log?: (message: string) => void, proxy?: string, strictSSL?: boolean) {
export function go(flavor: Flavor, platform: Platform, logger: Logger, proxy?: string, strictSSL?: boolean) {
return new Promise<boolean>((resolve, reject) => {
log = log || (_ => { });

log(`Flavor: ${flavor}, Platform: ${platform}`);

const fileName = getDownloadFileName(flavor, platform);
const installDirectory = getInstallDirectory(flavor);

log(`[INFO] Installing OmniSharp to ${installDirectory}`);
logger.appendLine(`Installing OmniSharp to ${installDirectory}`);
logger.increaseIndent();

const urlString = `${BaseDownloadUrl}/${fileName}`;

log(`[INFO] Attempting to download ${urlString}`);
logger.appendLine(`Attempting to download ${fileName}`);

return download(urlString, proxy, strictSSL)
.then(inStream => {
Expand All @@ -130,7 +128,7 @@ export function go(flavor: Flavor, platform: Platform, log?: (message: string) =
return reject(err);
}

log(`[INFO] Downloading to ${tmpPath}...`);
logger.appendLine(`Downloading to ${tmpPath}...`);

const outStream = fs.createWriteStream(null, { fd: fd });

Expand All @@ -140,16 +138,16 @@ export function go(flavor: Flavor, platform: Platform, log?: (message: string) =
outStream.once('finish', () => {
// At this point, the asset has finished downloading.

log(`[INFO] Download complete!`);
log(`[INFO] Decompressing...`);
logger.appendLine(`Download complete!`);
logger.appendLine(`Decompressing...`);

return decompress(tmpPath, installDirectory)
.then(files => {
log(`[INFO] Done! ${files.length} files unpacked.`);
logger.appendLine(`Done! ${files.length} files unpacked.\n`);
return resolve(true);
})
.catch(err => {
log(`[ERROR] ${err}`);
logger.appendLine(`[ERROR] ${err}`);
return reject(err);
});
});
Expand All @@ -159,7 +157,10 @@ export function go(flavor: Flavor, platform: Platform, log?: (message: string) =
})
.catch(err =>
{
log(`[ERROR] ${err}`);
logger.appendLine(`[ERROR] ${err}`);
});
}).then(res => {
logger.decreaseIndent();
return res;
});
}
10 changes: 7 additions & 3 deletions src/omnisharp/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export interface LaunchDetails {
export interface LaunchResult {
process: ChildProcess;
command: string;
usingMono: boolean;
}

export function launchOmniSharp(details: LaunchDetails): Promise<LaunchResult> {
Expand Down Expand Up @@ -205,7 +206,8 @@ function launchWindows(details: LaunchDetails): Promise<LaunchResult> {

return resolve({
process,
command: details.serverPath
command: details.serverPath,
usingMono: false
});
});
}
Expand All @@ -231,7 +233,8 @@ function launchNixCoreCLR(details: LaunchDetails): Promise<LaunchResult> {

return resolve({
process,
command: details.serverPath
command: details.serverPath,
usingMono: false
});
});
}
Expand All @@ -249,7 +252,8 @@ function launchNixMono(details: LaunchDetails): Promise<LaunchResult> {

return resolve({
process,
command: details.serverPath
command: details.serverPath,
usingMono: true
});
});
});
Expand Down
58 changes: 58 additions & 0 deletions src/omnisharp/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

'use strict';

export class Logger {
private _writer: (message: string) => void;
private _prefix: string;

private _indentLevel: number = 0;
private _indentSize: number = 4;
private _atLineStart: boolean = false;

constructor(writer: (message: string) => void, prefix?: string) {
this._writer = writer;
this._prefix = prefix;
}

private _appendCore(message: string): void {
if (this._atLineStart) {
if (this._indentLevel > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we really be taking a dependency on leftpad here :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly. Seems like overkill just to repeat some characters. Left pad expects a length to be passed. I suppose I could use it to generate the indent string like so:

leftPad('', this._indentLevel * 4, ' ');

Not sure it's worth it. 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could also do something like this:

const indent = " ".repeat(this._indentLevel * 4);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, this was supposed to just be a joke based on the fact that the removal of leftpad from NPM broke the internet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know. I was being ironic. Gosh! Why doesn't anyone understand me?

😄😄😄😄😄

const indent = " ".repeat(this._indentLevel * this._indentSize);
this._writer(indent);
}

if (this._prefix) {
this._writer(`[${this._prefix}] `);
}

this._atLineStart = false;
}

this._writer(message);
}

public increaseIndent(): void {
this._indentLevel += 1;
}

public decreaseIndent(): void {
if (this._indentLevel > 0) {
this._indentLevel -= 1;
}
}

public append(message?: string): void {
message = message || "";
this._appendCore(message);
}

public appendLine(message?: string): void {
message = message || "";
this._appendCore(message + '\n');
this._atLineStart = true;
}
}
36 changes: 29 additions & 7 deletions src/omnisharp/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {launchOmniSharp} from './launcher';
import * as protocol from './protocol';
import * as omnisharp from './omnisharp';
import * as download from './download';
import {Logger} from './logger';
import {DelayTracker} from './delayTracker';
import {LaunchTarget, findLaunchTargets, getDefaultFlavor} from './launcher';
import {Platform, getCurrentPlatform} from '../platform';
Expand Down Expand Up @@ -76,6 +77,7 @@ export abstract class OmnisharpServer {
private _queue: Request[] = [];
private _isProcessingQueue = false;
private _channel: vscode.OutputChannel;
protected _logger: Logger;

private _isDebugEnable: boolean = false;

Expand All @@ -84,8 +86,10 @@ export abstract class OmnisharpServer {

constructor(reporter: TelemetryReporter) {
this._extraArgs = [];
this._channel = vscode.window.createOutputChannel('OmniSharp Log');
this._reporter = reporter;

this._channel = vscode.window.createOutputChannel('OmniSharp Log');
this._logger = new Logger(message => this._channel.append(message));
}

public isRunning(): boolean {
Expand Down Expand Up @@ -276,15 +280,33 @@ export abstract class OmnisharpServer {

args = args.concat(this._extraArgs);

this._fireEvent(Events.StdOut, `[INFO] Starting OmniSharp at '${solutionPath}'...\n`);
this._logger.appendLine(`Starting OmniSharp server at ${new Date().toLocaleString()}`);
this._logger.increaseIndent();
this._logger.appendLine(`Target: ${solutionPath}`);
this._logger.decreaseIndent();
this._logger.appendLine();

this._fireEvent(Events.BeforeServerStart, solutionPath);

return launchOmniSharp({serverPath, flavor, cwd, args}).then(value => {
if (value.usingMono) {
this._logger.appendLine(`OmniSharp server started wth Mono`);
}
else {
this._logger.appendLine(`OmniSharp server started`);
}

this._logger.increaseIndent();
this._logger.appendLine(`Path: ${value.command}`);
this._logger.appendLine(`PID: ${value.process.pid}`);
this._logger.decreaseIndent();
this._logger.appendLine();

this._serverProcess = value.process;
this._delayTrackers = {};
this._fireEvent(Events.StdOut, `[INFO] Started OmniSharp from '${value.command}' with process id ${value.process.pid}...\n`);
this._setState(ServerState.Started);
this._fireEvent(Events.ServerStart, solutionPath);

return this._doConnect();
}).then(() => {
return vscode.commands.getCommands()
Expand Down Expand Up @@ -440,11 +462,11 @@ export abstract class OmnisharpServer {
const config = vscode.workspace.getConfiguration();
const proxy = config.get<string>('http.proxy');
const strictSSL = config.get('http.proxyStrictSSL', true);
const logger = (message: string) => { this._channel.appendLine(message); };
const logger = (message: string) => { this._logger.appendLine(message); };

this._fireEvent(Events.BeforeServerInstall, this);

return download.go(flavor, platform, logger, proxy, strictSSL).then(_ => {
return download.go(flavor, platform, this._logger, proxy, strictSSL).then(_ => {
return omnisharp.findServerPath(installDirectory);
});
});
Expand Down Expand Up @@ -622,7 +644,7 @@ export class StdioOmnisharpServer extends OmnisharpServer {

const onLineReceived = (line: string) => {
if (line[0] !== '{') {
this._fireEvent(Events.StdOut, `${line}\n`);
this._logger.appendLine(line);
return;
}

Expand Down Expand Up @@ -681,7 +703,7 @@ export class StdioOmnisharpServer extends OmnisharpServer {
if (packet.Event === 'log') {
// handle log events
const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body;
this._fireEvent(Events.StdOut, `[${entry.LogLevel}:${entry.Name}] ${entry.Message}\n`);
this._logger.appendLine(`[${entry.LogLevel}:${entry.Name}] ${entry.Message}`);
return;
} else {
// fwd all other events
Expand Down