Skip to content

Commit

Permalink
Merge pull request #2121 from Nexus-Mods/wipe-completely-on-uninstall
Browse files Browse the repository at this point in the history
Improved: Additional Set of Uninstaller Improvements
  • Loading branch information
Sewer56 authored Oct 3, 2024
2 parents bd0a712 + cdf509e commit 6abc7ca
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
12 changes: 6 additions & 6 deletions src/NexusMods.App/Commandline/CleanupVerbs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ private static async Task<int> UninstallApp(
[Injected] ISettingsManager settingsManager,
[Injected] IFileSystem fileSystem)
{
// Prevent a race condition where `IRepository` is not fully done initializing.
// https://github.com/Nexus-Mods/NexusMods.App/issues/1396
Thread.Sleep(1000);

// Step 1: Revert the managed games to their original state
var db = conn.Db;
var managedInstallations = Loadout.All(db)
Expand Down Expand Up @@ -91,11 +87,14 @@ are other than {##}. Resolving these on our end would be hard.
// switching backends out. At that point you'd add others here too.
JsonStorageBackend.GetConfigsFolderPath(fileSystem),

// The whole base DataModel folder.
// The DataModel folder.
DataModelSettings.GetStandardDataModelFolder(fileSystem),

// The whole base Download folder.
DownloadSettings.GetStandardDownloadsFolder(fileSystem),

// Local Application Data (where all app files default to).
DataModelSettings.GetLocalApplicationDataDirectory(fileSystem),
}.Concat(dataModelSettings.ArchiveLocations.Select(path => path.ToPath(fileSystem)));

if (fileSystem.OS.IsUnix())
Expand Down Expand Up @@ -135,8 +134,9 @@ private static async Task DeleteRemainingFilesWindows(AbsolutePath[] appFiles, I
var scriptPath = Path.Combine(AppContext.BaseDirectory, "uninstall-helper.ps1");

// Execute the PowerShell script
var args = $"-ExecutionPolicy Bypass -Command \"& \'{scriptPath}\' -FilesToDeletePath \'{filesToDeletePath}\' -DirectoriesToDeletePath \'{directoriesToDeletePath}\'\"";
await Cli.Wrap("powershell")
.WithArguments($"-ExecutionPolicy Bypass -Command \"& \"{scriptPath}\" -FilesToDeletePath \"{filesToDeletePath}\" -DirectoriesToDeletePath \"{directoriesToDeletePath}\"\"")
.WithArguments(args)
.ExecuteAsync();

// Clean up the temporary files
Expand Down
50 changes: 34 additions & 16 deletions src/NexusMods.DataModel/DataModelSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace NexusMods.DataModel;
[PublicAPI]
public record DataModelSettings : ISettings
{
private const string DataModelFolderName = "DataModel";

/// <summary>
/// If true, data model will be stored in memory only and the paths will be ignored.
/// </summary>
Expand Down Expand Up @@ -40,38 +42,54 @@ public static ISettingsBuilder Configure(ISettingsBuilder settingsBuilder)
public static DataModelSettings CreateDefault(IServiceProvider serviceProvider)
{
var os = serviceProvider.GetRequiredService<IFileSystem>().OS;
var baseKnownPath = GetStandardDataModelPaths(os, out var baseDirectoryName);
var baseKnownPath = GetLocalApplicationDataDirectory(os, out var baseDirectoryName);

return new DataModelSettings
{
MnemonicDBPath = new ConfigurablePath(baseKnownPath, $"{baseDirectoryName}/MnemonicDB.rocksdb"),
MnemonicDBPath = new ConfigurablePath(baseKnownPath, $"{baseDirectoryName}/{DataModelFolderName}/MnemonicDB.rocksdb"),
ArchiveLocations = [
new ConfigurablePath(baseKnownPath, $"{baseDirectoryName}/Archives"),
new ConfigurablePath(baseKnownPath, $"{baseDirectoryName}/{DataModelFolderName}/Archives"),
],
};
}

private static KnownPath GetStandardDataModelPaths(IOSInformation os, out string baseDirectoryName)
/// <summary>
/// Retrieves the base directory where the App stores its local application data.
/// </summary>
/// <returns>The absolute path to the local application data directory.</returns>
public static AbsolutePath GetLocalApplicationDataDirectory(IFileSystem fs)
{
var baseKnownPath = os.MatchPlatform(
onWindows: () => KnownPath.LocalApplicationDataDirectory,
onLinux: () => KnownPath.XDG_DATA_HOME,
onOSX: () => KnownPath.LocalApplicationDataDirectory
);

// NOTE: OSX ".App" is apparently special, using _ instead of . to prevent weirdness
baseDirectoryName = os.IsOSX ? "NexusMods_App/DataModel" : "NexusMods.App/DataModel";
return baseKnownPath;
var basePath = GetLocalApplicationDataDirectory(fs.OS, out var relativePath);
return fs.GetKnownPath(basePath).Combine(relativePath);
}

/// <summary>
/// Retrieves the default DataModel folder.
/// This folder is reserved for the App and should not store user info.
/// </summary>
public static AbsolutePath GetStandardDataModelFolder(IFileSystem fs)
{
var os = fs.OS;
var baseKnownPath = GetStandardDataModelPaths(os, out var baseDirectoryName);
return fs.GetKnownPath(baseKnownPath).Combine(baseDirectoryName);
var baseKnownPath = GetLocalApplicationDataDirectory(os, out var baseDirectoryName);
return fs.GetKnownPath(baseKnownPath).Combine(baseDirectoryName).Combine(DataModelFolderName);
}

/// <summary>
/// Retrieves the base directory where the App stores its local application data.
/// </summary>
/// <param name="os">OS Information.</param>
/// <param name="baseDirectoryName">Relative path to the returned <see cref="KnownPath"/>.</param>
/// <returns></returns>
private static KnownPath GetLocalApplicationDataDirectory(IOSInformation os, out string baseDirectoryName)
{
var baseKnownPath = os.MatchPlatform(
onWindows: () => KnownPath.LocalApplicationDataDirectory,
onLinux: () => KnownPath.XDG_DATA_HOME,
onOSX: () => KnownPath.LocalApplicationDataDirectory
);

// NOTE: OSX ".App" is apparently special, using _ instead of . to prevent weirdness
baseDirectoryName = os.IsOSX ? "NexusMods_App" : "NexusMods.App";
return baseKnownPath;
}
}

0 comments on commit 6abc7ca

Please sign in to comment.