-
Notifications
You must be signed in to change notification settings - Fork 689
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
Add prerequisite check for running OmniSharp. #5397
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import * as vscode from "vscode"; | ||
import * as semver from "semver"; | ||
import { getDotnetInfo } from "../utils/getDotnetInfo"; | ||
import { Options } from "./options"; | ||
import { getMonoVersion } from "../utils/getMonoVersion"; | ||
import { OmniSharpMonoResolver } from "./OmniSharpMonoResolver"; | ||
import { getMSBuildVersion } from "../utils/getMSBuildInfo"; | ||
|
||
export interface RequirementResult { | ||
needsDotNetSdk: boolean; | ||
needsMono: boolean; | ||
needsMSBuildTools: boolean; | ||
} | ||
|
||
export async function validateRequirements(options: Options): Promise<boolean> { | ||
const result = await checkRequirements(options); | ||
|
||
if (result.needsDotNetSdk) { | ||
const downloadSdk = await promptToDownloadDotNetSDK(); | ||
|
||
if (downloadSdk === PromptResult.Yes) { | ||
let dotnetcoreURL = 'https://dot.net/core-sdk-vscode'; | ||
vscode.env.openExternal(vscode.Uri.parse(dotnetcoreURL)); | ||
} else if (downloadSdk === PromptResult.No) { | ||
vscode.commands.executeCommand('workbench.action.openGlobalSettings'); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
if (result.needsMono | ||
|| result.needsMSBuildTools) { // Since we are currently not checking for MSBuild Tools on Windows this indicates a partial install of Mono. | ||
|
||
const downloadMono = await promptToDownloadMono(); | ||
|
||
if (downloadMono === PromptResult.Yes) { | ||
let monoURL = 'https://www.mono-project.com/download/stable/'; | ||
vscode.env.openExternal(vscode.Uri.parse(monoURL)); | ||
} else if (downloadMono === PromptResult.No) { | ||
vscode.commands.executeCommand('workbench.action.openGlobalSettings'); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
async function checkRequirements(options: Options): Promise<RequirementResult> { | ||
if (options.useModernNet) { | ||
const dotnetInfo = await getDotnetInfo(options.dotNetCliPaths); | ||
const needsDotNetSdk = dotnetInfo.Version === undefined || semver.lt(dotnetInfo.Version, '6.0.0'); | ||
return { | ||
needsDotNetSdk, | ||
needsMono: false, | ||
needsMSBuildTools: false, | ||
}; | ||
} | ||
|
||
if (process.platform === 'win32') { | ||
// Need to determine way to surface missing MSBuild Tools for windows. | ||
return { | ||
needsMSBuildTools: false, | ||
needsDotNetSdk: false, | ||
needsMono: false, | ||
}; | ||
} | ||
else { | ||
const monoResolver = new OmniSharpMonoResolver(getMonoVersion); | ||
let monoError: Error | undefined; | ||
try { | ||
await monoResolver.getHostExecutableInfo(options); | ||
} catch (e) { | ||
monoError = e; | ||
} | ||
|
||
const msbuildVersion = await getMSBuildVersion(); | ||
|
||
return { | ||
needsMono: monoError !== undefined, | ||
needsDotNetSdk: false, | ||
needsMSBuildTools: msbuildVersion !== undefined, | ||
}; | ||
} | ||
} | ||
|
||
enum PromptResult { | ||
Dismissed, | ||
Yes, | ||
No | ||
} | ||
|
||
interface PromptItem extends vscode.MessageItem { | ||
result: PromptResult; | ||
} | ||
|
||
async function promptToDownloadDotNetSDK() { | ||
return new Promise<PromptResult>((resolve, reject) => { | ||
const message = 'OmniSharp requires an install of the .NET SDK to provide language services when `omnisharp.useModernNet` is enabled in Settings. Please install the latest .NET SDK and restart vscode. If you continue see this error after installing .NET and restarting vscode, you may need to log out and log back in or restart your system for changes to the PATH to take effect.'; | ||
|
||
const messageOptions: vscode.MessageOptions = { modal: true }; | ||
|
||
const yesItem: PromptItem = { title: 'Get the SDK', result: PromptResult.Yes }; | ||
const noItem: PromptItem = { title: 'Open settings', result: PromptResult.No, isCloseAffordance: true }; | ||
|
||
vscode.window.showErrorMessage(message, messageOptions, noItem, yesItem) | ||
.then(selection => resolve(selection?.result ?? PromptResult.Dismissed)); | ||
}); | ||
} | ||
|
||
async function promptToDownloadMono() { | ||
return new Promise<PromptResult>((resolve, reject) => { | ||
const message = 'OmniSharp requires a complete install of Mono (including MSBuild) to provide language services when `omnisharp.useModernNet` is disabled in Settings. Please install the latest Mono and restart.'; | ||
|
||
const messageOptions: vscode.MessageOptions = { modal: true }; | ||
|
||
const yesItem: PromptItem = { title: 'Download Mono', result: PromptResult.Yes }; | ||
const noItem: PromptItem = { title: 'Open settings', result: PromptResult.No, isCloseAffordance: true }; | ||
|
||
vscode.window.showErrorMessage(message, messageOptions, noItem, yesItem) | ||
.then(selection => resolve(selection?.result ?? PromptResult.Dismissed)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,8 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf | |
return _dotnetInfo; | ||
} | ||
|
||
let dotnetExeName = CoreClrDebugUtil.getPlatformExeExtension(); | ||
let dotnetExecutablePath = undefined; | ||
let dotnetExeName = join('dotnet', CoreClrDebugUtil.getPlatformExeExtension()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is currently broken in main. |
||
let dotnetExecutablePath: string | undefined = undefined; | ||
|
||
for (const dotnetPath of dotNetCliPaths) { | ||
let dotnetFullPath = join(dotnetPath, dotnetExeName); | ||
|
@@ -31,13 +31,12 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf | |
} | ||
} | ||
|
||
let dotnetInfo = new DotnetInfo(); | ||
const dotnetInfo = new DotnetInfo(); | ||
|
||
try { | ||
let data = await execChildProcess(`${dotnetExecutablePath || 'dotnet'} --info`, process.cwd()); | ||
|
||
dotnetInfo.CliPath = dotnetExecutablePath; | ||
let data = await execChildProcess(`${dotnetExecutablePath || 'dotnet'} --info`, process.cwd(), process.env); | ||
|
||
dotnetInfo.CliPath = dotnetExecutablePath; | ||
dotnetInfo.FullInfo = data; | ||
|
||
let lines: string[] = data.replace(/\r/mg, '').split('\n'); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import { join } from "path"; | ||
import { execChildProcess } from "../common"; | ||
import { CoreClrDebugUtil } from "../coreclr-debug/util"; | ||
|
||
export const MSBUILD_MISSING_MESSAGE = "A valid msbuild installation could not be found."; | ||
|
||
let _msbuildVersion: string | undefined; | ||
|
||
export async function getMSBuildVersion(): Promise<string | undefined> { | ||
if (_msbuildVersion !== undefined) { | ||
return _msbuildVersion; | ||
} | ||
|
||
const msbuildExeName = join('msbuild', CoreClrDebugUtil.getPlatformExeExtension()); | ||
|
||
try { | ||
let data = await execChildProcess(`${msbuildExeName} --version --nologo`, process.cwd(), process.env); | ||
const match = /^(\d+\.\d+\.\d+\.\d+)$/.exec(data); | ||
if (match.length > 0) { | ||
_msbuildVersion = match[1]; | ||
} | ||
} | ||
catch { | ||
} | ||
|
||
return _msbuildVersion; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow x64 Mono build of O# to install on Apple Silicon.