You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.9 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. namespace IPA.Patcher
  8. {
  9. /// <summary>
  10. /// A unit for backup. WIP.
  11. /// </summary>
  12. public class BackupUnit
  13. {
  14. public string Name { get; private set; }
  15. private DirectoryInfo _BackupPath;
  16. private PatchContext _Context;
  17. private List<string> _Files = new List<string>();
  18. private FileInfo _ManifestFile;
  19. private static string _ManifestFileName = "$manifest$.txt";
  20. public BackupUnit(PatchContext context) : this(context, DateTime.Now.ToString("yyyy-MM-dd_h-mm-ss"))
  21. {
  22. }
  23. private BackupUnit(PatchContext context, string name)
  24. {
  25. Name = name;
  26. _Context = context;
  27. _BackupPath = new DirectoryInfo(Path.Combine(_Context.BackupPath, Name));
  28. _ManifestFile = new FileInfo(Path.Combine(_BackupPath.FullName, _ManifestFileName));
  29. }
  30. public static BackupUnit FromDirectory(DirectoryInfo directory, PatchContext context)
  31. {
  32. var unit = new BackupUnit(context, directory.Name);
  33. // Read Manifest
  34. if (unit._ManifestFile.Exists)
  35. {
  36. string manifest = File.ReadAllText(unit._ManifestFile.FullName);
  37. foreach (var line in manifest.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
  38. unit._Files.Add(line);
  39. }
  40. else
  41. {
  42. foreach (var file in directory.GetFiles("*", SearchOption.AllDirectories))
  43. {
  44. if (file.Name == _ManifestFileName) continue;
  45. var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
  46. unit._Files.Add(relativePath);
  47. }
  48. }
  49. return unit;
  50. }
  51. public void Add(string file)
  52. {
  53. Add(new FileInfo(file));
  54. }
  55. internal void Delete()
  56. {
  57. _BackupPath.Delete(true);
  58. }
  59. /// <summary>
  60. /// Adds a file to the list of changed files and backups it.
  61. /// </summary>
  62. /// <param name="path"></param>
  63. public void Add(FileInfo file)
  64. {
  65. if(!file.FullName.StartsWith(_Context.ProjectRoot))
  66. {
  67. Console.Error.WriteLine("Invalid file path for backup! {0}", file);
  68. return;
  69. }
  70. var relativePath = file.FullName.Substring(_Context.ProjectRoot.Length + 1);
  71. var backupPath = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath));
  72. if(_Files.Contains(relativePath))
  73. {
  74. Console.WriteLine("Skipping backup of {0}", relativePath);
  75. return;
  76. }
  77. // Copy over
  78. backupPath.Directory.Create();
  79. if (file.Exists)
  80. {
  81. file.CopyTo(backupPath.FullName);
  82. }
  83. else
  84. {
  85. // Make empty file
  86. backupPath.Create().Close();
  87. }
  88. if (!File.Exists(_ManifestFile.FullName))
  89. _ManifestFile.Create().Close();
  90. var stream = _ManifestFile.AppendText();
  91. stream.WriteLine(relativePath);
  92. stream.Close();
  93. // Add to list
  94. _Files.Add(relativePath);
  95. }
  96. /// <summary>
  97. /// Reverts the changes made in this unit.
  98. /// </summary>
  99. public void Restore()
  100. {
  101. foreach(var relativePath in _Files)
  102. {
  103. Console.WriteLine("Restoring {0}", relativePath);
  104. // Original version
  105. var backupFile = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath));
  106. var target = new FileInfo(Path.Combine(_Context.ProjectRoot, relativePath));
  107. if (backupFile.Exists)
  108. {
  109. if (backupFile.Length > 0)
  110. {
  111. Console.WriteLine(" {0} => {1}", backupFile.FullName, target.FullName);
  112. target.Directory.Create();
  113. backupFile.CopyTo(target.FullName, true);
  114. }
  115. else
  116. {
  117. Console.WriteLine(" x {0}", target.FullName);
  118. if(target.Exists)
  119. {
  120. target.Delete();
  121. }
  122. }
  123. } else
  124. {
  125. Console.Error.WriteLine("Backup not found!");
  126. }
  127. }
  128. }
  129. }
  130. }