Add dotnetup "happy path" design proposal - #372
Conversation
Proposes how dotnetup makes its managed hive win for SDK and runtime resolution: a near-term change to `everywhere` mode that prepends the dotnetup dotnet directory before the Program Files entry on the system PATH, and a longer-term user-scoped, source-gated muxer redirect that relocates both SDK and runtime (including `dotnet foo.dll`). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f118977e-1e71-40b0-8045-10f5ab006715
| - Make the `dotnetup`-managed hive the SDK that wins for CLI and tools, reliably, after a | ||
| simple `dotnetup` action. |
There was a problem hiding this comment.
We should make sure this is:
- clearly messaged during
dotnetupinstall and in any docs - surfaced (with pointers to resolution if possible) in non-happy-path cases - for example, I have some repo that uses local sdk paths, I try dotnetup at some point, later I go back to my repo and it no longer finds the sdk required
- indicated in general diagnostic info like
dotnet --info
Basically, the happy-path requires everything being on-boarded to dotnetup, so I want to make sure we are intentional about the experience in the non-happy-path / transition.
There was a problem hiding this comment.
We would want local repo paths to continue to work. The sdk.paths feature should continue to work (and override or be applied after the environment-variable based redirect). Putting a specific version of dotnet on the path shouldi also work as long as we include the "REDIRECT_SOURCE" type environment variable.
It would be good for dotnet --info to include information about the redirection if it applied.
|
|
||
| ## Relationship to existing mechanisms | ||
|
|
||
| - **`global.json` `sdk.paths` / `$host$`** |
There was a problem hiding this comment.
Does this mean that the environment variable basically replaces sdk.paths, but everything else in the global.json is respected?
There was a problem hiding this comment.
We'd like sdk.paths and everything else in global.json to continue to work. The behavior we'd like is that everything would work the same as if C:\Program Files\dotnet was not on the PATH, and instead the folder specified by the redirect (such as C:\Users\daplaist\AppData\Local\dotnet) were on the PATH instead.
There was a problem hiding this comment.
as if C:\Program Files\dotnet was not on the PATH, and instead the folder specified by the redirect (such as C:\Users\daplaist\AppData\Local\dotnet) were on the PATH instead.
So as if it was actually C:\Users\daplaist\AppData\Local\dotnet that was launched? In my mind that means:
- global.json without
sdk.paths: only look in the redirect folder, respecting everything in global.json- this means that if the global.json specifies an sdk version that is not in the redirect (but is in the global install), the resolution would fail
- global.json with
sdk.paths: redirect folder replaces$host$insdk.paths, if$host$is not listed insdk.pathswe won't look in the redirect - no global.json: only look in redirect folder, use latest sdk found
Does that match your thinking?
SDK/runtime resolution can be confusing enough - I want to make sure we're very explicit about how anything we add interacts with existing features, where it sits in the resolution logic, and if/how much it adds to the complexity.
| `PATH`, `dotnetup` today *removes* that entry. This proposal changes that to a durable prepend: | ||
|
|
||
| 1. Elevate once (the same elevation `dotnetup` already uses to edit the machine-wide `PATH`). | ||
| 2. **Insert the `dotnetup` dotnet directory into the system `PATH` immediately before the |
There was a problem hiding this comment.
Does dotnetup do multi-arch today or only the OS architecture?
There was a problem hiding this comment.
We don't do multi-arch today but we should think about how the redirect support would interact with multi-arch. I'm not sure if it would, you can't have two different architectures of dotnet on the PATH (or you can, but it doesn't matter since only the first one will apply).
| Concretely, the muxer would support the following environment variables: | ||
|
|
||
| - `DOTNET_ROOT_REDIRECT_TARGET` - The path of the hive to redirect to | ||
| - `DOTNET_ROOT_REDIRECT_SOURCES` - A list of sources to redirect from. This allows the redirect to be restricted to the Program Files muxer, so that other muxers (such as from an unzipped runtime/SDK) are not affected |
There was a problem hiding this comment.
Is this list of sources expected to be something that changes much? Would it be anything other than the global install?
General concern around the source path matching:
- I assume this would require some sort of canonicalization given the myriad of ways the same path can be specified.
- different behaviour based on where an install (that is otherwise xcopy-able) is located seems rather confusing.
(I don't have a good solution - just calling it out)
There was a problem hiding this comment.
We would expect to only set it to the global install. So theoretically we could have the muxer check its install location to determine whether to apply the redirect without the second environment variable. But it seems probably better (and more testable) to use an environment variable.
There was a problem hiding this comment.
I wonder if something like a marker file next to dotnet that indicates enabling redirection and is only included in the installation bundle (and not the archives) would make sense. It would avoid path matching. Different acquisition methods would still have different behaviour (when dotnetup has been in play), but it wouldn't change on xcopy to another location.
| - **Non-Windows.** The goals are the same on macOS/Linux, but this proposal focuses on the | ||
| Windows solution (likely the hardest). Phase 1 is Windows-specific and likely doesn't apply; | ||
| Phase 2's redirect may or may not be the right approach there. The cross-platform design | ||
| remains to be worked out. |
There was a problem hiding this comment.
I'd rather consider this for all platforms (even if Windows is the motivating one).
There was a problem hiding this comment.
Updated this to try to make clear that the muxer feature should apply to all platforms.
| access it, so they fall through to the machine-wide install — but an elevated process (or an account such as SYSTEM) | ||
| may resolve `dotnet` from that hive, so the wrong user's install can win. This "multi-user oddness" | ||
| (accepted for the near term) is why Phase 1 is a bridge; Phase 2 (per-user, no system `PATH` | ||
| change) removes it. |
There was a problem hiding this comment.
removes it
Does that mean a one-time elevation as well?
There was a problem hiding this comment.
Phase 2 would have probably include a one-time elevation to install the updated muxer, if it wasn't already installed in Program Files.
|
cc @richlander |
Proposes how dotnetup makes its managed hive win for SDK and runtime resolution: a near-term change to
everywheremode that prepends the dotnetup dotnet directory before the Program Files entry on the system PATH, and a longer-term user-scoped, source-gated muxer redirect that relocates both SDK and runtime (includingdotnet foo.dll).