diff --git a/package.json b/package.json index 3c095f6af..5d963bd74 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,8 @@ "onCommand:o.restart", "onCommand:o.pickProjectAndStart", "onCommand:o.showOutput", - "onCommand:dotnet.restore", + "onCommand:dotnet.restore.project", + "onCommand:dotnet.restore.all", "onCommand:dotnet.generateAssets", "onCommand:csharp.downloadDebugger", "onCommand:csharp.listProcess", @@ -606,8 +607,13 @@ "category": ".NET" }, { - "command": "dotnet.restore", - "title": "Restore Packages", + "command": "dotnet.restore.project", + "title": "Restore Project", + "category": ".NET" + }, + { + "command": "dotnet.restore.all", + "title": "Restore All Projects", "category": ".NET" }, { diff --git a/src/features/commands.ts b/src/features/commands.ts index 2bfa76aca..c21e8af27 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -21,38 +21,33 @@ import CompositeDisposable from '../CompositeDisposable'; import OptionProvider from '../observers/OptionProvider'; export default function registerCommands(server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider): CompositeDisposable { - let d1 = vscode.commands.registerCommand('o.restart', () => restartOmniSharp(server)); - let d2 = vscode.commands.registerCommand('o.pickProjectAndStart', async () => pickProjectAndStart(server, optionProvider)); - let d3 = vscode.commands.registerCommand('o.showOutput', () => eventStream.post(new ShowOmniSharpChannel())); - let d4 = vscode.commands.registerCommand('dotnet.restore', fileName => { - if (fileName) { - dotnetRestoreForProject(server, fileName, eventStream); - } - else { - dotnetRestoreAllProjects(server, eventStream); - } - }); + let disposable = new CompositeDisposable(); + disposable.add(vscode.commands.registerCommand('o.restart', () => restartOmniSharp(server))); + disposable.add(vscode.commands.registerCommand('o.pickProjectAndStart', async () => pickProjectAndStart(server, optionProvider))); + disposable.add(vscode.commands.registerCommand('o.showOutput', () => eventStream.post(new ShowOmniSharpChannel()))); + disposable.add(vscode.commands.registerCommand('dotnet.restore.project', () => pickProjectAndDotnetRestore(server, eventStream))); + disposable.add(vscode.commands.registerCommand('dotnet.restore.all', () => dotnetRestoreAllProjects(server, eventStream))); // register empty handler for csharp.installDebugger // running the command activates the extension, which is all we need for installation to kickoff - let d5 = vscode.commands.registerCommand('csharp.downloadDebugger', () => { }); + disposable.add(vscode.commands.registerCommand('csharp.downloadDebugger', () => { })); // register process picker for attach let attachItemsProvider = DotNetAttachItemsProviderFactory.Get(); let attacher = new AttachPicker(attachItemsProvider); - let d6 = vscode.commands.registerCommand('csharp.listProcess', async () => attacher.ShowAttachEntries()); + disposable.add(vscode.commands.registerCommand('csharp.listProcess', async () => attacher.ShowAttachEntries())); // Register command for generating tasks.json and launch.json assets. - let d7 = vscode.commands.registerCommand('dotnet.generateAssets', async () => generateAssets(server)); + disposable.add(vscode.commands.registerCommand('dotnet.generateAssets', async () => generateAssets(server))); // Register command for remote process picker for attach - let d8 = vscode.commands.registerCommand('csharp.listRemoteProcess', async (args) => RemoteAttachPicker.ShowAttachEntries(args, platformInfo)); + disposable.add(vscode.commands.registerCommand('csharp.listRemoteProcess', async (args) => RemoteAttachPicker.ShowAttachEntries(args, platformInfo))); // Register command for adapter executable command. - let d9 = vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)); - let d10 = vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)); + disposable.add(vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream))); + disposable.add(vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream))); - return new CompositeDisposable(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10); + return new CompositeDisposable(disposable); } function restartOmniSharp(server: OmniSharpServer) { @@ -64,7 +59,7 @@ function restartOmniSharp(server: OmniSharpServer) { } } -async function pickProjectAndStart(server: OmniSharpServer, optionProvider: OptionProvider) { +async function pickProjectAndStart(server: OmniSharpServer, optionProvider: OptionProvider): Promise { let options = optionProvider.GetLatestOptions(); return findLaunchTargets(options).then(targets => { @@ -120,58 +115,40 @@ function projectsToCommands(projects: protocol.ProjectDescriptor[], eventStream: }); } -export async function dotnetRestoreAllProjects(server: OmniSharpServer, eventStream: EventStream): Promise { - - if (!server.isRunning()) { - return Promise.reject('OmniSharp server is not running.'); +async function pickProjectAndDotnetRestore(server: OmniSharpServer, eventStream: EventStream): Promise { + let descriptors = await getProjectDescriptors(server); + eventStream.post(new CommandDotNetRestoreStart()); + let commands = await Promise.all(projectsToCommands(descriptors, eventStream)); + let command = await vscode.window.showQuickPick(commands); + if (command) { + return command.execute(); } - - return serverUtils.requestWorkspaceInformation(server).then(async info => { - - let descriptors = protocol.getDotNetCoreProjectDescriptors(info); - - if (descriptors.length === 0) { - return Promise.reject("No .NET Core projects found"); - } - - let commandPromises = projectsToCommands(descriptors, eventStream); - - return Promise.all(commandPromises).then(commands => { - return vscode.window.showQuickPick(commands); - }).then(command => { - if (command) { - return command.execute(); - } - }); - }); } -export async function dotnetRestoreForProject(server: OmniSharpServer, filePath: string, eventStream: EventStream) { +async function dotnetRestoreAllProjects(server: OmniSharpServer, eventStream: EventStream): Promise { + let descriptors = await getProjectDescriptors(server); + eventStream.post(new CommandDotNetRestoreStart()); + for (let descriptor of descriptors) { + await dotnetRestore(descriptor.Directory, eventStream); + } +} +async function getProjectDescriptors(server: OmniSharpServer): Promise { if (!server.isRunning()) { return Promise.reject('OmniSharp server is not running.'); } - return serverUtils.requestWorkspaceInformation(server).then(async info => { - - let descriptors = protocol.getDotNetCoreProjectDescriptors(info); - - if (descriptors.length === 0) { - return Promise.reject("No .NET Core projects found"); - } + let info = await serverUtils.requestWorkspaceInformation(server); + let descriptors = protocol.getDotNetCoreProjectDescriptors(info); + if (descriptors.length === 0) { + return Promise.reject("No .NET Core projects found"); + } - for (let descriptor of descriptors) { - if (descriptor.FilePath === filePath) { - return dotnetRestore(descriptor.Directory, eventStream, filePath); - } - } - }); + return descriptors; } -async function dotnetRestore(cwd: string, eventStream: EventStream, filePath?: string) { +async function dotnetRestore(cwd: string, eventStream: EventStream, filePath?: string): Promise { return new Promise((resolve, reject) => { - eventStream.post(new CommandDotNetRestoreStart()); - let cmd = 'dotnet'; let args = ['restore']; diff --git a/src/observers/InformationMessageObserver.ts b/src/observers/InformationMessageObserver.ts index 2c42d7e28..64afa8823 100644 --- a/src/observers/InformationMessageObserver.ts +++ b/src/observers/InformationMessageObserver.ts @@ -20,10 +20,11 @@ export class InformationMessageObserver { } private async handleOmnisharpServerUnresolvedDependencies(event: ObservableEvent.OmnisharpServerUnresolvedDependencies) { + //to do: determine if we need the unresolved dependencies message let csharpConfig = this.vscode.workspace.getConfiguration('csharp'); if (!csharpConfig.get('suppressDotnetRestoreNotification')) { - let message = `There are unresolved dependencies from '${this.vscode.workspace.asRelativePath(event.unresolvedDependencies.FileName)}'. Please execute the restore command to continue.`; - return showInformationMessage(this.vscode, message, { title: 'Restore', command: 'dotnet.restore', args: event.unresolvedDependencies.FileName }); + let message = `There are unresolved dependencies'. Please execute the restore command to continue.`; + return showInformationMessage(this.vscode, message, { title: "Restore", command: "dotnet.restore.all" }); } } } diff --git a/src/observers/utils/MessageItemWithCommand.ts b/src/observers/utils/MessageItemWithCommand.ts index d0367f7db..81fec5f34 100644 --- a/src/observers/utils/MessageItemWithCommand.ts +++ b/src/observers/utils/MessageItemWithCommand.ts @@ -7,5 +7,4 @@ import { MessageItem } from "../../vscodeAdapter"; export default interface MessageItemWithCommand extends MessageItem { command: string; - args?: any; } diff --git a/src/observers/utils/ShowInformationMessage.ts b/src/observers/utils/ShowInformationMessage.ts index 5d97bc9ec..02537f3e7 100644 --- a/src/observers/utils/ShowInformationMessage.ts +++ b/src/observers/utils/ShowInformationMessage.ts @@ -4,18 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { vscode } from "../../vscodeAdapter"; -import MessageItemWithCommand from "./MessageItemWithCommand"; +import MessageItemWithCommand from "./MessageItemWithCommand"; export default async function showInformationMessage(vscode: vscode, message: string, ...items: MessageItemWithCommand[]) { try { let value = await vscode.window.showInformationMessage(message, ...items); if (value && value.command) { - if (value.args) { - vscode.commands.executeCommand(value.command, value.args); - } - else { - vscode.commands.executeCommand(value.command); - } + vscode.commands.executeCommand(value.command); } } catch (err) { diff --git a/test/unitTests/logging/InformationMessageObserver.test.ts b/test/unitTests/logging/InformationMessageObserver.test.ts index f3abc58a9..47e0dc2d7 100644 --- a/test/unitTests/logging/InformationMessageObserver.test.ts +++ b/test/unitTests/logging/InformationMessageObserver.test.ts @@ -22,11 +22,14 @@ suite("InformationMessageObserver", () => { let commandDone: Promise; let vscode = getVsCode(); let infoMessage: string; - let relativePath: string; let invokedCommand: string; let observer: InformationMessageObserver = new InformationMessageObserver(vscode); setup(() => { + infoMessage = undefined; + invokedCommand = undefined; + doClickCancel = undefined; + doClickOk = undefined; commandDone = new Promise(resolve => { signalCommandDone = () => { resolve(); }; }); @@ -35,7 +38,7 @@ suite("InformationMessageObserver", () => { [ { event: getUnresolvedDependenices("someFile"), - expectedCommand: "dotnet.restore" + expectedCommand: "dotnet.restore.all" } ].forEach((elem) => { suite(elem.event.constructor.name, () => { @@ -53,7 +56,6 @@ suite("InformationMessageObserver", () => { test('The information message is shown', async () => { observer.post(elem.event); - expect(relativePath).to.not.be.empty; expect(infoMessage).to.not.be.empty; doClickOk(); await commandDone; @@ -79,11 +81,6 @@ suite("InformationMessageObserver", () => { teardown(() => { commandDone = undefined; - infoMessage = undefined; - relativePath = undefined; - invokedCommand = undefined; - doClickCancel = undefined; - doClickOk = undefined; }); function getVsCode() { @@ -107,11 +104,6 @@ suite("InformationMessageObserver", () => { return undefined; }; - vscode.workspace.asRelativePath = (pathOrUri?: string, includeWorspaceFolder?: boolean) => { - relativePath = pathOrUri; - return relativePath; - }; - return vscode; } }); \ No newline at end of file