dotnetup uninstall matches specifications before refreshing changed global.json records
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 1.3k
- PR merge metrics
- PR metrics pending
Description
### Description
`dotnetup sdk uninstall` selects matching install specifications before garbage collection refreshes GlobalJson-sourced specifications. This means uninstall makes its decision using stale manifest data and then garbage collection can change the tracked-channel list after that decision.
Before uninstall time, refresh and consolidate elegacy global json records before selecting matching specs.
The current ordering:
- match an uninstall target -> remove records -> refresh remaining records -> gc
It should instead be
- refresh -> consolidate and deduplicate global json entries -> find all matching independent specs -> remove all matching records -> gc
DotnetRootEntry deduplication should compare component, version/channel for explicit, and component + normalized global json path for global json based specs.
# AI context
The current effective ordering is:
1. Match the requested uninstall target against stored specifications.
2. Remove matching records.
3. Run garbage collection.
4. During garbage collection, reread tracked `global.json` files and update their derived channels.
If historical records exist for a changed `global.json`, the first uninstall may remove only the record already containing the requested value. Garbage collection then rewrites the remaining records to the current value, so the requested SDK remains referenced and a second identical uninstall is required.
### Example behavior
A user ran:
```console
dotnetup uninstall 11.0.100-preview.6.26359.118 --source all
```
The first invocation dereferenced one GlobalJson record. Immediately afterward, `dotnetup list` showed three identical records for the same Roslyn `global.json`. A second invocation dereferenced all three and removed the SDK.
This is consistent with stale records being refreshed only after uninstall matching.
### Proposed behavior
Before selecting uninstall matches:
1. Refresh GlobalJson specifications from their files.
2. Consolidate records sharing the same durable GlobalJson identity.
3. Find all matching independent specifications using the requested source filter.
4. Remove all matching records.
5. Run garbage collection.
Install should prevent duplicate identities from being created, while uninstall and garbage collection should repair legacy manifests defensively.
Multiple records may still legitimately be removed when different GlobalJson paths or sources independently match the requested value. Records for one GlobalJson path should first be treated as one logical requirement.
### Acceptance criteria
- Uninstall does not require a second identical invocation after GlobalJson records are refreshed.
- The tracked-channel list does not gain duplicate entries as a side effect of uninstall.
- All independently matching specifications are removed.
- Broader or otherwise nonmatching specifications are preserved and may continue retaining the installed SDK.
Related: #55312 and #56225.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.