diff --git a/src/Opt.hpp b/src/Opt.hpp index 2087c42..6c345de 100644 --- a/src/Opt.hpp +++ b/src/Opt.hpp @@ -1,59 +1,46 @@ -#include -#include -#include -#include -#include -#include +#pragma once + +#include +#include #include - -template <> -struct TCLAP::ArgTraits { - typedef ValueLike ValueCategory; -}; +#include +#include namespace xwim { -namespace fs = std::filesystem; +enum class Action { EXTRACT, COMPRESS }; -class Opt { - private: - // clang-format off - TCLAP::CmdLine cmd_line - {"xwim - Do What I Mean Extractor", ' ', "0.5.0"}; - - TCLAP::SwitchArg arg_compress - {"c", "compress", "Compress ", cmd_line, false}; - - TCLAP::SwitchArg arg_extract - {"x", "extract", "Extract ", cmd_line, false}; - - TCLAP::ValueArg arg_out - {"o", "out", "Out ", false, fs::path{}, "A path on the filesystem", cmd_line}; - - TCLAP::UnlabeledMultiArg arg_paths - {"Paths", "Filesystem paths to extract or compress", true, "A path on the filesystem", cmd_line}; - // clang-format on - - public: - void parse(int argc, char** argv) { cmd_line.parse(argc, argv); } - - void validate() { - 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_line, e); - } catch (TCLAP::ExitException& e) { - exit(e.getExitStatus()); - } - } - } +struct UserOpt { + std::optional action; + bool interactive; + std::optional out; + std::set paths; }; +struct XwimConfig { + Action action; + std::filesystem::path output; + std::set input; +}; + +XwimConfig guess_wim(UserOpt user_opt); +void do_wim(XwimConfig); + } // namespace xwim + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + template + 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(), ""); + } +}; diff --git a/src/Xwim.cpp b/src/Xwim.cpp index ab3160c..b0564e4 100644 --- a/src/Xwim.cpp +++ b/src/Xwim.cpp @@ -14,10 +14,6 @@ #include "Archiver.hpp" #include "Common.hpp" -namespace xwim { -using namespace std; -namespace fs = std::filesystem; - #if defined(unix) || defined(__unix__) || defined(__unix) std::string default_extension = ".tar.gz"; #elif defined(_win32) || defined(__win32__) || defined(__windows__) @@ -26,6 +22,10 @@ std::string default_extension = ".zip"; std::string default_extension = ".zip"; #endif +namespace xwim { +using namespace std; +namespace fs = std::filesystem; + Xwim::Xwim() : action{Action::UNKNOWN} {} void Xwim::try_infer() { diff --git a/src/Xwim.hpp b/src/Xwim.hpp index 6741bb7..318f059 100644 --- a/src/Xwim.hpp +++ b/src/Xwim.hpp @@ -9,13 +9,14 @@ #include #include "Common.hpp" +#include "Opt.hpp" #include "Archiver.hpp" namespace xwim { using namespace std; namespace fs = std::filesystem; -enum class Action { UNKNOWN, EXTRACT, COMPRESS }; +Xwim xwim(UserOpt user_opt); class Xwim { private: @@ -43,21 +44,3 @@ class Xwim { }; } // namespace xwim - -template <> -struct fmt::formatter { - constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } - - template - 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(), ""); - } -}; diff --git a/src/main.cpp b/src/main.cpp index e3e28da..f27b3f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,31 +1,69 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include "Common.hpp" -#include "Opt.hpp" #include "Log.hpp" +#include "Opt.hpp" #include "Xwim.hpp" using namespace xwim; using namespace std; +template <> +struct TCLAP::ArgTraits { + 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 ", cmd_line, false}; + + TCLAP::SwitchArg arg_extract + {"x", "extract", "Extract ", cmd_line, false}; + + TCLAP::SwitchArg arg_noninteractive + {"ni", "noninteractive", "Fail if action cannot be determined", cmd_line, false}; + + TCLAP::ValueArg arg_out + {"o", "out", "Out ", false, std::filesystem::path{}, "A path on the filesystem", cmd_line}; + + TCLAP::UnlabeledMultiArg 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{arg_paths.getValue().begin(), arg_paths.getValue().end()}; + + return user_opt; +} + int main(int argc, char** argv) { log::init(); - Opt opt; - opt.parse(argc, argv); - opt.validate(); - - Xwim xwim{}; - - try { - xwim.dwim(); - } catch (XwimError& e) { - spdlog::error(e.what()); - } + UserOpt user_opt = parse_args(argc, argv); + XwimConfig xwim_config = guess_wim(user_opt); + do_wim(xwim_config); } diff --git a/src/meson.build b/src/meson.build index 1f6588c..0062962 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,5 @@ xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp'] +xwim_dwim = ['dwim/Opt.cpp'] xwim_archiver = ['archiver/LibArchiver.cpp'] 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('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)