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.

97 lines
3.1 KiB

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