Skip to content

Commit 32917c2

Browse files
authored
Merge pull request #5837 from dibarbet/report_issue
Implement report issue command for prerelease extension
2 parents c81fc4a + 949bbc9 commit 32917c2

25 files changed

+351
-327
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
"typescript": "4.6.3",
143143
"unzipper": "0.10.11",
144144
"vsce": "2.9.2",
145+
"vscode-uri": "^3.0.7",
145146
"webpack": "5.76.0",
146147
"webpack-cli": "4.6.0"
147148
},
@@ -1678,8 +1679,7 @@
16781679
{
16791680
"command": "csharp.reportIssue",
16801681
"title": "Report an issue",
1681-
"category": "CSharp",
1682-
"enablement": "config.dotnet.server.useOmnisharp"
1682+
"category": "CSharp"
16831683
},
16841684
{
16851685
"command": "csharp.showDecompilationTerms",

src/constants/IGetDotnetInfo.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/coreclr-debug/activate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { PlatformInformation } from '../shared/platform';
1111
import { DebuggerPrerequisiteWarning, DebuggerPrerequisiteFailure, DebuggerNotInstalledFailure } from '../omnisharp/loggingEvents';
1212
import { EventStream } from '../EventStream';
1313
import { getRuntimeDependencyPackageWithId } from '../tools/RuntimeDependencyPackageUtils';
14-
import { getDotnetInfo } from '../utils/getDotnetInfo';
14+
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
1515
import { Options } from '../shared/options';
1616
import { RemoteAttachPicker } from '../features/processPicker';
1717
import CompositeDisposable from '../CompositeDisposable';

src/coreclr-debug/util.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as fs from 'fs';
88
import * as semver from 'semver';
99
import * as os from 'os';
1010
import { PlatformInformation } from '../shared/platform';
11-
import { getDotnetInfo, DotnetInfo } from '../utils/getDotnetInfo';
11+
import { getDotnetInfo, DotnetInfo } from '../shared/utils/getDotnetInfo';
1212

1313
const MINIMUM_SUPPORTED_DOTNET_CLI: string = '1.0.0';
1414

@@ -127,6 +127,10 @@ export function getTargetArchitecture(platformInfo: PlatformInformation, launchJ
127127
}
128128

129129
// Otherwise, look at the runtime ID.
130+
if (!dotnetInfo.RuntimeId) {
131+
throw new Error(`Unable to determine RuntimeId. Please set 'targetArchitecture' in your launch.json configuration.`);
132+
}
133+
130134
if (dotnetInfo.RuntimeId.includes('arm64'))
131135
{
132136
return 'arm64';

src/features/commands.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import { EventStream } from '../EventStream';
1818
import { PlatformInformation } from '../shared/platform';
1919
import CompositeDisposable from '../CompositeDisposable';
2020
import OptionProvider from '../shared/observers/OptionProvider';
21-
import reportIssue from './reportIssue';
21+
import reportIssue from '../shared/reportIssue';
2222
import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver';
23-
import { getDotnetInfo } from '../utils/getDotnetInfo';
23+
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
2424
import { getDecompilationAuthorization, resetDecompilationAuthorization } from '../omnisharp/decompilationPrompt';
2525
import { IWorkspaceDebugInformationProvider } from '../shared/IWorkspaceDebugInformationProvider';
2626

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

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

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

src/features/reportIssue.ts

Lines changed: 0 additions & 116 deletions
This file was deleted.

src/lsptoolshost/commands.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ import { UriConverter } from './uriConverter';
88
import * as languageClient from 'vscode-languageclient/node';
99
import { RoslynLanguageServer } from './roslynLanguageServer';
1010
import { createLaunchTargetForSolution } from '../shared/LaunchTarget';
11+
import reportIssue from '../shared/reportIssue';
12+
import { getDotnetInfo } from '../shared/utils/getDotnetInfo';
13+
import OptionProvider from '../shared/observers/OptionProvider';
14+
import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver';
1115

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

2833
/**
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as path from 'path';
7+
import * as vscode from 'vscode';
8+
import { HostExecutableInformation } from "../shared/constants/HostExecutableInformation";
9+
import { IHostExecutableResolver } from "../shared/constants/IHostExecutableResolver";
10+
import { PlatformInformation } from "../shared/platform";
11+
import { Options } from "../shared/options";
12+
import { existsSync } from 'fs';
13+
import { CSharpExtensionId } from '../constants/CSharpExtensionId';
14+
15+
export const DotNetRuntimeVersion = '7.0';
16+
17+
interface IDotnetAcquireResult {
18+
dotnetPath: string;
19+
}
20+
21+
/**
22+
* Resolves the dotnet runtime for a server executable from given options and the dotnet runtime VSCode extension.
23+
*/
24+
export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
25+
constructor(
26+
private platformInfo: PlatformInformation,
27+
/**
28+
* This is a function instead of a string because the server path can change while the extension is active (when the option changes).
29+
*/
30+
private getServerPath: (options: Options, platform: PlatformInformation) => string) { }
31+
32+
private hostInfo: HostExecutableInformation | undefined;
33+
34+
async getHostExecutableInfo(options: Options): Promise<HostExecutableInformation> {
35+
let dotnetRuntimePath = options.commonOptions.dotnetPath;
36+
const serverPath = this.getServerPath(options, this.platformInfo);
37+
if (!dotnetRuntimePath) {
38+
let dotnetInfo = await this.acquireDotNetProcessDependencies(serverPath);
39+
dotnetRuntimePath = path.dirname(dotnetInfo.path);
40+
}
41+
42+
const dotnetExecutableName = this.platformInfo.isWindows() ? 'dotnet.exe' : 'dotnet';
43+
const dotnetExecutablePath = path.join(dotnetRuntimePath, dotnetExecutableName);
44+
if (!existsSync(dotnetExecutablePath)) {
45+
throw new Error(`Cannot find dotnet path '${dotnetExecutablePath}'`);
46+
}
47+
48+
return {
49+
version: "", /* We don't need to know the version - we've already downloaded the correct one */
50+
path: dotnetExecutablePath,
51+
env: process.env,
52+
};
53+
}
54+
55+
/**
56+
* Acquires the .NET runtime if it is not already present.
57+
* @returns The path to the .NET runtime
58+
*/
59+
private async acquireRuntime(): Promise<HostExecutableInformation> {
60+
if (this.hostInfo) {
61+
return this.hostInfo;
62+
}
63+
64+
let status = await vscode.commands.executeCommand<IDotnetAcquireResult>('dotnet.acquireStatus', {
65+
version: DotNetRuntimeVersion,
66+
requestingExtensionId: CSharpExtensionId,
67+
});
68+
if (status === undefined) {
69+
await vscode.commands.executeCommand('dotnet.showAcquisitionLog');
70+
71+
status = await vscode.commands.executeCommand<IDotnetAcquireResult>('dotnet.acquire', {
72+
version: DotNetRuntimeVersion,
73+
requestingExtensionId: CSharpExtensionId,
74+
});
75+
if (!status?.dotnetPath) {
76+
throw new Error('Could not resolve the dotnet path!');
77+
}
78+
}
79+
80+
return (this.hostInfo = {
81+
version: DotNetRuntimeVersion,
82+
path: status.dotnetPath,
83+
env: process.env
84+
});
85+
}
86+
87+
/**
88+
* Acquires the .NET runtime and any other dependencies required to spawn a particular .NET executable.
89+
* @param path The path to the entrypoint assembly. Typically a .dll.
90+
* @returns The path to the `dotnet` command to use to spawn the process.
91+
*/
92+
private async acquireDotNetProcessDependencies(path: string) {
93+
const dotnetPath = await this.acquireRuntime();
94+
95+
const args = [path];
96+
// This will install any missing Linux dependencies.
97+
await vscode.commands.executeCommand('dotnet.ensureDotnetDependencies', { command: dotnetPath, arguments: args });
98+
99+
return dotnetPath;
100+
}
101+
}
102+
103+
104+

0 commit comments

Comments
 (0)