CLI tool for running Playbooks
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.

98 lines
3.2 KiB

1 year ago
10 months ago
1 year ago
6 months ago
1 year ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using TrustedUninstaller.Shared.Exceptions;
  7. using TrustedUninstaller.Shared.Tasks;
  8. using YamlDotNet.Serialization;
  9. namespace TrustedUninstaller.Shared.Actions
  10. {
  11. internal enum LineInFileOperation
  12. {
  13. Delete = 0,
  14. Add = 1
  15. }
  16. internal class LineInFileAction : TaskAction, ITaskAction
  17. {
  18. public void RunTaskOnMainThread() { throw new NotImplementedException(); }
  19. [YamlMember(Alias = "path")]
  20. public string RawPath { get; set; }
  21. [YamlMember(Alias = "line")]
  22. public string RawLines { get; set; }
  23. [YamlMember(Alias = "operation")]
  24. public LineInFileOperation Operation { get; set; } = LineInFileOperation.Delete;
  25. [YamlMember(typeof(string), Alias = "weight")]
  26. public int ProgressWeight { get; set; } = 1;
  27. public int GetProgressWeight() => ProgressWeight;
  28. private bool InProgress { get; set; } = false;
  29. public void ResetProgress() => InProgress = false;
  30. public string ErrorString() => $"LineInFileAction failed to {Operation.ToString().ToLower()} lines to file '{RawPath}'.";
  31. public UninstallTaskStatus GetStatus()
  32. {
  33. if (InProgress)
  34. {
  35. return UninstallTaskStatus.InProgress;
  36. }
  37. var realPath = this.GetRealPath();
  38. if (!File.Exists(realPath))
  39. {
  40. // If the file doesn't exist it can't contain the lines either, can it?
  41. return Operation == LineInFileOperation.Delete ?
  42. UninstallTaskStatus.Completed : UninstallTaskStatus.ToDo;
  43. }
  44. var isDone = !GetMissingLines().Any();
  45. return isDone ? UninstallTaskStatus.Completed : UninstallTaskStatus.ToDo;
  46. }
  47. private IEnumerable<string> GetLines() =>
  48. RawLines.Split(
  49. new[] { "\r\n", "\r", "\n" },
  50. StringSplitOptions.None
  51. );
  52. private IEnumerable<string> GetMissingLines()
  53. {
  54. var realPath = this.GetRealPath();
  55. var fileLines = File.ReadAllLines(realPath);
  56. var targetLines = GetLines();
  57. return targetLines.Where(line => !fileLines.Contains(line));
  58. }
  59. private string GetRealPath()
  60. {
  61. return Environment.ExpandEnvironmentVariables(RawPath);
  62. }
  63. public async Task<bool> RunTask()
  64. {
  65. if (InProgress) throw new TaskInProgressException("Another LineInFile action was called while one was in progress.");
  66. InProgress = true;
  67. //Wording should be improved here
  68. Console.WriteLine($"{Operation.ToString().TrimEnd('e')}ing text lines in file '{RawPath}'...");
  69. var realPath = this.GetRealPath();
  70. var missingLines = GetMissingLines();
  71. using var sw = File.AppendText(realPath);
  72. foreach (var missingLine in missingLines)
  73. {
  74. await sw.WriteLineAsync(missingLine);
  75. }
  76. InProgress = false;
  77. return true;
  78. }
  79. }
  80. }