Add remove mount capabilities to CLI and UI #62
This commit is contained in:
0
support/3rd_party/icu_configure.sh
vendored
Executable file → Normal file
0
support/3rd_party/icu_configure.sh
vendored
Executable file → Normal file
@@ -49,28 +49,28 @@ private:
|
||||
stop_type *stop_requested_{nullptr};
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto copy_to(std::string_view new_path,
|
||||
bool overwrite) const -> bool override;
|
||||
[[nodiscard]] auto copy_to(std::string_view new_path, bool overwrite) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
count(bool recursive = false) const -> std::uint64_t override;
|
||||
[[nodiscard]] auto count(bool recursive = false) const
|
||||
-> std::uint64_t override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
create_directory(std::string_view path = "") const -> fs_directory_t override;
|
||||
[[nodiscard]] auto create_directory(std::string_view path = "") const
|
||||
-> fs_directory_t override;
|
||||
|
||||
[[nodiscard]] auto create_file(std::string_view file_name,
|
||||
bool read_only) const -> fs_file_t override;
|
||||
|
||||
[[nodiscard]] auto exists() const -> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_directory(std::string_view path) const -> fs_directory_t override;
|
||||
[[nodiscard]] auto get_directory(std::string_view path) const
|
||||
-> fs_directory_t override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_directories() const -> std::vector<fs_directory_t> override;
|
||||
[[nodiscard]] auto get_directories() const
|
||||
-> std::vector<fs_directory_t> override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_file(std::string_view path) const -> fs_file_t override;
|
||||
[[nodiscard]] auto get_file(std::string_view path) const
|
||||
-> fs_file_t override;
|
||||
|
||||
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
|
||||
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
|
||||
[[nodiscard]] auto remove_recursively() -> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
size(bool recursive = false) const -> std::uint64_t override;
|
||||
[[nodiscard]] auto size(bool recursive = false) const
|
||||
-> std::uint64_t override;
|
||||
|
||||
public:
|
||||
auto operator=(const directory &) noexcept -> directory & = delete;
|
||||
|
@@ -84,19 +84,19 @@ auto traverse_directory(
|
||||
});
|
||||
}
|
||||
|
||||
struct dirent *de{nullptr};
|
||||
while (res && (de = readdir(root)) && !is_stop_requested()) {
|
||||
if (de->d_type == DT_DIR) {
|
||||
if ((std::string_view(de->d_name) == ".") ||
|
||||
(std::string_view(de->d_name) == "..")) {
|
||||
struct dirent *entry{nullptr};
|
||||
while (res && (entry = ::readdir(root)) && !is_stop_requested()) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
if ((std::string_view(entry->d_name) == ".") ||
|
||||
(std::string_view(entry->d_name) == "..")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res = directory_action(repertory::utils::file::directory(
|
||||
repertory::utils::path::combine(path, {de->d_name})));
|
||||
repertory::utils::path::combine(path, {entry->d_name})));
|
||||
} else {
|
||||
res = file_action(repertory::utils::file::file(
|
||||
repertory::utils::path::combine(path, {de->d_name})));
|
||||
repertory::utils::path::combine(path, {entry->d_name})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,16 +113,67 @@ auto directory::copy_to(std::string_view new_path, bool overwrite) const
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
try {
|
||||
throw utils::error::create_exception(
|
||||
function_name, {
|
||||
"failed to copy directory",
|
||||
"not implemented",
|
||||
utils::string::from_bool(overwrite),
|
||||
new_path,
|
||||
path_,
|
||||
});
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
if (not exists()) {
|
||||
throw utils::error::create_exception(function_name,
|
||||
{
|
||||
"failed to copy directory",
|
||||
"source does not exist",
|
||||
path_,
|
||||
std::string{new_path},
|
||||
});
|
||||
}
|
||||
|
||||
auto src_root = utils::path::finalize(path_);
|
||||
auto dst_root = utils::path::finalize(new_path);
|
||||
|
||||
if (directory{dst_root}.exists()) {
|
||||
auto src_base = utils::path::strip_to_file_name(src_root);
|
||||
dst_root = utils::path::combine(dst_root, {src_base});
|
||||
} else {
|
||||
auto dst_parent = utils::path::get_parent_path(dst_root);
|
||||
if (not dst_parent.empty() && not directory{dst_parent}.exists()) {
|
||||
auto parent_parent = utils::path::get_parent_path(dst_parent);
|
||||
auto last_piece = utils::path::strip_to_file_name(dst_parent);
|
||||
[[maybe_unused]] auto sub_dir =
|
||||
directory{parent_parent}.create_directory(last_piece);
|
||||
}
|
||||
if (not directory{dst_root}.exists()) {
|
||||
auto root_parent = utils::path::get_parent_path(dst_root);
|
||||
auto root_name = utils::path::strip_to_file_name(dst_root);
|
||||
[[maybe_unused]] auto sub_dir =
|
||||
directory{root_parent}.create_directory(root_name);
|
||||
}
|
||||
}
|
||||
|
||||
auto success = traverse_directory(
|
||||
src_root,
|
||||
[this, &dst_root, &src_root](auto &&dir_item) -> bool {
|
||||
auto child_src = dir_item.get_path();
|
||||
auto rel_path = utils::path::get_relative_path(child_src, src_root);
|
||||
auto child_dst = utils::path::combine(dst_root, {rel_path});
|
||||
|
||||
auto child_parent = utils::path::get_parent_path(child_dst);
|
||||
auto child_name = utils::path::strip_to_file_name(child_dst);
|
||||
[[maybe_unused]] auto sub_dir =
|
||||
directory{child_parent}.create_directory(child_name);
|
||||
return not is_stop_requested();
|
||||
},
|
||||
[this, &dst_root, overwrite, &src_root](auto &&file_item) -> bool {
|
||||
auto child_src = file_item.get_path();
|
||||
auto rel_path = utils::path::get_relative_path(child_src, src_root);
|
||||
auto child_dst = utils::path::combine(dst_root, {rel_path});
|
||||
|
||||
if (not file{child_src}.copy_to(child_dst, overwrite)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return not is_stop_requested();
|
||||
},
|
||||
stop_requested_);
|
||||
|
||||
return success && not is_stop_requested();
|
||||
} catch (const std::exception &ex) {
|
||||
utils::error::handle_exception(function_name, ex);
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
}
|
||||
@@ -138,7 +189,7 @@ auto directory::count(bool recursive) const -> std::uint64_t {
|
||||
|
||||
traverse_directory(
|
||||
path_,
|
||||
[&ret, &recursive](auto dir_item) -> bool {
|
||||
[&ret, &recursive](auto &&dir_item) -> bool {
|
||||
if (recursive) {
|
||||
ret += dir_item.count(true);
|
||||
}
|
||||
@@ -146,7 +197,7 @@ auto directory::count(bool recursive) const -> std::uint64_t {
|
||||
++ret;
|
||||
return true;
|
||||
},
|
||||
[&ret](auto /* file_item */) -> bool {
|
||||
[&ret](auto && /* file_item */) -> bool {
|
||||
++ret;
|
||||
return true;
|
||||
},
|
||||
@@ -252,14 +303,14 @@ auto directory::get_directories() const -> std::vector<fs_directory_t> {
|
||||
|
||||
traverse_directory(
|
||||
path_,
|
||||
[this, &ret](auto dir_item) -> bool {
|
||||
[this, &ret](auto &&dir_item) -> bool {
|
||||
ret.emplace_back(fs_directory_t{
|
||||
new directory(dir_item.get_path(), stop_requested_),
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
[](auto /* file_item */) -> bool { return true; }, stop_requested_);
|
||||
[](auto && /* file_item */) -> bool { return true; }, stop_requested_);
|
||||
|
||||
return ret;
|
||||
} catch (const std::exception &e) {
|
||||
@@ -311,8 +362,8 @@ auto directory::get_files() const -> std::vector<fs_file_t> {
|
||||
std::vector<fs_file_t> ret{};
|
||||
|
||||
traverse_directory(
|
||||
path_, [](auto /* dir_item */) -> bool { return true; },
|
||||
[&ret](auto file_item) -> bool {
|
||||
path_, [](auto && /* dir_item */) -> bool { return true; },
|
||||
[&ret](auto &&file_item) -> bool {
|
||||
ret.emplace_back(fs_file_t{
|
||||
new file(file_item.get_path()),
|
||||
});
|
||||
@@ -338,13 +389,13 @@ auto directory::get_items() const -> std::vector<fs_item_t> {
|
||||
|
||||
traverse_directory(
|
||||
path_,
|
||||
[this, &ret](auto dir_item) -> bool {
|
||||
[this, &ret](auto &&dir_item) -> bool {
|
||||
ret.emplace_back(fs_item_t{
|
||||
new directory(dir_item.get_path(), stop_requested_),
|
||||
});
|
||||
return true;
|
||||
},
|
||||
[&ret](auto file_item) -> bool {
|
||||
[&ret](auto &&file_item) -> bool {
|
||||
ret.emplace_back(fs_item_t{
|
||||
new file(file_item.get_path()),
|
||||
});
|
||||
@@ -384,15 +435,68 @@ auto directory::move_to(std::string_view new_path) -> bool {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
try {
|
||||
throw utils::error::create_exception(function_name,
|
||||
{
|
||||
"failed to move directory",
|
||||
"not implemented",
|
||||
new_path,
|
||||
path_,
|
||||
});
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::handle_exception(function_name, e);
|
||||
if (not exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto src_root = utils::path::finalize(path_);
|
||||
auto dst_root = utils::path::finalize(new_path);
|
||||
if (src_root == dst_root) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (directory{dst_root}.exists()) {
|
||||
throw utils::error::create_exception(function_name,
|
||||
{
|
||||
"failed to move directory",
|
||||
"destination exists",
|
||||
src_root,
|
||||
dst_root,
|
||||
});
|
||||
}
|
||||
|
||||
auto dst_parent = utils::path::get_parent_path(dst_root);
|
||||
if (not dst_parent.empty() && not directory{dst_parent}.exists()) {
|
||||
auto parent_parent = utils::path::get_parent_path(dst_parent);
|
||||
auto last_piece = utils::path::strip_to_file_name(dst_parent);
|
||||
[[maybe_unused]] auto sub_dir =
|
||||
directory{parent_parent}.create_directory(last_piece);
|
||||
}
|
||||
|
||||
if (not directory{dst_root}.exists()) {
|
||||
auto root_parent = utils::path::get_parent_path(dst_root);
|
||||
auto root_name = utils::path::strip_to_file_name(dst_root);
|
||||
[[maybe_unused]] auto sub_dir =
|
||||
directory{root_parent}.create_directory(root_name);
|
||||
}
|
||||
|
||||
if (not copy_to(dst_root, true)) {
|
||||
throw utils::error::create_exception(function_name,
|
||||
{
|
||||
"failed to move directory",
|
||||
"copy failed",
|
||||
src_root,
|
||||
dst_root,
|
||||
});
|
||||
}
|
||||
|
||||
if (is_stop_requested()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not remove_recursively()) {
|
||||
throw utils::error::create_exception(function_name,
|
||||
{
|
||||
"failed to move directory",
|
||||
"remove source failed",
|
||||
src_root,
|
||||
});
|
||||
}
|
||||
|
||||
path_ = dst_root;
|
||||
return true;
|
||||
} catch (const std::exception &ex) {
|
||||
utils::error::handle_exception(function_name, ex);
|
||||
} catch (...) {
|
||||
utils::error::handle_exception(function_name);
|
||||
}
|
||||
@@ -439,8 +543,10 @@ auto directory::remove_recursively() -> bool {
|
||||
|
||||
if (not traverse_directory(
|
||||
path_,
|
||||
[](auto dir_item) -> bool { return dir_item.remove_recursively(); },
|
||||
[](auto file_item) -> bool { return file_item.remove(); },
|
||||
[](auto &&dir_item) -> bool {
|
||||
return dir_item.remove_recursively();
|
||||
},
|
||||
[](auto &&file_item) -> bool { return file_item.remove(); },
|
||||
stop_requested_)) {
|
||||
return false;
|
||||
}
|
||||
@@ -463,14 +569,14 @@ auto directory::size(bool recursive) const -> std::uint64_t {
|
||||
|
||||
traverse_directory(
|
||||
path_,
|
||||
[&ret, &recursive](auto dir_item) -> bool {
|
||||
[&ret, &recursive](auto &&dir_item) -> bool {
|
||||
if (recursive) {
|
||||
ret += dir_item.size(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
[&ret](auto file_item) -> bool {
|
||||
[&ret](auto &&file_item) -> bool {
|
||||
auto cur_size = file_item.size();
|
||||
if (cur_size.has_value()) {
|
||||
ret += cur_size.value();
|
||||
|
@@ -336,6 +336,7 @@ TEST_P(utils_encryption_read_encrypted_range_fixture, single_byte_read) {
|
||||
|
||||
TEST_P(utils_encryption_read_encrypted_range_fixture,
|
||||
begin_at_exact_chunk_boundary) {
|
||||
|
||||
auto begin = static_cast<std::uint64_t>(chunk);
|
||||
std::uint64_t end = begin + 1024U - 1U;
|
||||
if (end >= plain_sz)
|
||||
|
Reference in New Issue
Block a user