Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/dnvm/PruneCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static async Task<int> Run(DnvmEnv env, Logger logger, Options options)
if (!manifest.IsSdkInstalled(sdk.Version, sdk.Dir))
{
env.Console.Warn($"SDK {sdk.Version} was not found in installed SDKs, cleaning up stale manifest entry.");
manifest = RemoveSdkFromChannels(manifest, sdk.Version);
manifest = RemoveSdkFromChannels(manifest, sdk.Version, sdk.Dir);
await @lock.WriteManifest(env, manifest);
continue;
}
Expand Down Expand Up @@ -110,18 +110,26 @@ public static async Task<int> Run(DnvmEnv env, Logger logger, Options options)
}
}

return sdksToRemove;
return sdksToRemove.Distinct().ToList();
}

/// <summary>
/// Removes an SDK version from all RegisteredChannels.InstalledSdkVersions.
/// Removes an SDK version from RegisteredChannels.InstalledSdkVersions for one SDK directory.
/// This is used to clean up stale entries left by a bug fixed in
/// https://github.com/dn-vm/dnvm/pull/274.
/// </summary>
private static Manifest RemoveSdkFromChannels(Manifest manifest, SemVersion sdkVersion)
private static Manifest RemoveSdkFromChannels(
Manifest manifest,
SemVersion sdkVersion,
SdkDirName sdkDir)
{
var updatedChannels = manifest.RegisteredChannels.Select(channel =>
{
if (channel.SdkDirName != sdkDir)
{
return channel;
}

var updatedInstalledVersions = channel.InstalledSdkVersions
.Where(version => version != sdkVersion)
.ToEq();
Expand Down
12 changes: 6 additions & 6 deletions src/dnvm/UninstallCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static async Task<int> 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;
Expand Down Expand Up @@ -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();
Expand Down
52 changes: 52 additions & 0 deletions test/UnitTests/PruneTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,58 @@ public Task MissingDirectoriesHandled() => RunWithServer(async (server, env) =>
Assert.Equal(upgradeVersion, finalManifest.InstalledSdks[0].SdkVersion);
});

[Fact]
public Task StaleCleanupDoesNotAffectOtherSdkDirectories() => RunWithServer(async (server, env) =>
{
var oldVersion = new SemVersion(8, 0, 100);
var newVersion = new SemVersion(8, 0, 101);
var defaultDir = DnvmEnv.DefaultSdkDirName;
var alternateDir = new SdkDirName("alternate");

var manifest = Manifest.Empty
.AddSdk(oldVersion, sdkDirParam: defaultDir)
.AddSdk(newVersion, sdkDirParam: defaultDir)
.AddSdk(oldVersion, sdkDirParam: alternateDir);
manifest = manifest with
{
RegisteredChannels =
[
new RegisteredChannel
{
ChannelName = new Channel.Latest(),
SdkDirName = defaultDir,
InstalledSdkVersions = [oldVersion, newVersion],
},
new RegisteredChannel
{
ChannelName = new Channel.VersionedMajorMinor(8, 0),
SdkDirName = defaultDir,
InstalledSdkVersions = [oldVersion, newVersion],
},
new RegisteredChannel
{
ChannelName = new Channel.VersionedMajorMinor(8, 0),
SdkDirName = alternateDir,
InstalledSdkVersions = [oldVersion],
},
]
};
await Manifest.WriteManifestUnsafe(env, manifest);

Assert.Equal(
[(oldVersion, defaultDir)],
PruneCommand.GetOutOfDateSdks(manifest));

Assert.Equal(0, await PruneCommand.Run(env, _logger, new PruneCommand.Options()));

var finalManifest = await Manifest.ReadManifestUnsafe(env);
Assert.Contains(finalManifest.InstalledSdks,
sdk => sdk.SdkVersion == oldVersion && sdk.SdkDirName == alternateDir);
Assert.Contains(finalManifest.RegisteredChannels,
channel => channel.SdkDirName == alternateDir
&& channel.InstalledSdkVersions.Contains(oldVersion));
});

/// <summary>
/// Tests the scenario from https://github.com/dn-vm/dnvm/issues/311:
/// Before PR #274, uninstalling an SDK removed it from InstalledSdks but not from
Expand Down
Loading