Compare commits

...

2 commits

Author SHA1 Message Date
d95f3d0f32
Refactor 2021-05-10 18:49:01 +02:00
0663f42aec
Separate options definition and parsing 2021-05-01 09:27:40 +02:00
6 changed files with 97 additions and 70 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
.clangd/ .clangd/
.cache/
build/ build/
target/ target/
compile_commands.json compile_commands.json

46
src/Opt.hpp Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include <fmt/core.h>
#include <fmt/format.h>
#include <filesystem>
#include <optional>
#include <set>
namespace xwim {
enum class Action { EXTRACT, COMPRESS };
struct UserOpt {
std::optional<Action> action;
bool interactive;
std::optional<std::filesystem::path> out;
std::set<std::filesystem::path> paths;
};
struct XwimConfig {
Action action;
std::filesystem::path output;
std::set<std::filesystem::path> input;
};
XwimConfig guess_wim(UserOpt user_opt);
void do_wim(XwimConfig);
} // namespace xwim
template <>
struct fmt::formatter<xwim::Action> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const xwim::Action& action, FormatContext& ctx) {
switch (action) {
case xwim::Action::EXTRACT:
return format_to(ctx.out(), "EXTRACT");
case xwim::Action::COMPRESS:
return format_to(ctx.out(), "COMPRESS");
};
return format_to(ctx.out(), "");
}
};

View file

@ -14,10 +14,6 @@
#include "Archiver.hpp" #include "Archiver.hpp"
#include "Common.hpp" #include "Common.hpp"
namespace xwim {
using namespace std;
namespace fs = std::filesystem;
#if defined(unix) || defined(__unix__) || defined(__unix) #if defined(unix) || defined(__unix__) || defined(__unix)
std::string default_extension = ".tar.gz"; std::string default_extension = ".tar.gz";
#elif defined(_win32) || defined(__win32__) || defined(__windows__) #elif defined(_win32) || defined(__win32__) || defined(__windows__)
@ -26,6 +22,10 @@ std::string default_extension = ".zip";
std::string default_extension = ".zip"; std::string default_extension = ".zip";
#endif #endif
namespace xwim {
using namespace std;
namespace fs = std::filesystem;
Xwim::Xwim() : action{Action::UNKNOWN} {} Xwim::Xwim() : action{Action::UNKNOWN} {}
void Xwim::try_infer() { void Xwim::try_infer() {

View file

@ -9,13 +9,14 @@
#include <stdexcept> #include <stdexcept>
#include "Common.hpp" #include "Common.hpp"
#include "Opt.hpp"
#include "Archiver.hpp" #include "Archiver.hpp"
namespace xwim { namespace xwim {
using namespace std; using namespace std;
namespace fs = std::filesystem; namespace fs = std::filesystem;
enum class Action { UNKNOWN, EXTRACT, COMPRESS }; Xwim xwim(UserOpt user_opt);
class Xwim { class Xwim {
private: private:
@ -43,21 +44,3 @@ class Xwim {
}; };
} // namespace xwim } // namespace xwim
template <>
struct fmt::formatter<xwim::Action> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const xwim::Action& action, FormatContext& ctx) {
switch (action) {
case xwim::Action::UNKNOWN:
return format_to(ctx.out(), "UNKNOWN");
case xwim::Action::EXTRACT:
return format_to(ctx.out(), "EXTRACT");
case xwim::Action::COMPRESS:
return format_to(ctx.out(), "COMPRESS");
};
return format_to(ctx.out(), "");
}
};

View file

@ -10,66 +10,60 @@
#include <cstdlib> #include <cstdlib>
#include <filesystem> #include <filesystem>
#include <memory>
#include <optional>
#include "Common.hpp" #include "Common.hpp"
#include "Log.hpp" #include "Log.hpp"
#include "Opt.hpp"
#include "Xwim.hpp" #include "Xwim.hpp"
using namespace xwim; using namespace xwim;
using namespace std; using namespace std;
namespace fs = std::filesystem;
template <> template <>
struct TCLAP::ArgTraits<std::filesystem::path> { struct TCLAP::ArgTraits<std::filesystem::path> {
typedef ValueLike ValueCategory; typedef ValueLike ValueCategory;
}; };
UserOpt parse_args(int argc, char** argv) {
// clang-format off
TCLAP::CmdLine cmd_line
{"xwim - Do What I Mean Extractor", ' ', "0.5.0"};
TCLAP::SwitchArg arg_compress
{"c", "compress", "Compress <files>", cmd_line, false};
TCLAP::SwitchArg arg_extract
{"x", "extract", "Extract <files>", cmd_line, false};
TCLAP::SwitchArg arg_noninteractive
{"ni", "noninteractive", "Fail if action cannot be determined", cmd_line, false};
TCLAP::ValueArg<std::filesystem::path> arg_out
{"o", "out", "Out <path>", false, std::filesystem::path{}, "A path on the filesystem", cmd_line};
TCLAP::UnlabeledMultiArg<std::filesystem::path> arg_paths
{"Paths", "Filesystem paths to extract or compress", true, "A path on the filesystem", cmd_line};
// clang-format on
cmd_line.parse(argc, argv);
UserOpt user_opt;
if(arg_compress.getValue()) user_opt.action = Action::COMPRESS;
if(arg_extract.getValue()) user_opt.action = Action::EXTRACT;
if(arg_out.isSet()) user_opt.out = arg_out.getValue();
user_opt.interactive = !arg_noninteractive.getValue();
user_opt.paths = std::set<fs::path>{arg_paths.getValue().begin(), arg_paths.getValue().end()};
return user_opt;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
log::init(); log::init();
TCLAP::CmdLine cmd{"xwim - Do What I Mean Extractor", ' ', "0.3.0"}; UserOpt user_opt = parse_args(argc, argv);
XwimConfig xwim_config = guess_wim(user_opt);
TCLAP::SwitchArg arg_compress{"c", "compress", "Compress <files>", cmd, do_wim(xwim_config);
false};
TCLAP::SwitchArg arg_extract{"x", "extract", "Extract <file>", cmd, false};
TCLAP::ValueArg<fs::path> arg_outfile{
"o", "out", "Out <file-or-path>",
false, fs::path{}, "A path on the filesystem",
cmd};
TCLAP::UnlabeledMultiArg<fs::path> arg_infiles{
"Files", "Archive to extract or files to compress", true,
"A path on the filesystem", cmd};
Xwim xwim;
cmd.parse(argc, argv);
if (arg_extract.isSet() && arg_compress.isSet()) {
// This is a bit ugly but `none-or-xor` only available in
// tclap-1.4 which is not well supported in current
// distributions
auto out = TCLAP::StdOutput{};
TCLAP::ArgException e{
"Cannot compress `-c` and extract `-x` simultaneously"};
try {
out.failure(cmd, e);
} catch (TCLAP::ExitException& e) {
exit(e.getExitStatus());
}
}
// `none-or-xor` ensured already
if (arg_extract.isSet()) xwim.setExtract();
if (arg_compress.isSet()) xwim.setCompress();
if (arg_outfile.isSet()) xwim.setOut(arg_outfile.getValue());
if (arg_infiles.isSet()) xwim.setIns(arg_infiles.getValue());
try {
xwim.try_infer();
xwim.dwim();
} catch (XwimError& e) {
spdlog::error(e.what());
}
} }

View file

@ -1,4 +1,5 @@
xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp'] xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp']
xwim_dwim = ['dwim/Opt.cpp']
xwim_archiver = ['archiver/LibArchiver.cpp'] xwim_archiver = ['archiver/LibArchiver.cpp']
is_static = get_option('default_library')=='static' is_static = get_option('default_library')=='static'
@ -8,4 +9,6 @@ xwim_libs = [dependency('libarchive', required: true, static: is_static),
dependency('spdlog', required: true, static: is_static), dependency('spdlog', required: true, static: is_static),
dependency('tclap', required: true, static: is_static)] dependency('tclap', required: true, static: is_static)]
executable('xwim', xwim_src+xwim_archiver, dependencies: xwim_libs) executable('xwim',
xwim_src+xwim_archiver+xwim_dwim,
dependencies: xwim_libs)