aboutsummaryrefslogtreecommitdiff
path: root/src/zen/cmds/copy_cmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zen/cmds/copy_cmd.cpp')
-rw-r--r--src/zen/cmds/copy_cmd.cpp207
1 files changed, 0 insertions, 207 deletions
diff --git a/src/zen/cmds/copy_cmd.cpp b/src/zen/cmds/copy_cmd.cpp
deleted file mode 100644
index 530661607..000000000
--- a/src/zen/cmds/copy_cmd.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#include "copy_cmd.h"
-
-#include <zencore/filesystem.h>
-#include <zencore/fmtutils.h>
-#include <zencore/logging.h>
-#include <zencore/string.h>
-#include <zencore/timer.h>
-
-namespace zen {
-
-CopyCommand::CopyCommand()
-{
- m_Options.add_options()("h,help", "Print help");
- m_Options.add_options()("no-clone", "Do not perform block clone", cxxopts::value(m_NoClone)->default_value("false"));
- m_Options.add_options()("must-clone",
- "Always perform block clone (fails if clone is not possible)",
- cxxopts::value(m_MustClone)->default_value("false"));
- m_Options.add_option("", "s", "source", "Copy source", cxxopts::value(m_CopySource), "<file/directory>");
- m_Options.add_option("", "t", "target", "Copy target", cxxopts::value(m_CopyTarget), "<file/directory>");
- m_Options.parse_positional({"source", "target"});
-}
-
-CopyCommand::~CopyCommand() = default;
-
-void
-CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
-{
- ZEN_UNUSED(GlobalOptions);
-
- if (!ParseOptions(argc, argv))
- {
- return;
- }
-
- // Validate arguments
-
- if (m_CopySource.empty())
- throw OptionParseException("'--source' is required", m_Options.help());
-
- if (m_CopyTarget.empty())
- throw OptionParseException("'--target' is required", m_Options.help());
-
- std::filesystem::path FromPath = m_CopySource;
- std::filesystem::path ToPath = m_CopyTarget;
-
- std::error_code Ec;
- std::filesystem::path FromCanonical = std::filesystem::canonical(FromPath, Ec);
-
- if (!Ec)
- {
- std::filesystem::path ToCanonical = std::filesystem::canonical(ToPath, Ec);
-
- if (!Ec)
- {
- if (FromCanonical == ToCanonical)
- {
- throw std::runtime_error("Target and source must be distinct files or directories");
- }
- }
- }
-
- const bool IsFileCopy = IsFile(m_CopySource);
- const bool IsDirCopy = IsDir(m_CopySource);
-
- if (!IsFileCopy && !IsDirCopy)
- {
- throw std::runtime_error("Invalid source specification (neither directory nor file)");
- }
-
- if (IsFileCopy && IsDirCopy)
- {
- throw std::runtime_error("Invalid source specification (both directory AND file!?)");
- }
-
- if (IsDirCopy)
- {
- if (IsFile(ToPath))
- {
- throw std::runtime_error("Attempted copy of directory into file");
- }
-
- if (!IsDir(ToPath))
- {
- CreateDirectories(ToPath);
- }
-
- std::filesystem::path ToCanonical = std::filesystem::canonical(ToPath, Ec);
-
- if (!Ec)
- {
- if (ToCanonical.generic_string().starts_with(FromCanonical.generic_string()) ||
- FromCanonical.generic_string().starts_with(ToCanonical.generic_string()))
- {
- throw std::runtime_error("Invalid parent/child relationship for source/target directories");
- }
- }
-
- // Multi file copy
-
- ZEN_CONSOLE("copying {} -> {}", FromPath, ToPath);
-
- zen::Stopwatch Timer;
-
- struct CopyVisitor : public FileSystemTraversal::TreeVisitor
- {
- CopyVisitor(std::filesystem::path InBasePath, zen::CopyFileOptions InCopyOptions)
- : BasePath(InBasePath)
- , CopyOptions(InCopyOptions)
- {
- }
-
- virtual void VisitFile(const std::filesystem::path& Parent,
- const path_view& File,
- uint64_t FileSize,
- uint32_t,
- uint64_t) override
- {
- ZEN_UNUSED(FileSize);
- std::error_code Ec;
- const std::filesystem::path Relative = std::filesystem::relative(Parent, BasePath, Ec);
-
- if (Ec)
- {
- FailedFileCount++;
- }
- else
- {
- const std::filesystem::path FromPath = Parent / File;
- const std::filesystem::path ToPath = TargetPath / Relative / File;
-
- try
- {
- zen::CreateDirectories(TargetPath / Relative);
- if (zen::CopyFile(FromPath, ToPath, CopyOptions))
- {
- ++FileCount;
- ByteCount += FileSize;
- }
- else
- {
- throw std::logic_error("CopyFile failed in an unexpected way");
- }
- }
- catch (const std::exception& Ex)
- {
- ++FailedFileCount;
-
- ZEN_CONSOLE_ERROR("Failed to copy '{}' to '{}': '{}'", FromPath, ToPath, Ex.what());
- }
- }
- }
-
- virtual bool VisitDirectory(const std::filesystem::path&, const path_view&, uint32_t) override { return true; }
-
- std::filesystem::path BasePath;
- std::filesystem::path TargetPath;
- zen::CopyFileOptions CopyOptions;
- int FileCount = 0;
- uint64_t ByteCount = 0;
- int FailedFileCount = 0;
- };
-
- zen::CopyFileOptions CopyOptions;
- CopyOptions.EnableClone = !m_NoClone;
- CopyOptions.MustClone = m_MustClone;
-
- CopyVisitor Visitor{FromPath, CopyOptions};
- Visitor.TargetPath = ToPath;
-
- FileSystemTraversal Traversal;
- Traversal.TraverseFileSystem(FromPath, Visitor);
-
- ZEN_CONSOLE("Copy of {} files ({}) completed in {} ({})",
- Visitor.FileCount,
- NiceBytes(Visitor.ByteCount),
- zen::NiceTimeSpanMs(Timer.GetElapsedTimeMs()),
- zen::NiceRate(Visitor.ByteCount, (uint32_t)Timer.GetElapsedTimeMs()));
-
- if (Visitor.FailedFileCount)
- {
- throw std::runtime_error(fmt::format("{} file copy operations FAILED", Visitor.FailedFileCount));
- }
- }
- else
- {
- // Single file copy
-
- zen::Stopwatch Timer;
-
- zen::CopyFileOptions CopyOptions;
- CopyOptions.EnableClone = !m_NoClone;
-
- zen::CreateDirectories(ToPath.parent_path());
- if (zen::CopyFile(FromPath, ToPath, CopyOptions))
- {
- ZEN_CONSOLE("Copy completed in {}", zen::NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
- }
- else
- {
- throw std::runtime_error(fmt::format("Failed to copy '{}' to '{}'", FromPath, ToPath));
- }
- }
-}
-
-} // namespace zen