-
Notifications
You must be signed in to change notification settings - Fork 676
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
Check DotnetRuntimeExtensionResolver for DOTNET_ROOT #6567
base: main
Are you sure you want to change the base?
Conversation
This PR adds in a check to obtain the DOTNET_ROOT from DotnetRuntimeExtensionResolver. The future work for this would be a global API from the runtime acquisition and centralize how C# Extension would obtain the dotnet cli path and we can remove the getDotNetInfo utils methods.
@@ -278,6 +281,14 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip | |||
// use the executable specified in the package.json if it exists or determine it based on some other information (e.g. the session) | |||
if (!executable) { | |||
const dotNetInfo = await getDotnetInfo(omnisharpOptions.dotNetCliPaths); | |||
const hostExecutableResolver = new DotnetRuntimeExtensionResolver( |
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.
Note - this currently only cares about the installed runtimes. It does not confirm there is an SDK. It will also only install a 7.0 runtime. Is that what you expect?
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.
I think this is the best we have for now until the .NET SDK installation API is avaliable to use.
This is to just workaround the scenario where dotnet exists in the PATH and we can hope there is an SDK.
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.
Do you require a .net 7 SDK or higher? Or can you use a .net 6 SDK? Because if oyu only have a .net 6 SDK installed on the path, this will return a locally installed .net 7 runtime (with no SDK information, you won't be able to see the .net 6 SDK from it)
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.
What Andrew is trying to do is find a version of .NET for the target app. The debugger itself will ignore DOTNET_ROOT
and run on its own runtime.
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.
It would be whatever the user's target framework would be.
The scenario is that the user was able to build their application with dotnet build
and I was hoping this API would help me grab the dotnet install path to set as DOTNET_ROOT.
E.g. ~/.dotnet
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.
So if the user's app targets .net6 and they only have .net6 SDK installed, this API will not return the path to the dotnet 6 installation. It will return a locally installed .net7 runtime path. Just want to make sure you know what to expect from this API.
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.
See https://github.com/dotnet/vscode-csharp/pull/6567/files#r1364688699
Maybe instead what should happen is getDotnetInfo
should return the real CLI path and the set of SDKs that are installed at that path (via dotnet --list-sdks
) - and then you use that.
Because DotnetRuntimeExtensionResolver
is really focused on making sure the runtime to host the server processes is available.
if (!dotnetRoot) { | ||
if (dotNetInfo.CliPath) { | ||
dotnetRoot = path.dirname(dotNetInfo.CliPath); | ||
} else if (hostExecutableInfo.path) { |
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.
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.
If the architecture of the debugger != the architecture of this runtime, we don't want to use it
We might need to re-write getHostExecutableInfo to get the correct architecture. Is it worth it when we will be throwing away this code for the NET SDK installation API?
If there already is a global .NET runtime, we don't want to use it
Whats the best way to check for this? I thought this was covered with process.env.DOTNET_ROOT
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.
We might need to re-write getHostExecutableInfo to get the correct architecture.
I think you just want to ignore it/not compute it if we are trying to get a different architecture. In other words, if you want to target x64
, but you are on an ARM64 mac, you need to download the the .NET Runtime yourself
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.
Whats the best way to check for this? I thought this was covered with process.env.DOTNET_ROOT
Normally we wouldn't use DOTNET_ROOT
if there was a globally installed .NET SDK. I would think you would want to exec dotnet --version
and if that succeeded: we use the global version.
@@ -278,6 +281,14 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip | |||
// use the executable specified in the package.json if it exists or determine it based on some other information (e.g. the session) | |||
if (!executable) { | |||
const dotNetInfo = await getDotnetInfo(omnisharpOptions.dotNetCliPaths); | |||
const hostExecutableResolver = new DotnetRuntimeExtensionResolver( | |||
this.platformInfo, | |||
() => _session?.configuration?.executable, |
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.
() => _session?.configuration?.executable, | |
() => _session?.configuration?.program |
Andrew, do you know how this is supposed to work? Do you know if there is some documentation? A few specific questions:
|
// Look to see if DOTNET_ROOT is set, then use dotnet cli path for omnisharp, then hostExecutableInfo | ||
let dotnetRoot: string | undefined = process.env.DOTNET_ROOT; | ||
if (!dotnetRoot) { | ||
if (dotNetInfo.CliPath) { |
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.
Be careful with the clipath here - I believe it comes from here - https://github.com/dotnet/vscode-csharp/blob/main/src/shared/utils/getDotnetInfo.ts#L22
which will return 'dotnet.exe' unless you pass in explicit CLI paths to getDotnetInfo
- it looks like you pass in the clipaths option, so I think it will only return a real path if that option has a value.
IMHO getDotnetInfo
should probably actually return the real dotnet installation exe path in all cases, but I've been afraid of making that change (not sure what else will break 😆 )
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.
Yeah. This normally worked with omnisharp beacuse I think they set the clipaths but this changed when it was all moved to roslyn.
|
Broadly speaking, I think there are two ways that we could solve the problem of acquiring a .NET SDK and/or Runtime for the app to use, and I don't know what one was selected -- Option 1: VS Code extension(s) install the .NET SDK and/or Runtime(s) that we think users are most likely to target This is obviously what VS does, though VS installs the SDK globally. I don't entirely understand the VS behavior, and how similar it is to the VS Code behavior -- if VS switches from installing say, .NET 6 to .NET 7, does it remove .NET 6? Will this work with the way VS Code is installing them? In an ideal world, under this option, I think the debugger should really be doing nothing. Otherwise, one can F5/Ctrl-F5 from VS code, but if one just opens a terminal, the app will no longer run. At the very least, I think we need documentation somewhere for what a user should do. Option 2: User should be guided to install the .NET Runtime and/or SDK the "normal way" In this option, we add some basic detection for understanding if there is a .NET runtime installed, and if that fails, we point them at instructions on how to install the runtime or SDK themselves. The nice thing about this is that the user is in charge of picking the right SDK/runtime, as there are many options and the one we pick may not be right for the user. |
I can explain the current expectations from the language server / project side. Note that there are two distinct parts -
However this may be changing once the .net runtime acquisition extension supports acquiring SDKs. I'm not 100% sure what the plans are there (I haven't seen the latest details). |
We are releasing the API to acquire a Global .NET SDK using the '.NET Runtime Install Tool', which will become the '.NET Install Tool' by the end of next week. C#/CDK will be able to call into that API to have us acquire a .NET SDK (versioned like so: 'major' like '6', major.minor like '3.1', feature band, such as '7.0.3xx' or specified version, like '7.0.103'. Work is starting on CDK side to consume this new API and add a UI layer. |
I think it would be best to hold off on these changes and utilize omnisharpOptions.dotNetCliPath for folks who do not install dotnet globally. |
This PR adds in a check to obtain the DOTNET_ROOT from DotnetRuntimeExtensionResolver.
This should be using the same dotnet as the roslyn LSP.
The future work for this would be a global API from the runtime acquisition and centralize how C# Extension would obtain the dotnet cli path and we can remove the getDotNetInfo utils methods.