CloneCmd.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using qdr.app.tools.qfu.Commands.Aspects;
  2. using Quadarax.Foundation.Core.QConsole;
  3. using Quadarax.Foundation.Core.QConsole.Argument;
  4. using Quadarax.Foundation.Core.QConsole.Attributes;
  5. using Quadarax.Foundation.Core.Value;
  6. namespace qdr.app.tools.qfu.Commands
  7. {
  8. [CommandDefinition]
  9. internal class CloneCmd : BaseCmd
  10. {
  11. #region *** Constants ***
  12. private const string CMD_NAME = "clone";
  13. private const string CMD_DESCR = "Clone source file to files specified.";
  14. private const string ARG_N_NAME = "n";
  15. private const string ARG_N_HINT = "ncount";
  16. private const string ARG_N_DESCR = "Numeric value how many <{0}> files will be generated. If used, then files in <{1}> arguments will be ignored.";
  17. #endregion
  18. #region *** Properties ***
  19. public override string Name => CMD_NAME;
  20. public override string Description => CMD_DESCR;
  21. protected string[] TargetFiles { get; private set; } = Array.Empty<string>();
  22. protected bool IsEnsurePath { get; private set; } = false;
  23. protected bool IsForce { get; private set; } = false;
  24. protected int? CloneCount{ get; private set; }
  25. #endregion
  26. #region *** Constructors ***
  27. public CloneCmd(Engine engine) : base(engine)
  28. {
  29. }
  30. #endregion
  31. #region *** Overrides ***
  32. #region **** EXECUTE ****
  33. protected override Result OnExecute()
  34. {
  35. WriteCaption($"Will be clonig file '{Source}' to {TargetFiles.Length} files {(IsForce ? "(with force)": string.Empty)}... ");
  36. var cnt = 0;
  37. var succ = 0;
  38. var bSucc = true;
  39. foreach (var file in TargetFiles)
  40. {
  41. cnt++;
  42. if (FileSystem.File.Exists(file) && !IsEnsurePath)
  43. {
  44. if (!IsForce)
  45. {
  46. WriteWarning($"[{cnt}] File '{file}' already exists. Skipping clone operation.");
  47. continue;
  48. }
  49. }
  50. try
  51. {
  52. FileSystem.File.Copy(Source, file, true);
  53. if (FileSystem.File.Exists(file))
  54. succ++;
  55. else
  56. WriteWarning($"[{cnt}] File '{file}' does not exist after copy operation.");
  57. WriteInfo($"[{cnt}] Cloned '{Source}' to '{file}' successfully.");
  58. }
  59. catch (Exception ex)
  60. {
  61. WriteError($"[{cnt}] Failed to clone '{Source}' to '{file}': {ex.Message}");
  62. bSucc = false;
  63. }
  64. }
  65. WriteCaption($"Succesfully cloned: {succ} of {cnt} files.");
  66. bSucc = succ == cnt;
  67. return bSucc ? new Result() : new Result(new Exception($"Failed to clone {TargetFiles.Length - succ} files from '{Source}'."));
  68. }
  69. #endregion
  70. #region **** Arguments ****
  71. protected override void OnValidateArguments()
  72. {
  73. if(WasArgumentSpecified(ARG_N_NAME))
  74. {
  75. // count argument is set -> fake argument to ensure that files are not used
  76. var argTaget = GetArgument(FilesAspect.ARG_FILES_NAME);
  77. argTaget.Value.Set("file");
  78. }
  79. base.OnValidateArguments();
  80. CheckSourceFileExists();
  81. if(WasArgumentSpecified(ARG_N_NAME))
  82. {
  83. CloneCount = GetArgumentValueOrDefault<int>(ARG_N_NAME, 0);
  84. TargetFiles = GenerateTargetFiles(CloneCount.Value);
  85. }
  86. else
  87. TargetFiles = ListAspect.GetFiles(this, FileSystem, FilesAspect.GetFiles(this, FileSystem, false));
  88. IsEnsurePath = GetArgumentValueOrDefault<bool>(FilesAspect.ARG_PATHENS_NAME, false);
  89. IsForce = GetArgumentValueOrDefault<bool>(ForceAspect.ARG_FORCE_NAME, false);
  90. }
  91. protected override IEnumerable<AbstractArgument> OnSetupArguments()
  92. {
  93. var list = base.OnSetupArguments().ToList();
  94. list.Add(new NamedArgument(ARG_N_NAME, string.Format(ARG_N_DESCR, SourceAspect.ARG_SRC_NAME, FilesAspect.ARG_FILES_NAME), ARG_N_HINT,Quadarax.Foundation.Core.QConsole.Value.TypeValuesEnum.Integer, "0",false));
  95. list.AddRange(ListAspect.SetupArguments());
  96. list.AddRange(FilesAspect.SetupArguments());
  97. list.AddRange(ForceAspect.SetupArguments());
  98. return list;
  99. }
  100. #endregion
  101. #region **** Private Operations ****
  102. private string[] GenerateTargetFiles(int count)
  103. {
  104. if (count <= 0)
  105. throw new ArgumentException("Count must be greater than zero.", nameof(count));
  106. var fileName = Path.GetFileNameWithoutExtension(Source);
  107. var fileExt = Path.GetExtension(Source);
  108. var directory = Path.GetDirectoryName(Source) ?? string.Empty;
  109. var files = new string[count];
  110. for (int i = 0; i < count; i++)
  111. {
  112. files[i] = Path.Combine(directory, $"{fileName}_{i + 1}{fileExt}");
  113. }
  114. return files;
  115. }
  116. #endregion
  117. #endregion
  118. }
  119. }