mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 16:29:58 +09:00
Allow game folder migration to fail gracefully when cleanup cannot completely succeed
This commit is contained in:
@ -33,7 +33,8 @@ namespace osu.Game.IO
|
||||
/// A general purpose migration method to move the storage to a different location.
|
||||
/// <param name="newStorage">The target storage of the migration.</param>
|
||||
/// </summary>
|
||||
public virtual void Migrate(Storage newStorage)
|
||||
/// <returns>Whether cleanup could complete.</returns>
|
||||
public virtual bool Migrate(Storage newStorage)
|
||||
{
|
||||
var source = new DirectoryInfo(GetFullPath("."));
|
||||
var destination = new DirectoryInfo(newStorage.GetFullPath("."));
|
||||
@ -57,17 +58,20 @@ namespace osu.Game.IO
|
||||
|
||||
CopyRecursive(source, destination);
|
||||
ChangeTargetStorage(newStorage);
|
||||
DeleteRecursive(source);
|
||||
|
||||
return DeleteRecursive(source);
|
||||
}
|
||||
|
||||
protected void DeleteRecursive(DirectoryInfo target, bool topLevelExcludes = true)
|
||||
protected bool DeleteRecursive(DirectoryInfo target, bool topLevelExcludes = true)
|
||||
{
|
||||
bool allFilesDeleted = true;
|
||||
|
||||
foreach (System.IO.FileInfo fi in target.GetFiles())
|
||||
{
|
||||
if (topLevelExcludes && IgnoreFiles.Contains(fi.Name))
|
||||
continue;
|
||||
|
||||
AttemptOperation(() => fi.Delete());
|
||||
allFilesDeleted &= AttemptOperation(() => fi.Delete(), throwOnFailure: false);
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo dir in target.GetDirectories())
|
||||
@ -75,11 +79,13 @@ namespace osu.Game.IO
|
||||
if (topLevelExcludes && IgnoreDirectories.Contains(dir.Name))
|
||||
continue;
|
||||
|
||||
AttemptOperation(() => dir.Delete(true));
|
||||
allFilesDeleted &= AttemptOperation(() => dir.Delete(true), throwOnFailure: false);
|
||||
}
|
||||
|
||||
if (target.GetFiles().Length == 0 && target.GetDirectories().Length == 0)
|
||||
AttemptOperation(target.Delete);
|
||||
allFilesDeleted &= AttemptOperation(target.Delete, throwOnFailure: false);
|
||||
|
||||
return allFilesDeleted;
|
||||
}
|
||||
|
||||
protected void CopyRecursive(DirectoryInfo source, DirectoryInfo destination, bool topLevelExcludes = true)
|
||||
@ -110,19 +116,25 @@ namespace osu.Game.IO
|
||||
/// </summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
/// <param name="attempts">The number of attempts (250ms wait between each).</param>
|
||||
protected static void AttemptOperation(Action action, int attempts = 10)
|
||||
/// <param name="throwOnFailure">Whether to throw an exception on failure. If <c>false</c>, will silently fail.</param>
|
||||
protected static bool AttemptOperation(Action action, int attempts = 10, bool throwOnFailure = true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (attempts-- == 0)
|
||||
throw;
|
||||
{
|
||||
if (throwOnFailure)
|
||||
throw;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(250);
|
||||
|
Reference in New Issue
Block a user