Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement report issue command for prerelease extension #5837

Merged
merged 10 commits into from
Jun 27, 2023
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"typescript": "4.6.3",
"unzipper": "0.10.11",
"vsce": "2.9.2",
"vscode-uri": "^3.0.7",
"webpack": "5.76.0",
"webpack-cli": "4.6.0"
},
Expand Down Expand Up @@ -1677,8 +1678,7 @@
{
"command": "csharp.reportIssue",
"title": "Report an issue",
"category": "CSharp",
"enablement": "config.dotnet.server.useOmnisharp"
"category": "CSharp"
},
{
"command": "csharp.showDecompilationTerms",
Expand Down
10 changes: 0 additions & 10 deletions src/constants/IGetDotnetInfo.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/coreclr-debug/activate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PlatformInformation } from '../shared/platform';
import { DebuggerPrerequisiteWarning, DebuggerPrerequisiteFailure, DebuggerNotInstalledFailure } from '../omnisharp/loggingEvents';
import { EventStream } from '../EventStream';
import { getRuntimeDependencyPackageWithId } from '../tools/RuntimeDependencyPackageUtils';
import { getDotnetInfo } from '../utils/getDotnetInfo';
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
import { Options } from '../shared/options';
import { RemoteAttachPicker } from '../features/processPicker';
import CompositeDisposable from '../CompositeDisposable';
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr-debug/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as fs from 'fs';
import * as semver from 'semver';
import * as os from 'os';
import { PlatformInformation } from '../shared/platform';
import { getDotnetInfo, DotnetInfo } from '../utils/getDotnetInfo';
import { getDotnetInfo, DotnetInfo } from '../shared/utils/getDotnetInfo';

const MINIMUM_SUPPORTED_DOTNET_CLI: string = '1.0.0';

Expand Down Expand Up @@ -127,6 +127,10 @@ export function getTargetArchitecture(platformInfo: PlatformInformation, launchJ
}

// Otherwise, look at the runtime ID.
if (!dotnetInfo.RuntimeId) {
throw new Error(`Unable to determine RuntimeId. Please set 'targetArchitecture' in your launch.json configuration.`);
}

if (dotnetInfo.RuntimeId.includes('arm64'))
{
return 'arm64';
Expand Down
6 changes: 3 additions & 3 deletions src/features/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { EventStream } from '../EventStream';
import { PlatformInformation } from '../shared/platform';
import CompositeDisposable from '../CompositeDisposable';
import OptionProvider from '../shared/observers/OptionProvider';
import reportIssue from './reportIssue';
import reportIssue from '../shared/reportIssue';
import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver';
import { getDotnetInfo } from '../utils/getDotnetInfo';
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
import { getDecompilationAuthorization, resetDecompilationAuthorization } from '../omnisharp/decompilationPrompt';
import { IWorkspaceDebugInformationProvider } from '../shared/IWorkspaceDebugInformationProvider';

Expand All @@ -47,7 +47,7 @@ export default function registerCommands(
// Register command for generating tasks.json and launch.json assets.
disposable.add(vscode.commands.registerCommand('dotnet.generateAssets', async (selectedIndex) => generateAssets(workspaceInformationProvider, selectedIndex)));

disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, context.extension.packageJSON.version, eventStream, getDotnetInfo, platformInfo.isValidPlatformForMono(), optionProvider.GetLatestOptions(), dotnetResolver, monoResolver)));
disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, context.extension.packageJSON.version, getDotnetInfo, platformInfo.isValidPlatformForMono(), optionProvider.GetLatestOptions(), dotnetResolver, monoResolver)));

disposable.add(vscode.commands.registerCommand('csharp.showDecompilationTerms', async () => showDecompilationTerms(context, server, optionProvider)));

Expand Down
116 changes: 0 additions & 116 deletions src/features/reportIssue.ts

This file was deleted.

7 changes: 6 additions & 1 deletion src/lsptoolshost/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import { UriConverter } from './uriConverter';
import * as languageClient from 'vscode-languageclient/node';
import { RoslynLanguageServer } from './roslynLanguageServer';
import { createLaunchTargetForSolution } from '../shared/LaunchTarget';
import reportIssue from '../shared/reportIssue';
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
import OptionProvider from '../shared/observers/OptionProvider';
import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver';

export function registerCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) {
export function registerCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer, optionProvider: OptionProvider, hostExecutableResolver: IHostExecutableResolver) {
// It is very important to be careful about the types used as parameters for these command callbacks.
// If the arguments are coming from the server as json, it is NOT appropriate to use type definitions
// from the normal vscode API (e.g. vscode.Location) as input parameters.
Expand All @@ -23,6 +27,7 @@ export function registerCommands(context: vscode.ExtensionContext, languageServe
context.subscriptions.push(vscode.commands.registerCommand('roslyn.client.completionComplexEdit', completionComplexEdit));
context.subscriptions.push(vscode.commands.registerCommand('dotnet.restartServer', async () => restartServer(languageServer)));
context.subscriptions.push(vscode.commands.registerCommand('dotnet.openSolution', async () => openSolution(languageServer)));
context.subscriptions.push(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, context.extension.packageJSON.version, getDotnetInfo, /*shouldIncludeMonoInfo:*/ false, optionProvider.GetLatestOptions(), hostExecutableResolver)));
}

/**
Expand Down
104 changes: 104 additions & 0 deletions src/lsptoolshost/dotnetRuntimeExtensionResolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as path from 'path';
import * as vscode from 'vscode';
import { HostExecutableInformation } from "../shared/constants/HostExecutableInformation";
import { IHostExecutableResolver } from "../shared/constants/IHostExecutableResolver";
import { PlatformInformation } from "../shared/platform";
import { Options } from "../shared/options";
import { existsSync } from 'fs';
import { CSharpExtensionId } from '../constants/CSharpExtensionId';

export const DotNetRuntimeVersion = '7.0';

interface IDotnetAcquireResult {
jaredpar marked this conversation as resolved.
Show resolved Hide resolved
dotnetPath: string;
}

/**
* Resolves the dotnet runtime for a server executable from given options and the dotnet runtime VSCode extension.
*/
export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
Copy link
Member Author

Choose a reason for hiding this comment

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

moved the runtime resolution into the IHostExecutableResolver so we can get this information in other places (and share more code with O#).

Copy link
Member Author

Choose a reason for hiding this comment

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

this is all essentially just moved

constructor(
private platformInfo: PlatformInformation,
/**
* This is a function instead of a string because the server path can change while the extension is active (when the option changes).
*/
private getServerPath: (options: Options, platform: PlatformInformation) => string) { }
Copy link
Member Author

@dibarbet dibarbet Jun 23, 2023

Choose a reason for hiding this comment

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

Updating to eventually share this with Razor - #5855
A couple reasons for doing it this way

  1. As mentioned in the comment it needs to be a function for when the server path changes (from the option). One IHostExecutableResolver is created during activation for roslyn, and re-used across server restarts.
  2. It didn't seem appropriate to update getHostExecutableInfo to take in the path because not all implementations of IHostExecutableResolver require a server path (for example used in O# with dotnet and mono as well). Its more of a property of this specific resolver.


private hostInfo: HostExecutableInformation | undefined;

async getHostExecutableInfo(options: Options): Promise<HostExecutableInformation> {
let dotnetRuntimePath = options.commonOptions.dotnetPath;
const serverPath = this.getServerPath(options, this.platformInfo);
if (!dotnetRuntimePath) {
let dotnetInfo = await this.acquireDotNetProcessDependencies(serverPath);
dotnetRuntimePath = path.dirname(dotnetInfo.path);
}

const dotnetExecutableName = this.platformInfo.isWindows() ? 'dotnet.exe' : 'dotnet';
const dotnetExecutablePath = path.join(dotnetRuntimePath, dotnetExecutableName);
if (!existsSync(dotnetExecutablePath)) {
throw new Error(`Cannot find dotnet path '${dotnetExecutablePath}'`);
}

return {
version: "", /* We don't need to know the version - we've already downloaded the correct one */
path: dotnetExecutablePath,
env: process.env,
};
}

/**
* Acquires the .NET runtime if it is not already present.
* @returns The path to the .NET runtime
*/
private async acquireRuntime(): Promise<HostExecutableInformation> {
if (this.hostInfo) {
return this.hostInfo;
}

let status = await vscode.commands.executeCommand<IDotnetAcquireResult>('dotnet.acquireStatus', {
version: DotNetRuntimeVersion,
requestingExtensionId: CSharpExtensionId,
});
if (status === undefined) {
await vscode.commands.executeCommand('dotnet.showAcquisitionLog');

status = await vscode.commands.executeCommand<IDotnetAcquireResult>('dotnet.acquire', {
version: DotNetRuntimeVersion,
requestingExtensionId: CSharpExtensionId,
});
if (!status?.dotnetPath) {
throw new Error('Could not resolve the dotnet path!');
}
}

return (this.hostInfo = {
version: DotNetRuntimeVersion,
path: status.dotnetPath,
env: process.env
});
}

/**
* Acquires the .NET runtime and any other dependencies required to spawn a particular .NET executable.
* @param path The path to the entrypoint assembly. Typically a .dll.
* @returns The path to the `dotnet` command to use to spawn the process.
*/
private async acquireDotNetProcessDependencies(path: string) {
const dotnetPath = await this.acquireRuntime();

const args = [path];
// This will install any missing Linux dependencies.
await vscode.commands.executeCommand('dotnet.ensureDotnetDependencies', { command: dotnetPath, arguments: args });

return dotnetPath;
}
}



Loading