From 801eaa70871a9ca86dab8022abfd87d558fa1db3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 10 Feb 2020 19:14:06 -0500 Subject: improve save backup logic --- src/SMAPI.Mods.SaveBackup/ModEntry.cs | 46 ++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'src/SMAPI.Mods.SaveBackup/ModEntry.cs') diff --git a/src/SMAPI.Mods.SaveBackup/ModEntry.cs b/src/SMAPI.Mods.SaveBackup/ModEntry.cs index 8b139d8f..b8d3be1c 100644 --- a/src/SMAPI.Mods.SaveBackup/ModEntry.cs +++ b/src/SMAPI.Mods.SaveBackup/ModEntry.cs @@ -66,29 +66,37 @@ namespace StardewModdingAPI.Mods.SaveBackup FileInfo targetFile = new FileInfo(Path.Combine(backupFolder.FullName, this.FileName)); DirectoryInfo fallbackDir = new DirectoryInfo(Path.Combine(backupFolder.FullName, this.BackupLabel)); if (targetFile.Exists || fallbackDir.Exists) + { + this.Monitor.Log("Already backed up today."); return; + } // copy saves to fallback directory (ignore non-save files/folders) - this.Monitor.Log($"Backing up saves to {fallbackDir.FullName}...", LogLevel.Trace); DirectoryInfo savesDir = new DirectoryInfo(Constants.SavesPath); - this.RecursiveCopy(savesDir, fallbackDir, entry => this.MatchSaveFolders(savesDir, entry), copyRoot: false); + if (!this.RecursiveCopy(savesDir, fallbackDir, entry => this.MatchSaveFolders(savesDir, entry), copyRoot: false)) + { + this.Monitor.Log("No saves found."); + return; + } // compress backup if possible - this.Monitor.Log("Compressing backup if possible...", LogLevel.Trace); if (!this.TryCompress(fallbackDir.FullName, targetFile, out Exception compressError)) { - if (Constants.TargetPlatform != GamePlatform.Android) // expected to fail on Android - this.Monitor.Log($"Couldn't compress backup, leaving it uncompressed.\n{compressError}", LogLevel.Trace); + this.Monitor.Log(Constants.TargetPlatform != GamePlatform.Android + ? $"Backed up to {fallbackDir.FullName}." // expected to fail on Android + : $"Backed up to {fallbackDir.FullName}. Couldn't compress backup:\n{compressError}" + ); } else + { + this.Monitor.Log($"Backed up to {targetFile.FullName}."); fallbackDir.Delete(recursive: true); - - this.Monitor.Log("Backup done!", LogLevel.Trace); + } } catch (Exception ex) { - this.Monitor.Log("Couldn't back up save files (see log file for details).", LogLevel.Warn); - this.Monitor.Log(ex.ToString(), LogLevel.Trace); + this.Monitor.Log("Couldn't back up saves (see log file for details).", LogLevel.Warn); + this.Monitor.Log(ex.ToString()); } } @@ -108,7 +116,7 @@ namespace StardewModdingAPI.Mods.SaveBackup { try { - this.Monitor.Log($"Deleting {entry.Name}...", LogLevel.Trace); + this.Monitor.Log($"Deleting {entry.Name}..."); if (entry is DirectoryInfo folder) folder.Delete(recursive: true); else @@ -123,7 +131,7 @@ namespace StardewModdingAPI.Mods.SaveBackup catch (Exception ex) { this.Monitor.Log("Couldn't remove old backups (see log file for details).", LogLevel.Warn); - this.Monitor.Log(ex.ToString(), LogLevel.Trace); + this.Monitor.Log(ex.ToString()); } } @@ -199,29 +207,33 @@ namespace StardewModdingAPI.Mods.SaveBackup /// Whether to copy the root folder itself, or false to only copy its contents. /// A filter which matches the files or directories to copy, or null to copy everything. /// Derived from the SMAPI installer code. - private void RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder, Func filter, bool copyRoot = true) + /// Returns whether any files were copied. + private bool RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder, Func filter, bool copyRoot = true) { - if (!targetFolder.Exists) - targetFolder.Create(); + if (!source.Exists || filter?.Invoke(source) == false) + return false; - if (filter?.Invoke(source) == false) - return; + bool anyCopied = false; switch (source) { case FileInfo sourceFile: + targetFolder.Create(); sourceFile.CopyTo(Path.Combine(targetFolder.FullName, sourceFile.Name)); + anyCopied = true; break; case DirectoryInfo sourceDir: DirectoryInfo targetSubfolder = copyRoot ? new DirectoryInfo(Path.Combine(targetFolder.FullName, sourceDir.Name)) : targetFolder; foreach (var entry in sourceDir.EnumerateFileSystemInfos()) - this.RecursiveCopy(entry, targetSubfolder, filter); + anyCopied = this.RecursiveCopy(entry, targetSubfolder, filter) || anyCopied; break; default: throw new NotSupportedException($"Unknown filesystem info type '{source.GetType().FullName}'."); } + + return anyCopied; } /// A copy filter which matches save folders. -- cgit