This commit is contained in:
parent
1aea5cd924
commit
c8e6f51e1b
1 changed files with 168 additions and 166 deletions
|
@ -1,19 +1,17 @@
|
||||||
#include "UserIntent.hpp"
|
#include "UserIntent.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include "Archiver.hpp"
|
#include "Archiver.hpp"
|
||||||
|
|
||||||
namespace xwim {
|
namespace xwim {
|
||||||
unique_ptr<UserIntent> make_compress_intent(const UserOpt &userOpt) {
|
unique_ptr<UserIntent> make_compress_intent(const UserOpt &userOpt) {
|
||||||
if (userOpt.paths.size() == 1) {
|
if (userOpt.paths.size() == 1) {
|
||||||
return make_unique<CompressSingleIntent>(
|
return make_unique<CompressSingleIntent>(
|
||||||
CompressSingleIntent{
|
CompressSingleIntent{*userOpt.paths.begin(), userOpt.out});
|
||||||
*userOpt.paths.begin(),
|
|
||||||
userOpt.out
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userOpt.out.has_value()) {
|
if (!userOpt.out.has_value()) {
|
||||||
|
@ -21,57 +19,57 @@ namespace xwim {
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_unique<CompressManyIntent>(
|
return make_unique<CompressManyIntent>(
|
||||||
CompressManyIntent{
|
CompressManyIntent{userOpt.paths, userOpt.out.value()});
|
||||||
userOpt.paths,
|
}
|
||||||
userOpt.out.value()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_ptr<UserIntent> make_extract_intent(const UserOpt &userOpt) {
|
unique_ptr<UserIntent> make_extract_intent(const UserOpt &userOpt) {
|
||||||
for (const path& p: userOpt.paths) {
|
for (const path &p : userOpt.paths) {
|
||||||
if (!can_handle_archive(p)) {
|
if (!can_handle_archive(p)) {
|
||||||
throw XwimError("Cannot extract path {}", p);
|
throw XwimError("Cannot extract path {}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_unique<ExtractIntent>(
|
return make_unique<ExtractIntent>(ExtractIntent{userOpt.paths, userOpt.out});
|
||||||
ExtractIntent{
|
}
|
||||||
userOpt.paths,
|
|
||||||
userOpt.out
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_ptr<UserIntent> try_infer_compress_intent(const UserOpt &userOpt) {
|
unique_ptr<UserIntent> try_infer_compress_intent(const UserOpt &userOpt) {
|
||||||
if(!userOpt.out.has_value()) {
|
if (!userOpt.out.has_value()) {
|
||||||
spdlog::debug("No <out> provided");
|
spdlog::debug("No <out> provided");
|
||||||
if(userOpt.paths.size() != 1) {
|
if (userOpt.paths.size() != 1) {
|
||||||
spdlog::debug("Not a single-path compression. Cannot guess <out> for many-path compression");
|
spdlog::debug(
|
||||||
|
"Not a single-path compression. Cannot guess <out> for many-path "
|
||||||
|
"compression");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::debug("Only one <path> provided. Assume single-path compression.");
|
spdlog::debug("Only one <path> provided. Assume single-path compression.");
|
||||||
return make_unique<CompressSingleIntent>(CompressSingleIntent{*userOpt.paths.begin(), userOpt.out});
|
return make_unique<CompressSingleIntent>(
|
||||||
|
CompressSingleIntent{*userOpt.paths.begin(), userOpt.out});
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::debug("<out> provided: {}", userOpt.out.value());
|
spdlog::debug("<out> provided: {}", userOpt.out.value());
|
||||||
if(can_handle_archive(userOpt.out.value())) {
|
if (can_handle_archive(userOpt.out.value())) {
|
||||||
spdlog::debug("{} given and a known archive format, assume compression", userOpt.out.value());
|
spdlog::debug("{} given and a known archive format, assume compression",
|
||||||
|
userOpt.out.value());
|
||||||
return make_compress_intent(userOpt);
|
return make_compress_intent(userOpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::debug("Cannot compress multiple paths without a user-provided output archive");
|
spdlog::debug(
|
||||||
|
"Cannot compress multiple paths without a user-provided output archive");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<UserIntent> try_infer_extract_intent(const UserOpt &userOpt) {
|
unique_ptr<UserIntent> try_infer_extract_intent(const UserOpt &userOpt) {
|
||||||
bool can_extract_all = std::all_of(
|
bool can_extract_all =
|
||||||
userOpt.paths.begin(), userOpt.paths.end(),
|
std::all_of(userOpt.paths.begin(), userOpt.paths.end(),
|
||||||
[](const path &path) { return can_handle_archive(path); });
|
[](const path &path) { return can_handle_archive(path); });
|
||||||
|
|
||||||
if(!can_extract_all) {
|
if (!can_extract_all) {
|
||||||
spdlog::debug("Cannot extract all provided <paths>. Assume this is not an extraction.");
|
spdlog::debug(
|
||||||
for(const path& p: userOpt.paths) {
|
"Cannot extract all provided <paths>. Assume this is not an "
|
||||||
if(!can_handle_archive(p)) {
|
"extraction.");
|
||||||
|
for (const path &p : userOpt.paths) {
|
||||||
|
if (!can_handle_archive(p)) {
|
||||||
spdlog::debug("Cannot handle {}", p);
|
spdlog::debug("Cannot handle {}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,20 +77,25 @@ namespace xwim {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(userOpt.out.has_value() && can_handle_archive(userOpt.out.value())) {
|
if (userOpt.out.has_value() && can_handle_archive(userOpt.out.value())) {
|
||||||
spdlog::debug("Could extract all provided <paths>. But also {} looks like an archive. Ambiguous intent. Assume this is not an extraction.", userOpt.out.value());
|
spdlog::debug(
|
||||||
|
"Could extract all provided <paths>. But also {} looks like an "
|
||||||
|
"archive. Ambiguous intent. Assume this is not an extraction.",
|
||||||
|
userOpt.out.value());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::debug("Could extract all provided <paths>. But also <out> looks like an archive. Ambiguous intent. Assume this is not an extraction.");
|
spdlog::debug(
|
||||||
|
"Could extract all provided <paths>. But also <out> looks like an "
|
||||||
|
"archive. Ambiguous intent. Assume this is not an extraction.");
|
||||||
return make_extract_intent(userOpt);
|
return make_extract_intent(userOpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<UserIntent> make_intent(const UserOpt &userOpt) {
|
unique_ptr<UserIntent> make_intent(const UserOpt &userOpt) {
|
||||||
if (userOpt.wants_compress() && userOpt.wants_extract()) {
|
if (userOpt.wants_compress() && userOpt.wants_extract()) {
|
||||||
throw XwimError("Cannot compress and extract simultaneously");
|
throw XwimError("Cannot compress and extract simultaneously");
|
||||||
}
|
}
|
||||||
if(userOpt.paths.empty()) {
|
if (userOpt.paths.empty()) {
|
||||||
throw XwimError("No input given...");
|
throw XwimError("No input given...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,33 +105,31 @@ namespace xwim {
|
||||||
|
|
||||||
spdlog::info("Intent not explicitly provided, trying to infer intent");
|
spdlog::info("Intent not explicitly provided, trying to infer intent");
|
||||||
|
|
||||||
if(auto intent = try_infer_extract_intent(userOpt)) {
|
if (auto intent = try_infer_extract_intent(userOpt)) {
|
||||||
spdlog::info("Extraction intent inferred");
|
spdlog::info("Extraction intent inferred");
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
spdlog::info("Cannot infer extraction intent");
|
spdlog::info("Cannot infer extraction intent");
|
||||||
|
|
||||||
if(auto intent = try_infer_compress_intent(userOpt)) {
|
if (auto intent = try_infer_compress_intent(userOpt)) {
|
||||||
spdlog::info("Compression intent inferred");
|
spdlog::info("Compression intent inferred");
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
spdlog::info("Cannot infer compression intent");
|
spdlog::info("Cannot infer compression intent");
|
||||||
|
|
||||||
|
|
||||||
throw XwimError("Cannot guess intent");
|
throw XwimError("Cannot guess intent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExtractIntent::execute() {
|
||||||
void ExtractIntent::execute() {
|
|
||||||
bool has_out = this->out.has_value();
|
bool has_out = this->out.has_value();
|
||||||
bool is_single = this->archives.size() == 1;
|
bool is_single = this->archives.size() == 1;
|
||||||
|
|
||||||
for (path p: this->archives) {
|
for (const path &p : this->archives) {
|
||||||
unique_ptr<Archiver> archiver = make_archiver(p);
|
unique_ptr<Archiver> archiver = make_archiver(p);
|
||||||
path out;
|
path out;
|
||||||
|
|
||||||
if(has_out) {
|
if (has_out) {
|
||||||
if(is_single) { // just dump content of archive into `out`
|
if (is_single) { // just dump content of archive into `out`
|
||||||
std::filesystem::create_directories(this->out.value());
|
std::filesystem::create_directories(this->out.value());
|
||||||
out = this->out.value();
|
out = this->out.value();
|
||||||
} else { // create an `out` folder and extract inside there
|
} else { // create an `out` folder and extract inside there
|
||||||
|
@ -146,15 +147,16 @@ namespace xwim {
|
||||||
// the stripped archive name
|
// the stripped archive name
|
||||||
auto dit = std::filesystem::directory_iterator(out);
|
auto dit = std::filesystem::directory_iterator(out);
|
||||||
|
|
||||||
if(dit == std::filesystem::directory_iterator()) {
|
if (dit == std::filesystem::directory_iterator()) {
|
||||||
spdlog::debug("Archive is empty");
|
spdlog::debug("Archive is empty");
|
||||||
} else if(is_directory(dit->path())){
|
} else if (is_directory(dit->path())) {
|
||||||
auto first_path = dit->path();
|
auto first_path = dit->path();
|
||||||
auto next_entry = next(dit);
|
auto next_entry = next(dit);
|
||||||
|
|
||||||
if(next_entry == std::filesystem::directory_iterator()) {
|
if (next_entry == std::filesystem::directory_iterator()) {
|
||||||
spdlog::debug("Archive has single entry which is a directory");
|
spdlog::debug("Archive has single entry which is a directory");
|
||||||
if(std::filesystem::equivalent(first_path.filename(), out.filename())) {
|
if (std::filesystem::equivalent(first_path.filename(),
|
||||||
|
out.filename())) {
|
||||||
spdlog::debug("Archive entry named like archive");
|
spdlog::debug("Archive entry named like archive");
|
||||||
int i = rand_int(0, 100000);
|
int i = rand_int(0, 100000);
|
||||||
|
|
||||||
|
@ -176,11 +178,11 @@ namespace xwim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CompressSingleIntent::execute() {
|
void CompressSingleIntent::execute() {
|
||||||
if(this->out.has_value()) {
|
if (this->out.has_value()) {
|
||||||
if(!can_handle_archive(this->out.value())) {
|
if (!can_handle_archive(this->out.value())) {
|
||||||
throw XwimError("Unknown archive format {}", this->out.value());
|
throw XwimError("Unknown archive format {}", this->out.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,14 +195,14 @@ namespace xwim {
|
||||||
set<path> ins{this->in};
|
set<path> ins{this->in};
|
||||||
archiver->compress(ins, out);
|
archiver->compress(ins, out);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CompressManyIntent::execute() {
|
void CompressManyIntent::execute() {
|
||||||
if(!can_handle_archive(this->out)) {
|
if (!can_handle_archive(this->out)) {
|
||||||
throw XwimError("Unknown archive format {}", this->out);
|
throw XwimError("Unknown archive format {}", this->out);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Archiver> archiver = make_archiver(this->out);
|
unique_ptr<Archiver> archiver = make_archiver(this->out);
|
||||||
archiver->compress(this->in_paths, this->out);
|
archiver->compress(this->in_paths, this->out);
|
||||||
};
|
};
|
||||||
} // namespace xwim
|
} // namespace xwim
|
||||||
|
|
Loading…
Reference in a new issue