Skip to content

Commit

Permalink
Merge pull request #2503 from akshita31/bug_generator
Browse files Browse the repository at this point in the history
Add command to create an issue from within the extension
  • Loading branch information
akshita31 authored Sep 19, 2018
2 parents d205271 + 61a2efb commit 9f37c43
Show file tree
Hide file tree
Showing 26 changed files with 731 additions and 73 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,11 @@
"command": "csharp.listRemoteProcess",
"title": "List processes on remote connection for attach",
"category": "CSharp"
},
{
"command": "csharp.reportIssue",
"title": "Start authoring a new issue on GitHub",
"category": "CSharp"
}
],
"keybindings": [
Expand Down
6 changes: 6 additions & 0 deletions src/constants/CSharpExtensionId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export const CSharpExtensionId = 'ms-vscode.csharp';
8 changes: 8 additions & 0 deletions src/constants/IGetDotnetInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface IGetDotnetInfo {
(): Promise<string>;
}
8 changes: 8 additions & 0 deletions src/constants/IGetMonoVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface IGetMonoVersion {
(environment: NodeJS.ProcessEnv): Promise<string>;
}
11 changes: 11 additions & 0 deletions src/constants/IMonoResolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Options } from "../omnisharp/options";
import { MonoInformation } from "./MonoInformation";

export interface IMonoResolver {
getGlobalMonoInfo(options: Options): Promise<MonoInformation>;
}
10 changes: 10 additions & 0 deletions src/constants/MonoInformation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface MonoInformation {
version: string;
path: string;
env: NodeJS.ProcessEnv;
}
6 changes: 5 additions & 1 deletion src/features/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import { EventStream } from '../EventStream';
import { PlatformInformation } from '../platform';
import CompositeDisposable from '../CompositeDisposable';
import OptionProvider from '../observers/OptionProvider';
import reportIssue from './reportIssue';
import { IMonoResolver } from '../constants/IMonoResolver';
import { getDotnetInfo } from '../utils/getDotnetInfo';

export default function registerCommands(server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider): CompositeDisposable {
export default function registerCommands(server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider, monoResolver: IMonoResolver): CompositeDisposable {
let disposable = new CompositeDisposable();
disposable.add(vscode.commands.registerCommand('o.restart', () => restartOmniSharp(server)));
disposable.add(vscode.commands.registerCommand('o.pickProjectAndStart', async () => pickProjectAndStart(server, optionProvider)));
Expand All @@ -46,6 +49,7 @@ export default function registerCommands(server: OmniSharpServer, platformInfo:
// Register command for adapter executable command.
disposable.add(vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)));
disposable.add(vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)));
disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, eventStream, getDotnetInfo, platformInfo.isValidPlatformForMono(), optionProvider.GetLatestOptions(), monoResolver)));

return new CompositeDisposable(disposable);
}
Expand Down
118 changes: 118 additions & 0 deletions src/features/reportIssue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { vscode } from "../vscodeAdapter";
import { Extension } from "../vscodeAdapter";
import { CSharpExtensionId } from "../constants/CSharpExtensionId";
import { EventStream } from "../EventStream";
import { OpenURL } from "../omnisharp/loggingEvents";
import { Options } from "../omnisharp/options";
import { IMonoResolver } from "../constants/IMonoResolver";
import { IGetDotnetInfo } from "../constants/IGetDotnetInfo";

const issuesUrl = "https://github.com/OmniSharp/omnisharp-vscode/issues/new";

export default async function reportIssue(vscode: vscode, eventStream: EventStream, getDotnetInfo: IGetDotnetInfo, isValidPlatformForMono: boolean, options: Options, monoResolver: IMonoResolver) {
const dotnetInfo = await getDotnetInfo();
const monoInfo = await getMonoIfPlatformValid(isValidPlatformForMono, options, monoResolver);
let extensions = getInstalledExtensions(vscode);
let csharpExtVersion = getCsharpExtensionVersion(vscode);

const body = encodeURIComponent(`## Issue Description ##
## Steps to Reproduce ##
## Expected Behavior ##
## Actual Behavior ##
## Logs ##
### OmniSharp log ###
<details>Post the output from Output-->OmniSharp log here</details>
### C# log ###
<details>Post the output from Output-->C# here</details>
## Environment information ##
**VSCode version**: ${vscode.version}
**C# Extension**: ${csharpExtVersion}
${monoInfo}
<details><summary>Dotnet Information</summary>
${dotnetInfo}</details>
<details><summary>Visual Studio Code Extensions</summary>
${generateExtensionTable(extensions)}
</details>
`);

const encodedBody = encodeURIComponent(body);
const queryStringPrefix: string = "?";
const fullUrl = `${issuesUrl}${queryStringPrefix}body=${encodedBody}`;
eventStream.post(new OpenURL(fullUrl));
}

function sortExtensions(a: Extension<any>, b: Extension<any>): number {

if (a.packageJSON.name.toLowerCase() < b.packageJSON.name.toLowerCase()) {
return -1;
}
if (a.packageJSON.name.toLowerCase() > b.packageJSON.name.toLowerCase()) {
return 1;
}
return 0;
}

function generateExtensionTable(extensions: Extension<any>[]) {
if (extensions.length <= 0) {
return "none";
}

const tableHeader = `|Extension|Author|Version|\n|---|---|---|`;
const table = extensions.map((e) => `|${e.packageJSON.name}|${e.packageJSON.publisher}|${e.packageJSON.version}|`).join("\n");

const extensionTable = `
${tableHeader}\n${table};
`;

return extensionTable;
}

async function getMonoIfPlatformValid(isValidPlatformForMono: boolean, options: Options, monoResolver: IMonoResolver): Promise<string> {
if (isValidPlatformForMono) {
let monoVersion: string;
try {
let globalMonoInfo = await monoResolver.getGlobalMonoInfo(options);
if (globalMonoInfo) {
monoVersion = `OmniSharp using global mono :${globalMonoInfo.version}`;
}
else {
monoVersion = `OmniSharp using built-in mono`;
}
}
catch (error) {
monoVersion = `There is a problem with running OmniSharp on mono: ${error}`;
}

return `<details><summary>Mono Information</summary>
${monoVersion}</details>`;
}

return "";
}



function getInstalledExtensions(vscode: vscode) {
let extensions = vscode.extensions.all
.filter(extension => extension.packageJSON.isBuiltin === false);

return extensions.sort(sortExtensions);
}

function getCsharpExtensionVersion(vscode: vscode): string {
const extension = vscode.extensions.getExtension(CSharpExtensionId);
return extension.packageJSON.version;
}
7 changes: 6 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ import DotNetTestChannelObserver from './observers/DotnetTestChannelObserver';
import DotNetTestLoggerObserver from './observers/DotnetTestLoggerObserver';
import { ShowOmniSharpConfigChangePrompt } from './observers/OptionChangeObserver';
import createOptionStream from './observables/CreateOptionStream';
import { CSharpExtensionId } from './constants/CSharpExtensionId';
import { OpenURLObserver } from './observers/OpenURLObserver';

export async function activate(context: vscode.ExtensionContext): Promise<CSharpExtensionExports> {

const extensionId = 'ms-vscode.csharp';
const extensionId = CSharpExtensionId;
const extension = vscode.extensions.getExtension<CSharpExtensionExports>(extensionId);
const extensionVersion = extension.packageJSON.version;
const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey;
Expand Down Expand Up @@ -91,6 +93,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
let projectStatusBarObserver = new ProjectStatusBarObserver(projectStatusBar);
eventStream.subscribe(projectStatusBarObserver.post);

let openURLObserver = new OpenURLObserver(vscode);
eventStream.subscribe(openURLObserver.post);

const debugMode = false;
if (debugMode) {
let omnisharpDebugModeLoggerObserver = new OmnisharpDebugModeLoggerObserver(omnisharpChannel);
Expand Down
22 changes: 22 additions & 0 deletions src/observers/OpenURLObserver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { vscode } from "../vscodeAdapter";
import { BaseEvent, OpenURL } from "../omnisharp/loggingEvents";

export class OpenURLObserver {

constructor(private vscode: vscode) {
}

public post = (event: BaseEvent) => {
switch (event.constructor.name) {
case OpenURL.name:
let url = (<OpenURL>event).url;
this.vscode.commands.executeCommand("vscode.open", this.vscode.Uri.parse(url));
break;
}
}
}
54 changes: 54 additions & 0 deletions src/omnisharp/OmniSharpMonoResolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { satisfies } from 'semver';
import * as path from 'path';
import { Options } from './options';
import { IMonoResolver } from '../constants/IMonoResolver';
import { MonoInformation } from '../constants/MonoInformation';
import { IGetMonoVersion } from '../constants/IGetMonoVersion';

export class OmniSharpMonoResolver implements IMonoResolver {
private minimumMonoVersion = "5.8.1";
constructor(private getMonoVersion: IGetMonoVersion) {
}

private async configureEnvironmentAndGetInfo(options: Options): Promise<MonoInformation> {
let env = { ...process.env };
let monoPath: string;
if (options.useGlobalMono !== "never" && options.monoPath !== undefined) {
env['PATH'] = path.join(options.monoPath, 'bin') + path.delimiter + env['PATH'];
env['MONO_GAC_PREFIX'] = options.monoPath;
monoPath = options.monoPath;
}

let version = await this.getMonoVersion(env);

return {
version,
path: monoPath,
env
};
}

public async getGlobalMonoInfo(options: Options): Promise<MonoInformation> {
let monoInfo = await this.configureEnvironmentAndGetInfo(options);
let isValid = monoInfo.version && satisfies(monoInfo.version, `>=${this.minimumMonoVersion}`);

if (options.useGlobalMono === "always") {
if (!isValid) {
throw new Error(`Cannot start OmniSharp because Mono version >=${this.minimumMonoVersion} is required.`);
}

return monoInfo;
}
else if (options.useGlobalMono === "auto" && isValid) {
return monoInfo;
}

return undefined;
}
}

7 changes: 5 additions & 2 deletions src/omnisharp/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import Disposable from '../Disposable';
import OptionProvider from '../observers/OptionProvider';
import trackVirtualDocuments from '../features/virtualDocumentTracker';
import { StructureProvider } from '../features/structureProvider';
import { OmniSharpMonoResolver } from './OmniSharpMonoResolver';
import { getMonoVersion } from '../utils/getMonoVersion';

export let omnisharp: OmniSharpServer;

Expand All @@ -45,7 +47,8 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an
};

const options = optionProvider.GetLatestOptions();
const server = new OmniSharpServer(vscode, provider, packageJSON, platformInfo, eventStream, optionProvider, extensionPath);
let omnisharpMonoResolver = new OmniSharpMonoResolver(getMonoVersion);
const server = new OmniSharpServer(vscode, provider, packageJSON, platformInfo, eventStream, optionProvider, extensionPath, omnisharpMonoResolver);
omnisharp = server;
const advisor = new Advisor(server); // create before server is started
const disposables = new CompositeDisposable();
Expand Down Expand Up @@ -93,7 +96,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an
localDisposables = null;
}));

disposables.add(registerCommands(server, platformInfo, eventStream, optionProvider));
disposables.add(registerCommands(server, platformInfo, eventStream, optionProvider, omnisharpMonoResolver));

if (!context.workspaceState.get<boolean>('assetPromptDisabled')) {
disposables.add(server.onServerStart(() => {
Expand Down
Loading

0 comments on commit 9f37c43

Please sign in to comment.