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 * as semver from "semver" ;
8+ import { getDotnetInfo } from "../utils/getDotnetInfo" ;
9+ import { Options } from "./options" ;
10+ import { getMonoVersion } from "../utils/getMonoVersion" ;
11+ import { OmniSharpMonoResolver } from "./OmniSharpMonoResolver" ;
12+ import { getMSBuildVersion } from "../utils/getMSBuildInfo" ;
13+
14+ export interface RequirementResult {
15+ needsDotNetSdk : boolean ;
16+ needsMono : boolean ;
17+ needsMSBuildTools : boolean ;
18+ }
19+
20+ export async function validateRequirements ( options : Options ) : Promise < boolean > {
21+ const result = await checkRequirements ( options ) ;
22+
23+ if ( result . needsDotNetSdk ) {
24+ const downloadSdk = await promptToDownloadDotNetSDK ( ) ;
25+
26+ if ( downloadSdk === PromptResult . Yes ) {
27+ let dotnetcoreURL = 'https://dot.net/core-sdk-vscode' ;
28+ vscode . env . openExternal ( vscode . Uri . parse ( dotnetcoreURL ) ) ;
29+ } else if ( downloadSdk === PromptResult . No ) {
30+ vscode . commands . executeCommand ( 'workbench.action.openGlobalSettings' ) ;
31+ }
32+
33+ return false ;
34+ }
35+
36+ if ( result . needsMono
37+ || result . needsMSBuildTools ) { // Since we are currently not checking for MSBuild Tools on Windows this indicates a partial install of Mono.
38+
39+ const downloadMono = await promptToDownloadMono ( ) ;
40+
41+ if ( downloadMono === PromptResult . Yes ) {
42+ let monoURL = 'https://www.mono-project.com/download/stable/' ;
43+ vscode . env . openExternal ( vscode . Uri . parse ( monoURL ) ) ;
44+ } else if ( downloadMono === PromptResult . No ) {
45+ vscode . commands . executeCommand ( 'workbench.action.openGlobalSettings' ) ;
46+ }
47+
48+ return false ;
49+ }
50+
51+ return true ;
52+ }
53+
54+ async function checkRequirements ( options : Options ) : Promise < RequirementResult > {
55+ if ( options . useModernNet ) {
56+ const dotnetInfo = await getDotnetInfo ( options . dotNetCliPaths ) ;
57+ const needsDotNetSdk = dotnetInfo . Version === undefined || semver . lt ( dotnetInfo . Version , '6.0.0' ) ;
58+ return {
59+ needsDotNetSdk,
60+ needsMono : false ,
61+ needsMSBuildTools : false ,
62+ } ;
63+ }
64+
65+ if ( process . platform === 'win32' ) {
66+ // Need to determine way to surface missing MSBuild Tools for windows.
67+ return {
68+ needsMSBuildTools : false ,
69+ needsDotNetSdk : false ,
70+ needsMono : false ,
71+ } ;
72+ }
73+ else {
74+ const monoResolver = new OmniSharpMonoResolver ( getMonoVersion ) ;
75+ let monoError : Error | undefined ;
76+ try {
77+ await monoResolver . getHostExecutableInfo ( options ) ;
78+ } catch ( e ) {
79+ monoError = e ;
80+ }
81+
82+ const msbuildVersion = await getMSBuildVersion ( ) ;
83+
84+ return {
85+ needsMono : monoError !== undefined ,
86+ needsDotNetSdk : false ,
87+ needsMSBuildTools : msbuildVersion !== undefined ,
88+ } ;
89+ }
90+ }
91+
92+ enum PromptResult {
93+ Dismissed ,
94+ Yes ,
95+ No
96+ }
97+
98+ interface PromptItem extends vscode . MessageItem {
99+ result : PromptResult ;
100+ }
101+
102+ async function promptToDownloadDotNetSDK ( ) {
103+ return new Promise < PromptResult > ( ( resolve , reject ) => {
104+ 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.' ;
105+
106+ const messageOptions : vscode . MessageOptions = { modal : true } ;
107+
108+ const yesItem : PromptItem = { title : 'Get the SDK' , result : PromptResult . Yes } ;
109+ const noItem : PromptItem = { title : 'Open settings' , result : PromptResult . No , isCloseAffordance : true } ;
110+
111+ vscode . window . showErrorMessage ( message , messageOptions , noItem , yesItem )
112+ . then ( selection => resolve ( selection ?. result ?? PromptResult . Dismissed ) ) ;
113+ } ) ;
114+ }
115+
116+ async function promptToDownloadMono ( ) {
117+ return new Promise < PromptResult > ( ( resolve , reject ) => {
118+ 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.' ;
119+
120+ const messageOptions : vscode . MessageOptions = { modal : true } ;
121+
122+ const yesItem : PromptItem = { title : 'Download Mono' , result : PromptResult . Yes } ;
123+ const noItem : PromptItem = { title : 'Open settings' , result : PromptResult . No , isCloseAffordance : true } ;
124+
125+ vscode . window . showErrorMessage ( message , messageOptions , noItem , yesItem )
126+ . then ( selection => resolve ( selection ?. result ?? PromptResult . Dismissed ) ) ;
127+ } ) ;
128+ }
0 commit comments