diff --git a/src/dnvm/UninstallCommand.cs b/src/dnvm/UninstallCommand.cs index fbe1762..61641da 100644 --- a/src/dnvm/UninstallCommand.cs +++ b/src/dnvm/UninstallCommand.cs @@ -71,7 +71,7 @@ public static async Task Run(ManifestLock @lock, DnvmEnv env, Logger logger DeleteAspnets(env, aspnetToRemove, logger); DeleteWins(env, winToRemove, logger); - manifest = UninstallSdk(manifest, sdkVersion); + manifest = UninstallSdks(manifest, sdksToRemove); await @lock.WriteManifest(env, manifest); return 0; @@ -137,18 +137,18 @@ private static void DeleteWins(DnvmEnv env, IEnumerable<(SemVersion, SdkDirName) } } - private static Manifest UninstallSdk(Manifest manifest, SemVersion sdkVersion) + private static Manifest UninstallSdks( + Manifest manifest, + HashSet<(SemVersion Version, SdkDirName Dir)> sdksToRemove) { - // Delete SDK version from all directories var newVersions = manifest.InstalledSdks - .Where(sdk => sdk.SdkVersion != sdkVersion) + .Where(sdk => !sdksToRemove.Contains((sdk.SdkVersion, sdk.SdkDirName))) .ToEq(); - // Also remove the SDK version from RegisteredChannels.InstalledSdkVersions var updatedChannels = manifest.RegisteredChannels.Select(channel => { var updatedInstalledVersions = channel.InstalledSdkVersions - .Where(version => version != sdkVersion) + .Where(version => !sdksToRemove.Contains((version, channel.SdkDirName))) .ToEq(); return channel with { InstalledSdkVersions = updatedInstalledVersions }; }).ToEq(); diff --git a/test/UnitTests/UninstallTests.cs b/test/UnitTests/UninstallTests.cs index 89e2de0..8ae5766 100644 --- a/test/UnitTests/UninstallTests.cs +++ b/test/UnitTests/UninstallTests.cs @@ -55,6 +55,87 @@ public Task LtsAndPreview() => RunWithServer(async (server, env) => Assert.True(env.DnvmHomeFs.DirectoryExists(UPath.Root / "preview" / "templates" / previewVersion.ToString())); }); + [Fact] + public Task DirectorySpecificUninstallKeepsOtherCopy() => RunWithServer(async (server, env) => + { + var version = new SemVersion(8, 0, 100); + var defaultDir = DnvmEnv.DefaultSdkDirName; + var alternateDir = new SdkDirName("alternate"); + var manifest = Manifest.Empty + .AddSdk(version, sdkDirParam: defaultDir) + .AddSdk(version, sdkDirParam: alternateDir); + manifest = manifest with + { + RegisteredChannels = + [ + new RegisteredChannel + { + ChannelName = new Channel.Latest(), + SdkDirName = defaultDir, + InstalledSdkVersions = [version], + }, + new RegisteredChannel + { + ChannelName = new Channel.VersionedMajorMinor(8, 0), + SdkDirName = alternateDir, + InstalledSdkVersions = [version], + }, + ] + }; + await Manifest.WriteManifestUnsafe(env, manifest); + + Assert.Equal(0, await UninstallCommand.Run(env, _logger, version, alternateDir)); + + var finalManifest = await Manifest.ReadManifestUnsafe(env); + Assert.Contains(finalManifest.InstalledSdks, + sdk => sdk.SdkVersion == version && sdk.SdkDirName == defaultDir); + Assert.DoesNotContain(finalManifest.InstalledSdks, + sdk => sdk.SdkVersion == version && sdk.SdkDirName == alternateDir); + Assert.Contains(finalManifest.RegisteredChannels, + channel => channel.SdkDirName == defaultDir + && channel.InstalledSdkVersions.Contains(version)); + Assert.Contains(finalManifest.RegisteredChannels, + channel => channel.SdkDirName == alternateDir + && !channel.InstalledSdkVersions.Contains(version)); + }); + + [Fact] + public Task UninstallWithoutDirectoryRemovesAllCopies() => RunWithServer(async (server, env) => + { + var version = new SemVersion(8, 0, 100); + var defaultDir = DnvmEnv.DefaultSdkDirName; + var alternateDir = new SdkDirName("alternate"); + var manifest = Manifest.Empty + .AddSdk(version, sdkDirParam: defaultDir) + .AddSdk(version, sdkDirParam: alternateDir); + manifest = manifest with + { + RegisteredChannels = + [ + new RegisteredChannel + { + ChannelName = new Channel.Latest(), + SdkDirName = defaultDir, + InstalledSdkVersions = [version], + }, + new RegisteredChannel + { + ChannelName = new Channel.VersionedMajorMinor(8, 0), + SdkDirName = alternateDir, + InstalledSdkVersions = [version], + }, + ] + }; + await Manifest.WriteManifestUnsafe(env, manifest); + + Assert.Equal(0, await UninstallCommand.Run(env, _logger, version)); + + var finalManifest = await Manifest.ReadManifestUnsafe(env); + Assert.DoesNotContain(finalManifest.InstalledSdks, sdk => sdk.SdkVersion == version); + Assert.All(finalManifest.RegisteredChannels, + channel => Assert.DoesNotContain(version, channel.InstalledSdkVersions)); + }); + [Fact] public Task UninstallMessage() => RunWithServer(async (server, env) => {