Skip to content

Commit 892916e

Browse files
authored
Merge pull request #6603 from dibarbet/nuget_restore
Add support for nuget restore commands
2 parents 2d3f1d7 + d8ec615 commit 892916e

File tree

7 files changed

+154
-4
lines changed

7 files changed

+154
-4
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
- Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876)
77

88
## Latest
9+
* Update Roslyn to 4.9.0-1.23530.4 (PR: [#6603](https://github.com/dotnet/vscode-csharp/pull/6603))
10+
* Enable NuGet restore commands `dotnet.restore.all` and `dotnet.restore.project` (PR: [#70588](https://github.com/dotnet/roslyn/pull/70588))
11+
* Fix issue where server did not reload projects after NuGet restore (PR: [#70602](https://github.com/dotnet/roslyn/pull/70602))
912
* Update debugger to 2.9.0 (PR: [#6623](https://github.com/dotnet/vscode-csharp/pull/6623))
1013
* Flush `Console.Write` buffer more often (Fixes: [#6598](https://github.com/dotnet/vscode-csharp/issues/6598))
1114
* Fix logpoint freezing on start (Fixes: [#6585](https://github.com/dotnet/vscode-csharp/issues/6585))

l10n/bundle.l10n.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@
130130
"Choose": "Choose",
131131
"Choose and set default": "Choose and set default",
132132
"Do not load any": "Do not load any",
133+
"Restore already in progress": "Restore already in progress",
134+
"Restore": "Restore",
135+
"Sending request": "Sending request",
133136
"C# configuration has changed. Would you like to reload the window to apply your changes?": "C# configuration has changed. Would you like to reload the window to apply your changes?",
134137
"Pick a fix all scope": "Pick a fix all scope",
135138
"Fix All Code Action": "Fix All Code Action",

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
}
3838
},
3939
"defaults": {
40-
"roslyn": "4.9.0-1.23526.14",
40+
"roslyn": "4.9.0-1.23530.4",
4141
"omniSharp": "1.39.10",
4242
"razor": "7.0.0-preview.23528.1",
4343
"razorOmnisharp": "7.0.0-preview.23363.1",
@@ -2038,13 +2038,13 @@
20382038
"command": "dotnet.restore.project",
20392039
"title": "%command.dotnet.restore.project%",
20402040
"category": ".NET",
2041-
"enablement": "config.dotnet.server.useOmnisharp"
2041+
"enablement": "dotnet.server.activatedStandalone"
20422042
},
20432043
{
20442044
"command": "dotnet.restore.all",
20452045
"title": "%command.dotnet.restore.all%",
20462046
"category": ".NET",
2047-
"enablement": "config.dotnet.server.useOmnisharp"
2047+
"enablement": "dotnet.server.activatedStandalone"
20482048
},
20492049
{
20502050
"command": "csharp.downloadDebugger",

src/lsptoolshost/restore.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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 vscode from 'vscode';
7+
import { RoslynLanguageServer } from './roslynLanguageServer';
8+
import { RestorableProjects, RestoreParams, RestorePartialResult, RestoreRequest } from './roslynProtocol';
9+
import path = require('path');
10+
11+
let _restoreInProgress = false;
12+
13+
export function registerRestoreCommands(
14+
context: vscode.ExtensionContext,
15+
languageServer: RoslynLanguageServer,
16+
restoreChannel: vscode.OutputChannel
17+
) {
18+
context.subscriptions.push(
19+
vscode.commands.registerCommand('dotnet.restore.project', async (_request): Promise<void> => {
20+
return chooseProjectAndRestore(languageServer, restoreChannel);
21+
})
22+
);
23+
context.subscriptions.push(
24+
vscode.commands.registerCommand('dotnet.restore.all', async (): Promise<void> => {
25+
return restore(languageServer, restoreChannel);
26+
})
27+
);
28+
}
29+
async function chooseProjectAndRestore(
30+
languageServer: RoslynLanguageServer,
31+
restoreChannel: vscode.OutputChannel
32+
): Promise<void> {
33+
const projects = await languageServer.sendRequest0(
34+
RestorableProjects.type,
35+
new vscode.CancellationTokenSource().token
36+
);
37+
38+
const items = projects.map((p) => {
39+
const projectName = path.basename(p);
40+
const item: vscode.QuickPickItem = {
41+
label: vscode.l10n.t(`Restore {0}`, projectName),
42+
description: p,
43+
};
44+
return item;
45+
});
46+
47+
const pickedItem = await vscode.window.showQuickPick(items);
48+
if (!pickedItem) {
49+
return;
50+
}
51+
52+
await restore(languageServer, restoreChannel, pickedItem.description);
53+
}
54+
55+
async function restore(
56+
languageServer: RoslynLanguageServer,
57+
restoreChannel: vscode.OutputChannel,
58+
projectFile?: string
59+
): Promise<void> {
60+
if (_restoreInProgress) {
61+
vscode.window.showErrorMessage(vscode.l10n.t('Restore already in progress'));
62+
return;
63+
}
64+
_restoreInProgress = true;
65+
restoreChannel.show(true);
66+
67+
const request: RestoreParams = { projectFilePath: projectFile };
68+
await vscode.window
69+
.withProgress(
70+
{
71+
location: vscode.ProgressLocation.Notification,
72+
title: vscode.l10n.t('Restore'),
73+
cancellable: true,
74+
},
75+
async (progress, token) => {
76+
const writeOutput = (output: RestorePartialResult) => {
77+
if (output.message) {
78+
restoreChannel.appendLine(output.message);
79+
}
80+
81+
progress.report({ message: output.stage });
82+
};
83+
84+
progress.report({ message: vscode.l10n.t('Sending request') });
85+
const responsePromise = languageServer.sendRequestWithProgress(
86+
RestoreRequest.type,
87+
request,
88+
async (p) => writeOutput(p),
89+
token
90+
);
91+
92+
await responsePromise.then(
93+
(result) => result.forEach((r) => writeOutput(r)),
94+
(err) => restoreChannel.appendLine(err)
95+
);
96+
}
97+
)
98+
.then(
99+
() => {
100+
_restoreInProgress = false;
101+
},
102+
() => {
103+
_restoreInProgress = false;
104+
}
105+
);
106+
107+
return;
108+
}

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import { registerCodeActionFixAllCommands } from './fixAllCodeAction';
5656
import { commonOptions, languageServerOptions, omnisharpOptions } from '../shared/options';
5757
import { NamedPipeInformation } from './roslynProtocol';
5858
import { IDisposable } from '../disposable';
59+
import { registerRestoreCommands } from './restore';
5960

6061
let _channel: vscode.OutputChannel;
6162
let _traceChannel: vscode.OutputChannel;
@@ -835,6 +836,7 @@ export async function activateRoslynLanguageServer(
835836
optionObservable: Observable<void>,
836837
outputChannel: vscode.OutputChannel,
837838
dotnetTestChannel: vscode.OutputChannel,
839+
dotnetChannel: vscode.OutputChannel,
838840
reporter: TelemetryReporter,
839841
languageServerEvents: RoslynLanguageServerEvents
840842
): Promise<RoslynLanguageServer> {
@@ -872,6 +874,8 @@ export async function activateRoslynLanguageServer(
872874
// Register any needed debugger components that need to communicate with the language server.
873875
registerDebugger(context, languageServer, languageServerEvents, platformInfo, _channel);
874876

877+
registerRestoreCommands(context, languageServer, dotnetChannel);
878+
875879
registerOnAutoInsert(languageServer);
876880

877881
context.subscriptions.push(registerLanguageServerOptionChanges(optionObservable));

src/lsptoolshost/roslynProtocol.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ export interface NamedPipeInformation {
150150
pipeName: string;
151151
}
152152

153+
export interface RestoreParams extends lsp.WorkDoneProgressParams, lsp.PartialResultParams {
154+
/**
155+
* An optional file path to restore.
156+
* If none is specified, the solution (or all loaded projects) are restored.
157+
*/
158+
projectFilePath?: string;
159+
}
160+
161+
export interface RestorePartialResult {
162+
stage: string;
163+
message: string;
164+
}
165+
153166
export namespace WorkspaceDebugConfigurationRequest {
154167
export const method = 'workspace/debugConfiguration';
155168
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
@@ -229,3 +242,21 @@ export namespace CodeActionFixAllResolveRequest {
229242
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
230243
export const type = new lsp.RequestType<RoslynFixAllCodeAction, RoslynFixAllCodeAction, void>(method);
231244
}
245+
246+
export namespace RestoreRequest {
247+
export const method = 'workspace/_roslyn_restore';
248+
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
249+
export const type = new lsp.ProtocolRequestType<
250+
RestoreParams,
251+
RestorePartialResult[],
252+
RestorePartialResult,
253+
void,
254+
void
255+
>(method);
256+
}
257+
258+
export namespace RestorableProjects {
259+
export const method = 'workspace/_roslyn_restorableProjects';
260+
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
261+
export const type = new lsp.RequestType0<string[], void>(method);
262+
}

src/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export async function activate(
8282

8383
const csharpChannel = vscode.window.createOutputChannel('C#');
8484
const dotnetTestChannel = vscode.window.createOutputChannel('.NET Test Log');
85+
const dotnetChannel = vscode.window.createOutputChannel('.NET NuGet Restore');
8586
const csharpchannelObserver = new CsharpChannelObserver(csharpChannel);
8687
const csharpLogObserver = new CsharpLoggerObserver(csharpChannel);
8788
eventStream.subscribe(csharpchannelObserver.post);
@@ -175,11 +176,11 @@ export async function activate(
175176
optionStream,
176177
csharpChannel,
177178
dotnetTestChannel,
179+
dotnetChannel,
178180
reporter,
179181
roslynLanguageServerEvents
180182
);
181183
} else {
182-
const dotnetChannel = vscode.window.createOutputChannel('.NET');
183184
const dotnetChannelObserver = new DotNetChannelObserver(dotnetChannel);
184185
const dotnetLoggerObserver = new DotnetLoggerObserver(dotnetChannel);
185186
eventStream.subscribe(dotnetChannelObserver.post);

0 commit comments

Comments
 (0)