-
Notifications
You must be signed in to change notification settings - Fork 167
Proposal for improving SDK selection with the host and admin installs #350
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
base: main
Are you sure you want to change the base?
Conversation
… the SDK selection for the host and have it work better with admin installs (especially visual Studio). Include a proposal for fast SDK version switching. Not-included is api work to share the SDK location to callers of the host/dotnetup.
|
If I understand this correctly, this environment variable is meant to allow de-coupling location of Current state: The SDK has to be in the known directory structure under that Proposal change: Optionally override the SDK location using env variable. For example, if dotnet is located at Is this correct understanding? |
|
That's a huge part of it, yeah. The thought being that if we can't always control PATH on Windows due to the choices we've made in our MSIs in the past, we can at least make the dotnet binaries that are invoked use the SDKs and Runtimes that the user intended. Then as a value-add on top of that, if the muxer also allowed for specific SDK version selection to be driven externally then you can put together a really good UX around experimenting with different SDK versions in the same workspace without having to make any permanent changes. This is something that folks struggle with today, as you have to create/update global.jsons to get the same experience. This isn't high friction, but it's also not no friction, and there's substantial prior art in other ecosystems for making it easy to switch tool chains on a temporary basis. |
| * **User Experience:** | ||
| * Detect if the global path points to `Program Files/dotnet` and the customer doesn't have the .NET 11 host which supports the SDK root feature. | ||
| * Notify the user: | ||
| > This configuration will only work in this window. Use `dotnetup use` each time you open a new command prompt. |
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.
The debugger etc still rely on the PATH so a lot of features won't work in this scenario. We explored the alternative of updating the muxer at the system hive but decided against that for concerns, such as an MSRC that could happen in a pre-release muxer (very unlikely.)
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 dotnet use will work for your window but your debugger (and potentially other scenarios not going through the CLI) will be in a bad place until net11?
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.
Right - I'd have to open my IDE/workspace in a way that gets the effects of running dotnetup (aka launch from the terminal). But users might not notice that nuance.
Won't you also need this to control the runtime selection for |
|
|
||
| ### **Behavior** | ||
|
|
||
| * If `global.json` includes an SDK path setting, **prefer that path over the environment variable**. |
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 feel like usually env vars have precedence over config files (since env vars can be set easily on the command line for one off scenarios). Is there a reason to have the precedence inverted here?
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're thinking of the most common use case being dotnetup and the global.json path is a fallback hence having the precedence flipped. @baronfel thoughts here? I think jjonescz is thinking about this from a more engineering focused position where envs usually are the overrides.
| ## **Proposal: DOTNET\_SDK\_ROOT** | ||
|
|
||
| Introduce a new environment variable: | ||
| `DOTNET_SDK_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.
It's not obvious to me what's the difference between DOTNET_SDK_ROOT and DOTNET_ROOT; could the doc perhaps explain that difference?
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.
One controls the SDK location and one controls the runtime location. DOTNET_ROOT is generally for when launching apps (with an app host presumably) and doesn't today control the SDK location. We could have it affect the SDK as well but that would be breaking hence proposing a new value. I'd have to think through whether the SDK_ROOT should affect the runtime ROOT and if there are customer scenarios who would want those different. Would a customer who's installed a user local hive want to run an app using the admin hive?
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 could have it affect the SDK as well but that would be breaking
Do we know how breaking it would be? Having a single env. variable that sets the location for both runtime and SDK would be much easier to explain.
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.
That's a good question. We'd need to understand what scenarios customers have where they are setting DOTNET_ROOT today. In particular, cases where they are setting it to a different location than their SDK and on a box where they are using their SDK.
Do we have any idea how common that is? I assume we don't have a lot of info for this so we'd be a bit blind (which is what makes me nervous about doing that). I'd be ok with one value though fwiw.
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.
@richlander @baronfel for thoughts on making DOTNET_ROOT apply to the SDK as well and if that's too risky.
For the dotnetup scenarios, we are going to be setting DOTNET_ROOT in addition to DOTNET_SDK_ROOT. For the muxer, we are proposing that the environment variable function like the global.json paths setting (with the addition of env expansion). I previously suggested having the muxer override DOTNET_ROOT for the global.json path scenario but there was pushback hence keeping two separate values. What's the behavior today if someone uses global.json paths and calls |
I believe that |
So in the case of someone using dotnetup where we've set both DOTNET_SDK_ROOT and DOTNET_ROOT, they'll get the runtime they expect. In the case where a customer sets only the SDK one themselves without going through dotnetup, they might be confused by the behavior but I think the result is ok (for the same reason that we're ok with DOTNET_ROOT not affecting the chosen sdk today). |
They will get the global runtime, they won't get the runtime that |
|
Let me try to clarify as there are a few scenarios. Kind of sounds like you're saying the current behavior for scenarios 2 and 3 as they exist today are not expected.
|
The effect of DOTNET_ROOT is very limited and makes sense in the shipping bits today. It stops making sense to me in the motivating scenario for this proposal. (Paraphrasing) The motivating scenario for this proposal is to allow one to completely relocated the .NET runtime and SDK, without touching PATH (assuming that the muxer on the PATH is recent enough). If |
|
What would happen to a loose zip file in this system if you set the environment variable at the system or user level? |
| * [.NET Environment Variables](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables) - Official documentation for .NET environment variables | ||
| * [global.json Overview](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) - Documentation for global.json configuration | ||
| * [.NET Installation Guide](https://learn.microsoft.com/en-us/dotnet/core/install/) - Official installation documentation | ||
| * [SDK Resolution in .NET](https://github.com/dotnet/designs/blob/main/accepted/2019/sdk-version-selection.md) - Design document for SDK version selection |
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.
This link 404s.
|
|
||
| ## Background | ||
|
|
||
| The .NET ecosystem has long needed better SDK selection capabilities similar to tools like `nvm` or `rustup`. Previous efforts explored this through the [dotnet bootstrapper path proposal](https://github.com/dotnet/designs/blob/a87cfdf032351fd7e7b449a11edeba1b92ba53b1/proposed/dotnet-bootstrapper/dotnet-bootstrapper-path.md), which investigated how to integrate a 'dotnet' bootstrapper with Visual Studio while managing PATH environment variable conflicts. |
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 very useful to see an in-depth appendix that demonstrates how these tools work, on both Windows and some unix (to provide sufficient comparse/contrast). Otherwise, it seems like we're designing in a bit of a vaccum.
Per offline discussion, this is the big sticking point with this proposal as the moment as we want to ensure that a customer downloading a zip independently of dotnetup can navigate to it (or add it to their path) and use it without getting super confused. The current proposal will lead to unexpected behavior in that scenario. We're exploring whether it's possible to only redirect for the centrally installed muxer (or just the program files\dotnet one on windows as windows is the most challenging to resolve). |
…n on previous alternatives that were considered. If this is still too much risk for the runtime team, we'll have to proceed with the guidance to customers modifying their profile/path.
| ### Behavior | ||
|
|
||
| * These environment variables only affect SDK loading behavior when running `dotnet` commands that require SDK resolution. | ||
| * Direct execution of applications via `dotnet foo.dll` is **not affected** to avoid impacting runtime behavior. |
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.
Isn't that a confusing behavior?
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.
This was a compromise with Andy as he didn't want to change the runtime load behavior. We're still talking with Elinor with how this might work but per my comment below, I think we're going to focus on finding a way to get feedback that is fewer long-term implications. If we get strong signal during previews, we'll revisit.
|
|
||
| * These environment variables only affect SDK loading behavior when running `dotnet` commands that require SDK resolution. | ||
| * Direct execution of applications via `dotnet foo.dll` is **not affected** to avoid impacting runtime behavior. | ||
| * If the host is launched from the source path specified in `DOTNET_ROOT_REDIRECT_SOURCES`, SDK resolution will use the path specified in `DOTNET_ROOT_REDIRECT_TARGET`. |
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 dislike CLI tools that change the behavior based on the path they are launched from. It means e.g. copying/linking the tool to some other place or launching it via an alternative path produces different results...
| * Microsoft could still modify the VS Developer Command Prompt and DevKit terminal creation to use appropriate SDK paths | ||
| * Users would be responsible for setting up their own terminal environments | ||
|
|
||
| **Issues with this approach:** |
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 is simplest solution, it has the least amount of magic, and it does not require any changes in the admin installed .NET. I have strong preference for this solution, at least as a starting point.
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.
Ultimately, the team is trying to find a point in time solution that allows us to get feedback on dotnetup on windows machines with admin installs. I think given the concerns raised from runtime folks about making permanent changes to unblock feedback on an experiment, we'll probably start with options that are more temporary in nature (like dotnetup elevating and modifying your system path or having a "dotnetup dotnet" command or one of the targeted changes for specific terminals/profiles).
I did a search on the doc and seem that The RID simplification spec I wrote is most similar to this one and could offer a guide on how to provide industry context. Searches on "rust", "python" and "manylinux" within that doc will demonstrate the research the team did to generate the design and how the final design differs from the existing SOTA in only nuanced and practical ways. The final doc documented the design in the context of that foundational and inspirational research and helped readers understand the need for the change and why we were adopting (subtly) different approaches. As the primary writer of that doc, the compare/contrast with existing solutions helped me build up confidence on the strength of our plan. At least some of the comments in the doc likely wouldn't be present in their current form if industry analysis was present. For fairness, most of our self-litigated analysis is not present in our spec, just the final derived insight. We also looked at golang and it isn't mentioned at all. If an analysis can be shared compactly like I did, that likely works well. |
|
This proposal was strictly focused on trying to enable us to get feedback from previews on machines that had Windows Admin installs and the muxer is unique enough that it may require a unique solution. I went ahead and added some compact ecosystem context to the primary document that outlines the cli-acquisition proposal here. I'm going to leave this open as we continue to have conversations but per my comment above, we have a few options that are potentially more temporary in nature to unblock feedback and we'll focus on those. We'll gather feedback on usage of dotnetup previews and use that to drive how we solve the admin problem long-term. |
Proposal for improving the SDK selection for the host and have it work better with admin installs (especially visual Studio).
Include a proposal for fast SDK version switching. Not-included is api work to share the SDK location to callers of the host/dotnetup.