From bcf1c64639e09495d67711fcfd3d13de8b629d08 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 May 2020 12:47:44 -0400 Subject: [PATCH 1/5] merged tools:: structures into the actual tools renamed stylesheets versions --- mob.ini | 8 +-- src/conf.cpp | 55 +++++--------------- src/conf.h | 93 ++------------------------------- src/env.cpp | 3 +- src/op.cpp | 5 +- src/tasks/boost.cpp | 8 +-- src/tasks/boost_di.cpp | 2 +- src/tasks/bzip2.cpp | 2 +- src/tasks/explorerpp.cpp | 2 +- src/tasks/fmt.cpp | 2 +- src/tasks/gtest.cpp | 4 +- src/tasks/libbsarch.cpp | 2 +- src/tasks/libffi.cpp | 2 +- src/tasks/libloot.cpp | 4 +- src/tasks/lz4.cpp | 9 ++-- src/tasks/modorganizer.cpp | 10 ++-- src/tasks/ncc.cpp | 2 +- src/tasks/nmm.cpp | 4 +- src/tasks/openssl.cpp | 6 +-- src/tasks/pyqt.cpp | 12 ++--- src/tasks/python.cpp | 9 ++-- src/tasks/sevenz.cpp | 2 +- src/tasks/sip.cpp | 4 +- src/tasks/spdlog.cpp | 4 +- src/tasks/stylesheets.cpp | 33 +++++++++--- src/tasks/tasks.h | 10 +++- src/tasks/usvfs.cpp | 6 +-- src/tasks/zlib.cpp | 2 +- src/tools/cmake.cpp | 37 +++++++------ src/tools/extractor.cpp | 11 ++-- src/tools/git.cpp | 40 +++++++++----- src/tools/jom.cpp | 7 ++- src/tools/msbuild.cpp | 11 ++-- src/tools/patcher.cpp | 7 ++- src/tools/tools.cpp | 104 +++++++++++++++++++++++++++++++++++-- src/tools/tools.h | 73 +++++++++++++++++++++++--- 36 files changed, 354 insertions(+), 241 deletions(-) diff --git a/mob.ini b/mob.ini index 29966c8..a7636d7 100644 --- a/mob.ini +++ b/mob.ini @@ -55,10 +55,10 @@ sip = 5.1.2 pyqt_sip = 12.7.2 explorerpp = 1.3.5 -ss_6788_paper_lad = 6.0 -ss_6788_paper_automata = 2.2 -ss_6788_paper_mono = 2.1 -ss_6788_1809_dark_mode = 2.0 +ss_paper_lad_6788 = 6.0 +ss_paper_automata_6788 = 2.2 +ss_paper_mono_6788 = 2.1 +ss_dark_mode_1809_6788 = 2.0 [paths] third_party = diff --git a/src/conf.cpp b/src/conf.cpp index b49c54f..a2ec743 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -3,6 +3,7 @@ #include "utility.h" #include "context.h" #include "process.h" +#include "tools/tools.h" namespace mob { @@ -154,12 +155,12 @@ bool conf::by_name_bool(const std::string& name) } -bool prebuilt::by_name(const std::string& s) +bool prebuilt_by_name(const std::string& task) { - return get("prebuilt", g_prebuilt, s); + return get("prebuilt", g_prebuilt, task); } -const std::string& versions::by_name(const std::string& s) +const std::string& version_by_name(const std::string& s) { return get("version", g_versions, s); } @@ -206,34 +207,6 @@ const fs::path& conf::log_file() } -namespace tools -{ - fs::path perl::binary() { return tool_by_name("perl"); } - fs::path msbuild::binary() { return tool_by_name("msbuild"); } - fs::path devenv::binary() { return tool_by_name("devenv"); } - fs::path cmake::binary() { return tool_by_name("cmake"); } - fs::path git::binary() { return tool_by_name("git"); } - fs::path sevenz::binary() { return tool_by_name("sevenz"); } - fs::path jom::binary() { return tool_by_name("jom"); } - fs::path nasm::binary() { return tool_by_name("nasm"); } - fs::path patch::binary() { return tool_by_name("patch"); } - fs::path nuget::binary() { return tool_by_name("nuget"); } - - fs::path vs::installation_path() { return paths::by_name("vs"); } - fs::path vs::vswhere() { return tool_by_name("vswhere"); } - fs::path vs::vcvars() { return tool_by_name("vcvars"); } - std::string vs::version() { return versions::by_name("vs"); } - std::string vs::year() { return versions::by_name("vs_year"); } - std::string vs::toolset() { return versions::by_name("vs_toolset"); } - std::string vs::sdk() { return versions::by_name("sdk"); } - - fs::path qt::installation_path() { return paths::by_name("qt_install"); } - fs::path qt::bin_path() { return paths::by_name("qt_bin"); } - std::string qt::version() { return versions::by_name("qt"); } - std::string qt::vs_version() { return versions::by_name("qt_vs"); } -} - - template bool parse_value(const std::string& s, T& out) { @@ -424,8 +397,8 @@ bool find_qmake(fs::path& check) // try Qt/Qt5.14.2/msvc*/bin/qmake.exe if (try_parts(check, { "Qt", - "Qt" + tools::qt::version(), - "msvc" + tools::qt::vs_version() + "_64", + "Qt" + qt::version(), + "msvc" + qt::vs_version() + "_64", "bin", "qmake.exe"})) { @@ -435,8 +408,8 @@ bool find_qmake(fs::path& check) // try Qt/5.14.2/msvc*/bin/qmake.exe if (try_parts(check, { "Qt", - tools::qt::version(), - "msvc" + tools::qt::vs_version() + "_64", + qt::version(), + "msvc" + qt::vs_version() + "_64", "bin", "qmake.exe"})) { @@ -499,7 +472,7 @@ fs::path find_qt() void validate_qt() { - fs::path p = tools::qt::installation_path(); + fs::path p = qt::installation_path(); if (!try_qt_location(p)) gcx().bail_out(context::conf, "qt path {} doesn't exist", p); @@ -585,12 +558,12 @@ fs::path find_temp_dir() fs::path find_vs() { if (conf::dry()) - return tools::vs::vswhere(); + return vs::vswhere(); auto p = process() - .binary(tools::vs::vswhere()) + .binary(vs::vswhere()) .arg("-prerelease") - .arg("-version", tools::vs::version()) + .arg("-version", vs::version()) .arg("-property", "installationPath") .stdout_flags(process::keep_in_string) .stderr_flags(process::inherit); @@ -636,7 +609,7 @@ void find_vcvars() if (bat.empty()) { - bat = tools::vs::installation_path() + bat = vs::installation_path() / "VC" / "Auxiliary" / "Build" / "vcvarsall.bat"; if (!try_vcvars(bat)) @@ -918,7 +891,7 @@ void init_options(const fs::path& ini, const std::vector& opts) set_path_if_empty("temp_dir", find_temp_dir); set_path_if_empty("patches", find_in_root("patches")); set_path_if_empty("licenses", find_in_root("licenses")); - set_path_if_empty("qt_bin", tools::qt::installation_path() / "bin"); + set_path_if_empty("qt_bin", qt::installation_path() / "bin"); find_vcvars(); validate_qt(); diff --git a/src/conf.h b/src/conf.h index 1a2afee..c89d764 100644 --- a/src/conf.h +++ b/src/conf.h @@ -9,80 +9,6 @@ namespace mob #define VALUE_BOOL(NAME) \ static bool NAME() { return by_name_bool(#NAME); } - -namespace tools -{ - struct perl - { - static fs::path binary(); - }; - - struct msbuild - { - static fs::path binary(); - }; - - struct devenv - { - static fs::path binary(); - }; - - struct cmake - { - static fs::path binary(); - }; - - struct git - { - static fs::path binary(); - }; - - struct sevenz - { - static fs::path binary(); - }; - - struct jom - { - static fs::path binary(); - }; - - struct nasm - { - static fs::path binary(); - }; - - struct patch - { - static fs::path binary(); - }; - - struct nuget - { - static fs::path binary(); - }; - - struct vs - { - static fs::path installation_path(); - static fs::path vswhere(); - static fs::path vcvars(); - static std::string version(); - static std::string year(); - static std::string toolset(); - static std::string sdk(); - }; - - struct qt - { - static fs::path installation_path(); - static fs::path bin_path(); - static std::string version(); - static std::string vs_version(); - }; -}; - - struct conf { static void set_output_log_level(int i); @@ -105,21 +31,6 @@ struct conf VALUE_BOOL(rebuild); }; -struct prebuilt -{ - static bool by_name(const std::string& s); -}; - -struct versions -{ - static const std::string& by_name(const std::string& s); - - VALUE(ss_6788_paper_lad); - VALUE(ss_6788_paper_automata); - VALUE(ss_6788_paper_mono); - VALUE(ss_6788_1809_dark_mode); -}; - struct paths { static const fs::path& by_name(const std::string& s); @@ -152,6 +63,10 @@ struct paths #undef VALUE +bool prebuilt_by_name(const std::string& task); +const std::string& version_by_name(const std::string& s); +const fs::path& tool_by_name(const std::string& s); + void init_options(const fs::path& ini, const std::vector& opts); bool verify_options(); void dump_options(); diff --git a/src/env.cpp b/src/env.cpp index 593b535..a683b27 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -4,6 +4,7 @@ #include "process.h" #include "op.h" #include "context.h" +#include "tools/tools.h" namespace mob { @@ -33,7 +34,7 @@ env get_vcvars_env(arch a) // "vcvarsall.bat" amd64 && set > temp_file const std::string cmd = - "\"" + path_to_utf8(tools::vs::vcvars()) + "\" " + arch_s + + "\"" + path_to_utf8(vs::vcvars()) + "\" " + arch_s + " && set > \"" + path_to_utf8(tmp) + "\""; process::raw(gcx(), cmd) diff --git a/src/op.cpp b/src/op.cpp index 65fe884..c8dfd3f 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -4,6 +4,7 @@ #include "conf.h" #include "context.h" #include "process.h" +#include "tools/tools.h" namespace mob::op { @@ -487,7 +488,7 @@ void archive_from_glob( op::create_directories(cx, dest_file.parent_path()); auto p = process() - .binary(tools::sevenz::binary()) + .binary(extractor::binary()) .arg("a") .arg(dest_file) .arg("-r") @@ -543,7 +544,7 @@ void archive_from_files( op::create_directories(cx, dest_file.parent_path()); auto p = process() - .binary(tools::sevenz::binary()) + .binary(extractor::binary()) .arg("a") .arg(dest_file) .arg("@", list_file, process::nospace) diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp index 1d6099a..d6fd640 100644 --- a/src/tasks/boost.cpp +++ b/src/tasks/boost.cpp @@ -11,17 +11,17 @@ boost::boost() const std::string& boost::version() { - return versions::by_name("boost"); + return version_by_name("boost"); } const std::string& boost::version_vs() { - return versions::by_name("boost_vs"); + return version_by_name("boost_vs"); } bool boost::prebuilt() { - return prebuilt::by_name("boost"); + return prebuilt_by_name("boost"); } fs::path boost::source_path() @@ -152,7 +152,7 @@ void boost::do_b2( .arg("address-model=", address_model_for_arch(a)) .arg("link=", link) .arg("runtime-link=", runtime_link) - .arg("toolset=", "msvc-" + tools::vs::toolset()) + .arg("toolset=", "msvc-" + vs::toolset()) .arg("--user-config=", config_jam_file()) .arg("--stagedir=", root_lib_path(a)) .arg("--libdir=", root_lib_path(a)) diff --git a/src/tasks/boost_di.cpp b/src/tasks/boost_di.cpp index f07c088..b486dd4 100644 --- a/src/tasks/boost_di.cpp +++ b/src/tasks/boost_di.cpp @@ -27,7 +27,7 @@ fs::path boost_di::source_path() void boost_di::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("boost-experimental", "di")) .branch("cpp14") .output(source_path())); diff --git a/src/tasks/bzip2.cpp b/src/tasks/bzip2.cpp index 19a3456..6c10090 100644 --- a/src/tasks/bzip2.cpp +++ b/src/tasks/bzip2.cpp @@ -11,7 +11,7 @@ bzip2::bzip2() const std::string& bzip2::version() { - return versions::by_name("bzip2"); + return version_by_name("bzip2"); } bool bzip2::prebuilt() diff --git a/src/tasks/explorerpp.cpp b/src/tasks/explorerpp.cpp index f1e8bb1..7689678 100644 --- a/src/tasks/explorerpp.cpp +++ b/src/tasks/explorerpp.cpp @@ -11,7 +11,7 @@ explorerpp::explorerpp() const std::string& explorerpp::version() { - return versions::by_name("explorerpp"); + return version_by_name("explorerpp"); } bool explorerpp::prebuilt() diff --git a/src/tasks/fmt.cpp b/src/tasks/fmt.cpp index 73b5594..b2b3bf4 100644 --- a/src/tasks/fmt.cpp +++ b/src/tasks/fmt.cpp @@ -11,7 +11,7 @@ fmt::fmt() const std::string& fmt::version() { - return versions::by_name("fmt"); + return version_by_name("fmt"); } bool fmt::prebuilt() diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 10f7509..6379f7e 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -11,7 +11,7 @@ gtest::gtest() const std::string& gtest::version() { - return versions::by_name("gtest"); + return version_by_name("gtest"); } bool gtest::prebuilt() @@ -31,7 +31,7 @@ void gtest::do_clean_for_rebuild() void gtest::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("google", "googletest")) .branch(version()) .output(source_path())); diff --git a/src/tasks/libbsarch.cpp b/src/tasks/libbsarch.cpp index 169bb9d..7e4b54f 100644 --- a/src/tasks/libbsarch.cpp +++ b/src/tasks/libbsarch.cpp @@ -11,7 +11,7 @@ libbsarch::libbsarch() const std::string& libbsarch::version() { - return versions::by_name("libbsarch"); + return version_by_name("libbsarch"); } bool libbsarch::prebuilt() diff --git a/src/tasks/libffi.cpp b/src/tasks/libffi.cpp index 11d7cf8..4e1b58c 100644 --- a/src/tasks/libffi.cpp +++ b/src/tasks/libffi.cpp @@ -27,7 +27,7 @@ fs::path libffi::source_path() void libffi::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("python","cpython-bin-deps")) .branch("libffi") .output(source_path())); diff --git a/src/tasks/libloot.cpp b/src/tasks/libloot.cpp index 44c6e73..0147c5e 100644 --- a/src/tasks/libloot.cpp +++ b/src/tasks/libloot.cpp @@ -11,12 +11,12 @@ libloot::libloot() const std::string& libloot::version() { - return versions::by_name("libloot"); + return version_by_name("libloot"); } const std::string& libloot::hash() { - return versions::by_name("libloot_hash"); + return version_by_name("libloot_hash"); } bool libloot::prebuilt() diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index c0c0e7b..14f7465 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -11,12 +11,12 @@ lz4::lz4() const std::string& lz4::version() { - return versions::by_name("lz4"); + return version_by_name("lz4"); } bool lz4::prebuilt() { - return prebuilt::by_name("lz4"); + return prebuilt_by_name("lz4"); } fs::path lz4::source_path() @@ -72,12 +72,13 @@ void lz4::build_and_install_prebuilt() void lz4::fetch_from_source() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("lz4","lz4")) .branch(version()) .output(source_path())); - run_tool(devenv_upgrade(solution_file())); + run_tool(vs(vs::upgrade) + .solution(solution_file())); } void lz4::build_and_install_from_source() diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp index 830d593..92f0251 100644 --- a/src/tasks/modorganizer.cpp +++ b/src/tasks/modorganizer.cpp @@ -59,7 +59,7 @@ void modorganizer::do_fetch() { initialize_super(super_path()); - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url(conf::mo_org(), repo_)) .branch(conf::mo_branch()) .output(this_source_path())); @@ -71,7 +71,7 @@ void modorganizer::do_build_and_install() std::scoped_lock lock(g_super_mutex); run_tool(process_runner(process() - .binary(tools::git::binary()) + .binary(git::binary()) .arg("-c", "core.autocrlf=false") .arg("submodule") .arg("--quiet") @@ -102,7 +102,7 @@ void modorganizer::do_build_and_install() .def("SPDLOG_ROOT", spdlog::source_path()) .def("LOOT_PATH", libloot::source_path()) .def("LZ4_ROOT", lz4::source_path()) - .def("QT_ROOT", tools::qt::installation_path()) + .def("QT_ROOT", qt::installation_path()) .def("ZLIB_ROOT", zlib::source_path()) .def("PYTHON_ROOT", python::source_path()) .def("SEVENZ_ROOT", sevenz::source_path()) @@ -137,7 +137,7 @@ void modorganizer::initialize_super(const fs::path& super_root) cx().trace(context::generic, "checking super"); auto p = process() - .binary(tools::git::binary()) + .binary(git::binary()) .arg("rev-parse") .arg("--is-inside-work-tree") .stderr_filter([](process::filter& f) @@ -157,7 +157,7 @@ void modorganizer::initialize_super(const fs::path& super_root) cx().trace(context::generic, "initializing super"); run_tool(process_runner(process() - .binary(tools::git::binary()) + .binary(git::binary()) .arg("init") .cwd(super_root))); } diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index c2ee1e0..1d75c32 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -33,7 +33,7 @@ void ncc::do_clean_for_rebuild() void ncc::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url(conf::mo_org(), "modorganizer-NCC")) .branch(conf::mo_branch()) .output(source_path())); diff --git a/src/tasks/nmm.cpp b/src/tasks/nmm.cpp index aa4ecc6..9f00752 100644 --- a/src/tasks/nmm.cpp +++ b/src/tasks/nmm.cpp @@ -11,7 +11,7 @@ nmm::nmm() const std::string& nmm::version() { - return versions::by_name("nmm"); + return version_by_name("nmm"); } bool nmm::prebuilt() @@ -31,7 +31,7 @@ void nmm::do_clean_for_rebuild() void nmm::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("Nexus-Mods", "Nexus-Mod-Manager")) .branch(version()) .output(source_path())); diff --git a/src/tasks/openssl.cpp b/src/tasks/openssl.cpp index b69142d..c4c87e3 100644 --- a/src/tasks/openssl.cpp +++ b/src/tasks/openssl.cpp @@ -11,12 +11,12 @@ openssl::openssl() const std::string& openssl::version() { - return versions::by_name("openssl"); + return version_by_name("openssl"); } bool openssl::prebuilt() { - return prebuilt::by_name("openssl"); + return prebuilt_by_name("openssl"); } fs::path openssl::source_path() @@ -106,7 +106,7 @@ void openssl::build_and_install_from_source() void openssl::configure() { run_tool(process_runner(process() - .binary(tools::perl::binary()) + .binary(perl::binary()) .arg("Configure") .arg("VC-WIN64A") .arg("--openssldir=", build_path()) diff --git a/src/tasks/pyqt.cpp b/src/tasks/pyqt.cpp index a21767a..6982291 100644 --- a/src/tasks/pyqt.cpp +++ b/src/tasks/pyqt.cpp @@ -11,17 +11,17 @@ pyqt::pyqt() const std::string& pyqt::version() { - return versions::by_name("pyqt"); + return version_by_name("pyqt"); } const std::string& pyqt::builder_version() { - return versions::by_name("pyqt_builder"); + return version_by_name("pyqt_builder"); } bool pyqt::prebuilt() { - return prebuilt::by_name("pyqt"); + return prebuilt_by_name("pyqt"); } fs::path pyqt::source_path() @@ -106,7 +106,7 @@ void pyqt::sip_build() { auto pyqt_env = env::vs_x64() .append_path({ - tools::qt::bin_path(), + qt::bin_path(), python::build_path(), python::source_path(), python::scripts_path()}) @@ -202,12 +202,12 @@ void pyqt::copy_files() // these are needed by PyQt5 while building several projects op::copy_file_to_dir_if_better(cx(), - tools::qt::bin_path() / "Qt5Core.dll", + qt::bin_path() / "Qt5Core.dll", python::build_path(), op::unsafe); // source file is outside prefix op::copy_file_to_dir_if_better(cx(), - tools::qt::bin_path() / "Qt5Xml.dll", + qt::bin_path() / "Qt5Xml.dll", python::build_path(), op::unsafe); // source file is outside prefix } diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index 3e50968..2c3b130 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -11,12 +11,12 @@ python::python() const std::string& python::version() { - return versions::by_name("python"); + return version_by_name("python"); } bool python::prebuilt() { - return prebuilt::by_name("python"); + return prebuilt_by_name("python"); } python::version_info python::parsed_version() @@ -109,12 +109,13 @@ void python::build_and_install_prebuilt() void python::fetch_from_source() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("python", "cpython")) .branch(version()) .output(source_path())); - run_tool(devenv_upgrade(solution_file())); + run_tool(vs(vs::upgrade) + .solution(solution_file())); } void python::build_and_install_from_source() diff --git a/src/tasks/sevenz.cpp b/src/tasks/sevenz.cpp index ca87718..2f87cec 100644 --- a/src/tasks/sevenz.cpp +++ b/src/tasks/sevenz.cpp @@ -11,7 +11,7 @@ sevenz::sevenz() const std::string& sevenz::version() { - return versions::by_name("sevenz"); + return version_by_name("sevenz"); } bool sevenz::prebuilt() diff --git a/src/tasks/sip.cpp b/src/tasks/sip.cpp index 4fca5ec..154e879 100644 --- a/src/tasks/sip.cpp +++ b/src/tasks/sip.cpp @@ -11,12 +11,12 @@ sip::sip() const std::string& sip::version() { - return versions::by_name("sip"); + return version_by_name("sip"); } const std::string& sip::version_for_pyqt() { - return versions::by_name("pyqt_sip"); + return version_by_name("pyqt_sip"); } bool sip::prebuilt() diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp index ca59df1..bf9c6a3 100644 --- a/src/tasks/spdlog.cpp +++ b/src/tasks/spdlog.cpp @@ -11,7 +11,7 @@ spdlog::spdlog() const std::string& spdlog::version() { - return versions::by_name("spdlog"); + return version_by_name("spdlog"); } bool spdlog::prebuilt() @@ -26,7 +26,7 @@ fs::path spdlog::source_path() void spdlog::do_fetch() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url("gabime", "spdlog")) .branch(version()) .output(source_path())); diff --git a/src/tasks/stylesheets.cpp b/src/tasks/stylesheets.cpp index 323a95e..b1bf1f6 100644 --- a/src/tasks/stylesheets.cpp +++ b/src/tasks/stylesheets.cpp @@ -15,6 +15,27 @@ const std::string& stylesheets::version() return s; } +std::string stylesheets::paper_lad_6788_version() +{ + return version_by_name("ss_paper_lad_6788"); +} + +std::string stylesheets::paper_automata_6788_version() +{ + return version_by_name("ss_paper_automata_6788"); +} + +std::string stylesheets::paper_mono_6788_version() +{ + return version_by_name("ss_paper_mono_6788"); +} + +std::string stylesheets::dark_mode_1809_6788_version() +{ + return version_by_name("ss_dark_mode_1809_6788"); +} + + bool stylesheets::prebuilt() { return false; @@ -65,29 +86,29 @@ std::vector stylesheets::releases() { "6788-00", "paper-light-and-dark", - versions::ss_6788_paper_lad(), - versions::ss_6788_paper_lad(), + stylesheets::paper_lad_6788_version(), + stylesheets::paper_lad_6788_version(), }, { "6788-00", "paper-automata", - versions::ss_6788_paper_automata(), + paper_automata_6788_version(), "Paper-Automata" }, { "6788-00", "paper-mono", - versions::ss_6788_paper_mono(), + paper_mono_6788_version(), "Paper-Mono" }, { "6788-00", "1809-dark-mode", - versions::ss_6788_1809_dark_mode(), - versions::ss_6788_1809_dark_mode() + dark_mode_1809_6788_version(), + dark_mode_1809_6788_version() } }; } diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h index a2f93b6..7c3da02 100644 --- a/src/tasks/tasks.h +++ b/src/tasks/tasks.h @@ -501,11 +501,17 @@ class stylesheets : public basic_task public: stylesheets(); - static const std::string& version(); static bool prebuilt(); - static fs::path source_path(); + static std::string paper_lad_6788_version(); + static std::string paper_automata_6788_version(); + static std::string paper_mono_6788_version(); + static std::string dark_mode_1809_6788_version(); + + // dummy, doesn't applly + static const std::string& version(); + protected: void do_fetch() override; void do_build_and_install() override; diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp index d20e83f..c8c6539 100644 --- a/src/tasks/usvfs.cpp +++ b/src/tasks/usvfs.cpp @@ -11,12 +11,12 @@ usvfs::usvfs() const std::string& usvfs::version() { - return versions::by_name("usvfs"); + return version_by_name("usvfs"); } bool usvfs::prebuilt() { - return prebuilt::by_name("usvfs"); + return prebuilt_by_name("usvfs"); } fs::path usvfs::source_path() @@ -65,7 +65,7 @@ void usvfs::build_and_install_prebuilt() void usvfs::fetch_from_source() { - run_tool(git_clone() + run_tool(git(git::clone_or_pull) .url(make_github_url(conf::mo_org(), "usvfs")) .branch(version()) .output(source_path())); diff --git a/src/tasks/zlib.cpp b/src/tasks/zlib.cpp index 1958525..13ae615 100644 --- a/src/tasks/zlib.cpp +++ b/src/tasks/zlib.cpp @@ -11,7 +11,7 @@ zlib::zlib() const std::string& zlib::version() { - return versions::by_name("zlib"); + return version_by_name("zlib"); } bool zlib::prebuilt() diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp index 0227a3e..7b0c918 100644 --- a/src/tools/cmake.cpp +++ b/src/tools/cmake.cpp @@ -8,7 +8,26 @@ cmake::cmake() : basic_process_runner("cmake"), gen_(jom), arch_(arch::def) { process_ - .binary(tools::cmake::binary()); + .binary(binary()); +} + +fs::path cmake::binary() +{ + return tool_by_name("cmake"); +} + +void cmake::clean(const context& cx, const fs::path& root) +{ + cx.trace(context::rebuild, "deleting all generator directories"); + + for (auto&& [k, g] : all_generators()) + { + op::delete_directory(cx, + root / g.output_dir(arch::x86), op::optional); + + op::delete_directory(cx, + root / g.output_dir(arch::x64), op::optional); + } } cmake& cmake::generator(generators g) @@ -58,20 +77,6 @@ fs::path cmake::result() const return output_; } -void cmake::clean(const context& cx, const fs::path& root) -{ - cx.trace(context::rebuild, "deleting all generator directories"); - - for (auto&& [k, g] : all_generators()) - { - op::delete_directory(cx, - root / g.output_dir(arch::x86), op::optional); - - op::delete_directory(cx, - root / g.output_dir(arch::x64), op::optional); - } -} - void cmake::do_run() { if (root_.empty()) @@ -110,7 +115,7 @@ const std::map& cmake::all_generators() { generators::vs, { "vsbuild", - "Visual Studio " + tools::vs::version() + " " + tools::vs::year(), + "Visual Studio " + vs::version() + " " + vs::year(), "Win32", "x64" }} diff --git a/src/tools/extractor.cpp b/src/tools/extractor.cpp index e7b6ef2..356f794 100644 --- a/src/tools/extractor.cpp +++ b/src/tools/extractor.cpp @@ -9,6 +9,11 @@ extractor::extractor() { } +fs::path extractor::binary() +{ + return tool_by_name("sevenz"); +} + extractor& extractor::file(const fs::path& file) { file_ = file; @@ -72,12 +77,12 @@ void extractor::do_run() cx_->trace(context::generic, "this is a tar.gz, piping"); auto extract_tar = process() - .binary(tools::sevenz::binary()) + .binary(binary()) .arg("x") .arg("-so", file_); auto extract_gz = process() - .binary(tools::sevenz::binary()) + .binary(binary()) .arg("x") .arg("-aoa") .arg("-si") @@ -89,7 +94,7 @@ void extractor::do_run() else { process_ = process() - .binary(tools::sevenz::binary()) + .binary(binary()) .arg("x") .arg("-aoa") .arg("-bd") diff --git a/src/tools/git.cpp b/src/tools/git.cpp index 67104e7..58f55eb 100644 --- a/src/tools/git.cpp +++ b/src/tools/git.cpp @@ -5,34 +5,50 @@ namespace mob { - -git_clone::git_clone() - : basic_process_runner("git") +git::git(ops o) + : basic_process_runner("git"), op_(o) { } -git_clone& git_clone::url(const mob::url& u) +fs::path git::binary() +{ + return tool_by_name("git"); +} + +git& git::url(const mob::url& u) { url_ = u; return *this; } -git_clone& git_clone::branch(const std::string& name) +git& git::branch(const std::string& name) { branch_ = name; return *this; } -git_clone& git_clone::output(const fs::path& dir) +git& git::output(const fs::path& dir) { where_ = dir; return *this; } -void git_clone::do_run() +void git::do_run() +{ + switch (op_) + { + case clone_or_pull: + do_clone_or_pull(); + + default: + cx_->bail_out(context::generic, "git unknown op {}", op_); + } +} + +void git::do_clone_or_pull() { if (url_.empty() || where_.empty()) - bail_out("git_clone missing parameters"); + bail_out("git missing parameters"); if (conf::redownload() || conf::reextract()) { @@ -48,10 +64,10 @@ void git_clone::do_run() pull(); } -void git_clone::clone() +void git::clone() { process_ = process() - .binary(tools::git::binary()) + .binary(binary()) .stderr_level(context::level::trace) .arg("clone") .arg("--recurse-submodules") @@ -65,10 +81,10 @@ void git_clone::clone() execute_and_join(); } -void git_clone::pull() +void git::pull() { process_ = process() - .binary(tools::git::binary()) + .binary(binary()) .stderr_level(context::level::trace) .arg("pull") .arg("--recurse-submodules") diff --git a/src/tools/jom.cpp b/src/tools/jom.cpp index 2333e9f..5c9fffe 100644 --- a/src/tools/jom.cpp +++ b/src/tools/jom.cpp @@ -10,6 +10,11 @@ jom::jom() { } +fs::path jom::binary() +{ + return tool_by_name("jom"); +} + jom& jom::path(const fs::path& p) { process_.cwd(p); @@ -55,7 +60,7 @@ void jom::do_run() } process_ - .binary(tools::jom::binary()) + .binary(binary()) .stderr_filter([](process::filter& f) { if (f.line.find("empower your cores") != std::string::npos) diff --git a/src/tools/msbuild.cpp b/src/tools/msbuild.cpp index 285ba46..209b5c6 100644 --- a/src/tools/msbuild.cpp +++ b/src/tools/msbuild.cpp @@ -11,6 +11,11 @@ msbuild::msbuild() : { } +fs::path msbuild::binary() +{ + return tool_by_name("msbuild"); +} + msbuild& msbuild::solution(const fs::path& sln) { sln_ = sln; @@ -61,7 +66,7 @@ int msbuild::result() const void msbuild::do_run() { // 14.2 to v142 - const auto toolset = "v" + replace_all(tools::vs::toolset(), ".", ""); + const auto toolset = "v" + replace_all(vs::toolset(), ".", ""); std::string plat; @@ -95,7 +100,7 @@ void msbuild::do_run() } process_ - .binary(tools::msbuild::binary()) + .binary(binary()) .chcp(65001) .stdout_encoding(encodings::utf8) .stderr_encoding(encodings::utf8) @@ -112,7 +117,7 @@ void msbuild::do_run() process_ .arg("-property:Configuration=", config_, process::quote) .arg("-property:PlatformToolset=" + toolset) - .arg("-property:WindowsTargetPlatformVersion=" + tools::vs::sdk()) + .arg("-property:WindowsTargetPlatformVersion=" + vs::sdk()) .arg("-property:Platform=", plat, process::quote) .arg("-verbosity:minimal", process::log_quiet) .arg("-consoleLoggerParameters:ErrorsOnly", process::log_quiet); diff --git a/src/tools/patcher.cpp b/src/tools/patcher.cpp index 56845de..e0721c7 100644 --- a/src/tools/patcher.cpp +++ b/src/tools/patcher.cpp @@ -10,6 +10,11 @@ patcher::patcher() { } +fs::path patcher::binary() +{ + return tool_by_name("patch"); +} + patcher& patcher::task(const std::string& name, bool prebuilt) { task_ = name; @@ -98,7 +103,7 @@ void patcher::do_run() void patcher::do_patch(const fs::path& patch_file) { const auto base = process() - .binary(tools::patch::binary()) + .binary(binary()) .arg("--read-only", "ignore") .arg("--strip", "0") .arg("--directory", output_) diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index 50c1c3f..6301ced 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -60,12 +60,101 @@ bool tool::interrupted() const } -devenv_upgrade::devenv_upgrade(fs::path sln) - : basic_process_runner("upgrade project"), sln_(std::move(sln)) +fs::path perl::binary() +{ + return tool_by_name("perl"); +} + +fs::path nasm::binary() +{ + return tool_by_name("nasm"); +} + +fs::path qt::installation_path() +{ + return paths::by_name("qt_install"); +} + +fs::path qt::bin_path() +{ + return paths::by_name("qt_bin"); +} + +std::string qt::version() +{ + return version_by_name("qt"); +} + +std::string qt::vs_version() +{ + return version_by_name("qt_vs"); +} + + +vs::vs(ops o) + : basic_process_runner("vs"), op_(o) { } -void devenv_upgrade::do_run() +fs::path vs::devenv_binary() +{ + return tool_by_name("devenv"); +} + +fs::path vs::installation_path() +{ + return paths::by_name("vs"); +} + +fs::path vs::vswhere() +{ + return tool_by_name("vswhere"); +} + +fs::path vs::vcvars() +{ + return tool_by_name("vcvars"); +} + +std::string vs::version() +{ + return version_by_name("vs"); +} + +std::string vs::year() +{ + return version_by_name("vs_year"); +} + +std::string vs::toolset() +{ + return version_by_name("vs_toolset"); +} + +std::string vs::sdk() +{ + return version_by_name("sdk"); +} + +vs& vs::solution(const fs::path& sln) +{ + sln_ = sln; + return *this; +} + +void vs::do_run() +{ + switch (op_) + { + case upgrade: + do_upgrade(); + + default: + cx_->bail_out(context::generic, "vs unknown op {}", op_); + } +} + +void vs::do_upgrade() { if (fs::exists(sln_.parent_path() / "UpgradeLog.htm")) { @@ -74,7 +163,7 @@ void devenv_upgrade::do_run() } process_ - .binary(tools::devenv::binary()) + .binary(devenv_binary()) .env(env::vs(arch::x64)) .arg("/upgrade") .arg(sln_); @@ -87,12 +176,17 @@ nuget::nuget(fs::path sln) : basic_process_runner("nuget"), sln_(std::move(sln)) { process_ - .binary(tools::nuget::binary()) + .binary(binary()) .arg("restore") .arg(sln_) .cwd(sln_.parent_path()); } +fs::path nuget::binary() +{ + return tool_by_name("nuget"); +} + void nuget::do_run() { execute_and_join(); diff --git a/src/tools/tools.h b/src/tools/tools.h index bb3b95d..a7e0fa6 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -41,6 +41,24 @@ private: }; +struct perl +{ + static fs::path binary(); +}; + +struct nasm +{ + static fs::path binary(); +}; + +struct qt +{ + static fs::path installation_path(); + static fs::path bin_path(); + static std::string version(); + static std::string vs_version(); +}; + class downloader : public tool { @@ -111,23 +129,33 @@ private: }; -class git_clone : public basic_process_runner +class git : public basic_process_runner { public: - git_clone(); + enum ops + { + clone_or_pull + }; - git_clone& url(const mob::url& u); - git_clone& branch(const std::string& name); - git_clone& output(const fs::path& dir); + + git(ops o); + + static fs::path binary(); + + git& url(const mob::url& u); + git& branch(const std::string& name); + git& output(const fs::path& dir); protected: void do_run() override; private: + ops op_; mob::url url_; std::string branch_; fs::path where_; + void do_clone_or_pull(); void clone(); void pull(); }; @@ -137,6 +165,9 @@ class extractor : public basic_process_runner { public: extractor(); + + static fs::path binary(); + extractor& file(const fs::path& file); extractor& output(const fs::path& dir); @@ -156,6 +187,8 @@ class patcher : public basic_process_runner public: patcher(); + static fs::path binary(); + patcher& task(const std::string& name, bool prebuilt=false); patcher& file(const fs::path& p); patcher& root(const fs::path& dir); @@ -184,6 +217,7 @@ public: cmake(); + static fs::path binary(); static void clean(const context& cx, const fs::path& root); cmake& generator(generators g); @@ -234,6 +268,8 @@ public: jom(); + static fs::path binary(); + jom& path(const fs::path& p); jom& target(const std::string& s); jom& def(const std::string& s); @@ -264,6 +300,8 @@ public: msbuild(); + static fs::path binary(); + msbuild& solution(const fs::path& sln); msbuild& projects(const std::vector& names); msbuild& parameters(const std::vector& params); @@ -288,16 +326,35 @@ private: }; -class devenv_upgrade : public basic_process_runner +class vs : public basic_process_runner { public: - devenv_upgrade(fs::path sln); + enum ops + { + upgrade = 1 + }; + + vs(ops o); + + static fs::path devenv_binary(); + static fs::path installation_path(); + static fs::path vswhere(); + static fs::path vcvars(); + static std::string version(); + static std::string year(); + static std::string toolset(); + static std::string sdk(); + + vs& solution(const fs::path& sln); protected: void do_run() override; private: + ops op_; fs::path sln_; + + void do_upgrade(); }; @@ -306,6 +363,8 @@ class nuget : public basic_process_runner public: nuget(fs::path sln); + static fs::path binary(); + protected: void do_run() override; From 376a3cb574f8f0819b40897026ac38a0442422a2 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 May 2020 14:14:29 -0400 Subject: [PATCH 2/5] simplified options: - stopped returning references, that was just to avoid copying the string before using regex_match(), which happens like twice - everything in one map - assume the ini contains all the options, don't duplicate them within mob --- .gitignore | 1 + mob.ini | 14 +- src/commands.cpp | 2 +- src/conf.cpp | 560 +++++++++++++------------------------ src/conf.h | 46 ++- src/tasks/boost.cpp | 10 +- src/tasks/boost_di.cpp | 5 +- src/tasks/bzip2.cpp | 2 +- src/tasks/explorerpp.cpp | 2 +- src/tasks/fmt.cpp | 2 +- src/tasks/gtest.cpp | 2 +- src/tasks/libbsarch.cpp | 2 +- src/tasks/libffi.cpp | 5 +- src/tasks/libloot.cpp | 4 +- src/tasks/licenses.cpp | 5 +- src/tasks/lz4.cpp | 2 +- src/tasks/modorganizer.cpp | 5 +- src/tasks/ncc.cpp | 5 +- src/tasks/nmm.cpp | 2 +- src/tasks/openssl.cpp | 8 +- src/tasks/pyqt.cpp | 4 +- src/tasks/python.cpp | 8 +- src/tasks/sevenz.cpp | 2 +- src/tasks/sip.cpp | 10 +- src/tasks/spdlog.cpp | 2 +- src/tasks/stylesheets.cpp | 5 +- src/tasks/task.h | 9 +- src/tasks/tasks.h | 54 ++-- src/tasks/usvfs.cpp | 2 +- src/tasks/zlib.cpp | 2 +- src/tools/tools.cpp | 6 +- 31 files changed, 315 insertions(+), 473 deletions(-) diff --git a/.gitignore b/.gitignore index c29c8ef..b133cb1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /vs/.vs /vs/*.user /mob.exe +/mob.log diff --git a/mob.ini b/mob.ini index a7636d7..00413d4 100644 --- a/mob.ini +++ b/mob.ini @@ -1,9 +1,13 @@ [options] -mo_org = ModOrganizer2 -mo_branch = master +mo_org = ModOrganizer2 +mo_branch = master +dry = false +redownload = false +reextract = false +rebuild = false output_log_level = 3 -file_log_level = 5 -log_file = mob.log +file_log_level = 5 +log_file = mob.log [tools] sevenz = 7z.exe @@ -16,6 +20,7 @@ devenv = devenv.exe msbuild = msbuild.exe nuget = nuget.exe vswhere = vswhere.exe +nasm = nasm.exe vcvars = [prebuilt] @@ -76,6 +81,7 @@ install_loot = install_plugins = install_stylesheets = install_licenses = +install_pythoncore = vs = qt_install = qt_bin = diff --git a/src/commands.cpp b/src/commands.cpp index f1e1aab..72b5b38 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -146,7 +146,7 @@ int command::run() if (flags_ & requires_options) { init_options(command::common.ini, command::common.options); - dump_options(); + log_options(); if (!verify_options()) return 1; diff --git a/src/conf.cpp b/src/conf.cpp index a2ec743..1dd2f65 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -8,188 +8,101 @@ namespace mob { -using string_map = std::map; -using path_map = std::map; -using bool_map = std::map; +static const std::string default_ini_filename = "mob.ini"; -static fs::path g_ini; -const std::string default_ini_filename = "mob.ini"; - -// special case to avoid string manipulations +// special cases to avoid string manipulations static int g_output_log_level = 3; static int g_file_log_level = 5; -static fs::path g_log_file = "c:\\dev\\projects\\mob\\mob.log"; -static string_map g_options = +static std::map> g_conf; + +const std::string& get_conf(const std::string& section, const std::string& key) { - {"mo_org", "ModOrganizer2"}, - {"mo_branch", "master"}, - {"dry", "false"}, - {"redownload", "false"}, - {"reextract", "false"}, - {"rebuild", "false"}, - {"output_log_level", ""}, - {"file_log_level", ""}, - {"log_file", ""} -}; + auto sitor = g_conf.find(section); -static path_map g_tools = -{ - {"sevenz", "7z.exe"}, - {"jom", "jom.exe"}, - {"patch", "patch.exe"}, - {"nuget", "nuget.exe"}, - {"vswhere", "vswhere.exe"}, - {"perl", "perl.exe"}, - {"msbuild", "msbuild.exe"}, - {"devenv", "devenv.exe"}, - {"cmake", "cmake.exe"}, - {"git", "git.exe"}, - {"nasm", "nasm.exe"}, - {"vcvars", ""}, -}; + if (sitor == g_conf.end()) + { + gcx().bail_out(context::conf, + "conf section '{}' doesn't exist", section); + } -static bool_map g_prebuilt = -{ - {"boost", false}, - {"lz4", false}, - {"openssl", false}, - {"pyqt", false}, - {"python", false}, - {"usvfs", false} -}; + auto kitor = sitor->second.find(key); -static string_map g_versions = -{ - {"vs", ""}, - {"vs_year", ""}, - {"vs_toolset", ""}, - {"sdk", ""}, - {"sevenz", ""}, - {"zlib", ""}, - {"boost", ""}, - {"boost_vs", ""}, - {"python", ""}, - {"fmt", ""}, - {"gtest", ""}, - {"libbsarch", ""}, - {"libloot", ""}, - {"libloot_hash", ""}, - {"openssl", ""}, - {"bzip2", ""}, - {"lz4", ""}, - {"nmm", ""}, - {"spdlog", ""}, - {"usvfs", ""}, - {"qt", ""}, - {"qt_vs", ""}, - {"pyqt", ""}, - {"pyqt_builder", ""}, - {"sip", ""}, - {"pyqt_sip", ""}, - {"explorerpp", ""}, + if (kitor == sitor->second.end()) + { + gcx().bail_out(context::conf, + "key '{}' not found in section '{}'", key, section); + } - {"ss_6788_paper_lad", ""}, - {"ss_6788_paper_automata", ""}, - {"ss_6788_paper_mono", ""}, - {"ss_6788_1809_dark_mode", ""} -}; - -static path_map g_paths = -{ - {"third_party" , ""}, - {"prefix", ""}, - {"cache", ""}, - {"build", ""}, - {"install", ""}, - {"install_bin", ""}, - {"install_libs", ""}, - {"install_pdbs", ""}, - {"install_dlls", ""}, - {"install_loot", ""}, - {"install_plugins", ""}, - {"install_stylesheets", ""}, - {"install_licenses", ""}, - {"install_pythoncore", ""}, - {"patches", ""}, - {"licenses", ""}, - {"vs", ""}, - {"qt_install", ""}, - {"qt_bin", ""}, - {"pf_x86", ""}, - {"pf_x64", ""}, - {"temp_dir", ""}, -}; - - -template -const typename Map::mapped_type& get( - const std::string& map_name, const Map& map, - const std::string& name) -{ - auto itor = map.find(name); - - if (itor == map.end()) - gcx().bail_out(context::conf, "{} '{}' doesn't exist", map_name, name); - - return itor->second; + return kitor->second; } - -const fs::path& tool_by_name(const std::string& name) +void set_conf( + const std::string& section, + const std::string& key, const std::string& value) { - return get("tool", g_tools, name); + auto sitor = g_conf.find(section); + + if (sitor == g_conf.end()) + { + gcx().bail_out(context::conf, + "conf section '{}' doesn't exist", section); + } + + auto kitor = sitor->second.find(key); + + if (kitor == sitor->second.end()) + { + gcx().bail_out(context::conf, + "key '{}' not found in section '{}'", key, section); + } + + kitor->second = value; } -const std::string& conf::by_name(const std::string& name) +void add_conf( + const std::string& section, + const std::string& key, const std::string& value) { - return get("option", g_options, name); + g_conf[section][key] = value; } -bool conf::by_name_bool(const std::string& name) +bool prebuilt_by_name(const std::string& task) { + std::istringstream iss(get_conf("prebuilt", task)); bool b; - std::istringstream iss(by_name(name)); iss >> std::boolalpha >> b; return b; } - -bool prebuilt_by_name(const std::string& task) +std::string version_by_name(const std::string& s) { - return get("prebuilt", g_prebuilt, task); + return get_conf("versions", s); } -const std::string& version_by_name(const std::string& s) +fs::path tool_by_name(const std::string& name) { - return get("version", g_versions, s); + return get_conf("tools", name); } -const fs::path& paths::by_name(const std::string& s) +fs::path path_by_name(const std::string& s) { - return get("path", g_paths, s); + return get_conf("paths", s); } -void conf::set_output_log_level(int i) +std::string conf_by_name(const std::string& name) { - if (i < 0 || i > 6) - gcx().bail_out(context::generic, "bad output log level {}", i); - - g_output_log_level = i; + return get_conf("options", name); } -void conf::set_file_log_level(int i) +bool bool_conf_by_name(const std::string& name) { - if (i < 0 || i > 6) - gcx().bail_out(context::generic, "bad file log level {}", i); - - g_file_log_level = i; + std::istringstream iss(get_conf("options", name)); + bool b; + iss >> std::boolalpha >> b; + return b; } -void conf::set_log_file(const fs::path& p) -{ - g_log_file = p; -} int conf::output_log_level() { @@ -201,74 +114,13 @@ int conf::file_log_level() return g_file_log_level; } -const fs::path& conf::log_file() + +struct parsed_option { - return g_log_file; -} + std::string section, key, value; +}; - -template -bool parse_value(const std::string& s, T& out) -{ - out = s; - return true; -} - -template <> -bool parse_value(const std::string& s, bool& out) -{ - std::istringstream iss(s); - iss >> std::boolalpha >> out; - return !iss.bad(); -} - -template <> -bool parse_value(const std::string& s, fs::path& out) -{ - out = utf8_to_utf16(s); - return true; -} - -template -bool set_option_impl( - Map& map, const std::string& key, const std::string& value) -{ - auto itor = map.find(key); - if (itor == map.end()) - { - gcx().error(context::conf, "unknown key '{}'", key); - return false; - } - - if (!parse_value(value, itor->second)) - { - gcx().error(context::conf, "bad value '{}'", value); - return false; - } - - return true; -} - -bool set_option( - const std::string& section, - const std::string& key, const std::string& value) -{ - if (section == "options") - return set_option_impl(g_options, key, value); - else if (section == "tools") - return set_option_impl(g_tools, key, value); - else if (section == "prebuilt") - return set_option_impl(g_prebuilt, key, value); - else if (section == "versions") - return set_option_impl(g_versions, key, value); - else if (section == "paths") - return set_option_impl(g_paths, key, value); - - gcx().error(context::conf, "bad section name '{}'", section); - return false; -} - -void set_option(const std::string& s) +parsed_option parse_option(const std::string& s) { const auto slash = s.find("/"); if (slash == std::string::npos) @@ -284,37 +136,11 @@ void set_option(const std::string& s) "bad option {}, must be section/key=value", s); } - const std::string section = s.substr(0, slash); - const std::string key = s.substr(slash + 1, equal - slash - 1); - const std::string value = s.substr(equal + 1); + std::string section = s.substr(0, slash); + std::string key = s.substr(slash + 1, equal - slash - 1); + std::string value = s.substr(equal + 1); - if (set_option(section, key, value)) - { - gcx().trace(context::conf, "setting {}/{}={}", section, key, value); - } - else - { - gcx().bail_out(context::conf, - "failed to set {}/{}={}", section, key, value); - } -} - -void dump_available_options() -{ - for (auto&& [k, v] : g_options) - u8cout << "options/" << k << " = " << v << "\n"; - - for (auto&& [k, v] : g_tools) - u8cout << "tools/" << k << " = " << v << "\n"; - - for (auto&& [k, v] : g_prebuilt) - u8cout << "prebuilt/" << k << " = " << v << "\n"; - - for (auto&& [k, v] : g_versions) - u8cout << "versions/" << k << " = " << v << "\n"; - - for (auto&& [k, v] : g_paths) - u8cout << "paths/" << k << " = " << v << "\n"; + return {section, key, value}; } bool try_parts(fs::path& check, const std::vector& parts) @@ -430,7 +256,7 @@ bool try_qt_location(fs::path& check) fs::path find_qt() { - fs::path p = g_paths["qt_install"]; + fs::path p = path_by_name("qt_install"); if (!p.empty()) { @@ -477,7 +303,7 @@ void validate_qt() if (!try_qt_location(p)) gcx().bail_out(context::conf, "qt path {} doesn't exist", p); - g_paths["qt_install"] = p; + set_conf("paths", "qt_install", path_to_utf8(p)); } fs::path get_known_folder(const GUID& id) @@ -596,7 +422,7 @@ bool try_vcvars(fs::path& bat) void find_vcvars() { - fs::path& bat = g_tools["vcvars"]; + fs::path bat = tool_by_name("vcvars"); if (conf::dry()) { @@ -605,31 +431,33 @@ void find_vcvars() return; } - - - if (bat.empty()) - { - bat = vs::installation_path() - / "VC" / "Auxiliary" / "Build" / "vcvarsall.bat"; - - if (!try_vcvars(bat)) - gcx().bail_out(context::conf, "vcvars not found at {}", bat); - } else { - if (!try_vcvars(bat)) - gcx().bail_out(context::conf, "vcvars not found at {}", bat); + if (bat.empty()) + { + bat = vs::installation_path() + / "VC" / "Auxiliary" / "Build" / "vcvarsall.bat"; + + if (!try_vcvars(bat)) + gcx().bail_out(context::conf, "vcvars not found at {}", bat); + } + else + { + if (!try_vcvars(bat)) + gcx().bail_out(context::conf, "vcvars not found at {}", bat); + } } + set_conf("tools", "vcvars", path_to_utf8(bat)); gcx().trace(context::conf, "using vcvars at {}", bat); } -void ini_error(std::size_t line, const std::string& what) +void ini_error(const fs::path& ini, std::size_t line, const std::string& what) { gcx().bail_out(context::conf, "{}:{}: {}", - g_ini.filename(), (line + 1), what); + ini.filename(), (line + 1), what); } fs::path find_ini(const fs::path& ini) @@ -680,8 +508,9 @@ std::vector read_ini(const fs::path& ini) } void parse_section( - std::size_t& i, const std::vector& lines, - const std::string& section) + const fs::path& ini, std::size_t& i, + const std::vector& lines, const std::string& section, + bool add) { ++i; @@ -694,27 +523,28 @@ void parse_section( const auto sep = line.find("="); if (sep == std::string::npos) - ini_error(i, "bad line '" + line + "'"); + ini_error(ini, i, "bad line '" + line + "'"); const std::string k = trim_copy(line.substr(0, sep)); const std::string v = trim_copy(line.substr(sep + 1)); if (k.empty()) - ini_error(i, "bad line '" + line + "'"); + ini_error(ini, i, "bad line '" + line + "'"); - if (!set_option(section, k, v)) - ini_error(i, "bad line '" + line + "'"); + if (add) + add_conf(section, k, v); + else + set_conf(section, k, v); ++i; } } -void parse_ini(const fs::path& ini) +void parse_ini(const fs::path& ini, bool add) { - g_ini = find_ini(ini); - gcx().debug(context::conf, "using ini at {}", g_ini); + gcx().debug(context::conf, "using ini at {}", ini); - const auto lines = read_ini(g_ini); + const auto lines = read_ini(ini); std::size_t i = 0; for (;;) @@ -727,11 +557,11 @@ void parse_ini(const fs::path& ini) if (line.starts_with("[") && line.ends_with("]")) { const std::string section = line.substr(1, line.size() - 2); - parse_section(i, lines, section); + parse_section(ini, i, lines, section, add); } else { - ini_error(i, "bad line '" + line + "'"); + ini_error(ini, i, "bad line '" + line + "'"); } } } @@ -765,7 +595,7 @@ bool check_missing_options() return false; } - for (auto&& [k, v] : g_versions) + for (auto&& [k, v] : g_conf["versions"]) { if (v.empty()) { @@ -780,108 +610,112 @@ bool check_missing_options() template void set_path_if_empty(const std::string& k, F&& f) { - auto itor = g_paths.find(k); - if (itor == g_paths.end()) - gcx().bail_out(context::conf, "unknown path key {}", k); + fs::path p = get_conf("paths", k); - if (!itor->second.empty()) + if (p.empty()) { - if (conf::dry()) - return; - - if (fs::exists(itor->second)) - { - itor->second = fs::canonical(itor->second); - return; - } + if constexpr (std::is_same_v>) + p = f; else - { - gcx().bail_out(context::conf, "path {} not found", itor->second); - } + p = f(); } - fs::path cp; + p = fs::absolute(p); - if constexpr (std::is_same_v>) - cp = f; - else - cp = f(); - - if (conf::dry()) + if (!conf::dry()) { - itor->second = cp; - return; + if (!fs::exists(p)) + gcx().bail_out(context::conf, "path {} not found", p); + + p = fs::canonical(p); } - cp = fs::absolute(cp); - - if (!fs::exists(cp)) - gcx().bail_out(context::conf, "path {} not found", cp); - - itor->second = fs::canonical(cp); + set_conf("paths", k, path_to_utf8(p)); } void make_canonical_path( const std::string& key, const fs::path& default_parent, const std::string& default_dir) { - auto itor = g_paths.find(key); - if (itor == g_paths.end()) - gcx().bail_out(context::conf, "unknown path key {}", key); + fs::path p = path_by_name(key); - if (itor->second.empty()) + if (p.empty()) { - itor->second = default_parent / default_dir; + p = default_parent / default_dir; } else { - if (itor->second.is_relative()) - itor->second = default_parent / itor->second; + if (p.is_relative()) + p = default_parent / p; } if (!conf::dry()) - itor->second = fs::weakly_canonical(fs::absolute(itor->second)); + p = fs::weakly_canonical(fs::absolute(p)); + + set_conf("paths", key, path_to_utf8(p)); } -void init_options(const fs::path& ini, const std::vector& opts) +void set_special_options() { - parse_ini(ini); + auto v = get_conf("options", "output_log_level"); + + if (!v.empty()) + { + try + { + const auto i = std::stoi(v); + if (i < 0 || i > 6) + gcx().bail_out(context::generic, "bad output log level {}", i); + + g_output_log_level = i; + } + catch(std::exception&) + { + gcx().bail_out(context::generic, "bad output log level {}", v); + } + } + + + v = get_conf("options", "file_log_level"); + + if (!v.empty()) + { + try + { + const auto i = std::stoi(v); + if (i < 0 || i > 6) + gcx().bail_out(context::generic, "bad file log level {}", i); + + g_file_log_level = i; + } + catch(std::exception&) + { + gcx().bail_out(context::generic, "bad file log level {}", v); + } + } +} + +void init_options( + const fs::path& ini_from_cl, const std::vector& opts) +{ + const fs::path actual_ini = find_ini(ini_from_cl); + parse_ini(actual_ini, true); if (!opts.empty()) { gcx().debug(context::conf, "overriding from command line:"); for (auto&& o : opts) - set_option(o); + { + const auto po = parse_option(o); + set_conf(po.section, po.key, po.value); + } } - try - { - if (!g_options["output_log_level"].empty()) - conf::set_output_log_level(std::stoi(g_options["output_log_level"])); - } - catch(std::exception&) - { - gcx().bail_out(context::generic, "bad output_log_level"); - } - - try - { - if (!g_options["file_log_level"].empty()) - conf::set_file_log_level(std::stoi(g_options["file_log_level"])); - } - catch(std::exception&) - { - gcx().bail_out(context::generic, "bad file_log_level"); - } - - if (!g_options["log_file"].empty()) - conf::set_log_file(g_options["log_file"]); - + set_special_options(); context::set_log_file(conf::log_file()); set_path_if_empty("third_party", find_third_party_directory); - this_env::prepend_to_path(paths::third_party() / "bin"); set_path_if_empty("pf_x86", find_program_files_x86); @@ -927,36 +761,46 @@ bool verify_options() template void table(const std::string& caption, const Map& values) { - std::size_t longest = 0; - for (auto&& [k, v] : values) - longest = std::max(longest, k.size()); - - gcx().trace(context::conf, "{}:", caption); - for (auto&& [k, v] : values) - gcx().trace(context::conf, " . {} = {}", pad_right(k, longest), v); } -void dump_options() +std::vector format_options() { - string_map opts = g_options; - table("options", opts); + std::size_t longest_section = 0; + std::size_t longest_key = 0; - string_map tools; - for (auto&& [k, v] : g_tools) - tools[k] = path_to_utf8(v); - table("tools", tools); + for (auto&& [s, kv] : g_conf) + { + longest_section = std::max(longest_section, s.size()); - string_map prebuilt; - for (auto&& [k, v] : g_prebuilt) - prebuilt[k] = (v ? "true" : "false"); - table("prebuilt", prebuilt); + for (auto&& [k, v] : kv) + longest_key = std::max(longest_key, k.size()); + } - table("versions", g_versions); + std::vector lines; - string_map paths; - for (auto&& [k, v] : g_paths) - paths[k] = path_to_utf8(v); - table("paths", paths); + for (auto&& [s, kv] : g_conf) + { + for (auto&& [k, v] : kv) + { + lines.push_back( + pad_right(s, longest_section) + " " + + pad_right(k, longest_key) + " = " + v); + } + } + + return lines; +} + +void log_options() +{ + for (auto&& line : format_options()) + gcx().trace(context::conf, "{}", line); +} + +void dump_available_options() +{ + for (auto&& line : format_options()) + u8cout << line << "\n"; } diff --git a/src/conf.h b/src/conf.h index c89d764..19559ce 100644 --- a/src/conf.h +++ b/src/conf.h @@ -3,37 +3,32 @@ namespace mob { -#define VALUE(NAME) \ - static decltype(auto) NAME() { return by_name(#NAME); } - -#define VALUE_BOOL(NAME) \ - static bool NAME() { return by_name_bool(#NAME); } +bool prebuilt_by_name(const std::string& task); +std::string version_by_name(const std::string& s); +fs::path tool_by_name(const std::string& s); +fs::path path_by_name(const std::string& s); +std::string conf_by_name(const std::string& s); +bool bool_conf_by_name(const std::string& s); struct conf { - static void set_output_log_level(int i); - static void set_file_log_level(int i); - static void set_log_file(const fs::path& p); - static int output_log_level(); static int file_log_level(); - static const fs::path& log_file(); - static const std::string& by_name(const std::string& s); - static bool by_name_bool(const std::string& name); + static std::string mo_org() { return conf_by_name("mo_org"); } + static std::string mo_branch() { return conf_by_name("mo_branch"); } + static fs::path log_file() { return conf_by_name("log_file"); } - VALUE(mo_org); - VALUE(mo_branch); - - VALUE_BOOL(dry); - VALUE_BOOL(redownload); - VALUE_BOOL(reextract); - VALUE_BOOL(rebuild); + static bool dry() { return bool_conf_by_name("dry"); } + static bool redownload() { return bool_conf_by_name("redownload"); } + static bool reextract() { return bool_conf_by_name("reextract"); } + static bool rebuild() { return bool_conf_by_name("rebuild"); } }; struct paths { - static const fs::path& by_name(const std::string& s); +#define VALUE(NAME) \ + static fs::path NAME() { return path_by_name(#NAME); } VALUE(third_party); VALUE(prefix); @@ -57,19 +52,14 @@ struct paths VALUE(pf_x86); VALUE(pf_x64); VALUE(temp_dir); + +#undef VALUE }; -#undef VALUE_BOOL -#undef VALUE - - -bool prebuilt_by_name(const std::string& task); -const std::string& version_by_name(const std::string& s); -const fs::path& tool_by_name(const std::string& s); void init_options(const fs::path& ini, const std::vector& opts); bool verify_options(); -void dump_options(); +void log_options(); void dump_available_options(); fs::path make_temp_file(); diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp index d6fd640..51fabef 100644 --- a/src/tasks/boost.cpp +++ b/src/tasks/boost.cpp @@ -9,12 +9,12 @@ boost::boost() { } -const std::string& boost::version() +std::string boost::version() { return version_by_name("boost"); } -const std::string& boost::version_vs() +std::string boost::version_vs() { return version_by_name("boost_vs"); } @@ -195,8 +195,10 @@ std::smatch boost::parse_boost_version() std::regex re(R"((\d+)\.(\d+)(?:\.(\d+)(?:-(\w+)(?:-(\w+))?)?)?)"); std::smatch m; - if (!std::regex_match(version(), m, re)) - bail_out("bad boost version '{}'", version()); + const auto s = version(); + + if (!std::regex_match(s, m, re)) + bail_out("bad boost version '{}'", s); return m; } diff --git a/src/tasks/boost_di.cpp b/src/tasks/boost_di.cpp index b486dd4..21be2a7 100644 --- a/src/tasks/boost_di.cpp +++ b/src/tasks/boost_di.cpp @@ -9,10 +9,9 @@ boost_di::boost_di() { } -const std::string& boost_di::version() +std::string boost_di::version() { - static std::string s; - return s; + return {}; } bool boost_di::prebuilt() diff --git a/src/tasks/bzip2.cpp b/src/tasks/bzip2.cpp index 6c10090..958cdba 100644 --- a/src/tasks/bzip2.cpp +++ b/src/tasks/bzip2.cpp @@ -9,7 +9,7 @@ bzip2::bzip2() { } -const std::string& bzip2::version() +std::string bzip2::version() { return version_by_name("bzip2"); } diff --git a/src/tasks/explorerpp.cpp b/src/tasks/explorerpp.cpp index 7689678..a397975 100644 --- a/src/tasks/explorerpp.cpp +++ b/src/tasks/explorerpp.cpp @@ -9,7 +9,7 @@ explorerpp::explorerpp() { } -const std::string& explorerpp::version() +std::string explorerpp::version() { return version_by_name("explorerpp"); } diff --git a/src/tasks/fmt.cpp b/src/tasks/fmt.cpp index b2b3bf4..bfb3927 100644 --- a/src/tasks/fmt.cpp +++ b/src/tasks/fmt.cpp @@ -9,7 +9,7 @@ fmt::fmt() { } -const std::string& fmt::version() +std::string fmt::version() { return version_by_name("fmt"); } diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 6379f7e..382497d 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -9,7 +9,7 @@ gtest::gtest() { } -const std::string& gtest::version() +std::string gtest::version() { return version_by_name("gtest"); } diff --git a/src/tasks/libbsarch.cpp b/src/tasks/libbsarch.cpp index 7e4b54f..61d0578 100644 --- a/src/tasks/libbsarch.cpp +++ b/src/tasks/libbsarch.cpp @@ -9,7 +9,7 @@ libbsarch::libbsarch() { } -const std::string& libbsarch::version() +std::string libbsarch::version() { return version_by_name("libbsarch"); } diff --git a/src/tasks/libffi.cpp b/src/tasks/libffi.cpp index 4e1b58c..e55d7ba 100644 --- a/src/tasks/libffi.cpp +++ b/src/tasks/libffi.cpp @@ -9,10 +9,9 @@ libffi::libffi() { } -const std::string& libffi::version() +std::string libffi::version() { - static std::string s; - return s; + return {}; } bool libffi::prebuilt() diff --git a/src/tasks/libloot.cpp b/src/tasks/libloot.cpp index 0147c5e..39f92fc 100644 --- a/src/tasks/libloot.cpp +++ b/src/tasks/libloot.cpp @@ -9,12 +9,12 @@ libloot::libloot() { } -const std::string& libloot::version() +std::string libloot::version() { return version_by_name("libloot"); } -const std::string& libloot::hash() +std::string libloot::hash() { return version_by_name("libloot_hash"); } diff --git a/src/tasks/licenses.cpp b/src/tasks/licenses.cpp index 2714f83..a1375af 100644 --- a/src/tasks/licenses.cpp +++ b/src/tasks/licenses.cpp @@ -9,10 +9,9 @@ licenses::licenses() { } -const std::string& licenses::version() +std::string licenses::version() { - static std::string s; - return s; + return {}; } bool licenses::prebuilt() diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index 14f7465..f64bb6b 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -9,7 +9,7 @@ lz4::lz4() { } -const std::string& lz4::version() +std::string lz4::version() { return version_by_name("lz4"); } diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp index 92f0251..6931956 100644 --- a/src/tasks/modorganizer.cpp +++ b/src/tasks/modorganizer.cpp @@ -24,10 +24,9 @@ modorganizer::modorganizer(std::string long_name) add_name(long_name); } -const std::string& modorganizer::version() +std::string modorganizer::version() { - static std::string s; - return s; + return {}; } bool modorganizer::prebuilt() diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index 1d75c32..4b628dc 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -9,10 +9,9 @@ ncc::ncc() { } -const std::string& ncc::version() +std::string ncc::version() { - static std::string s; - return s; + return {}; } bool ncc::prebuilt() diff --git a/src/tasks/nmm.cpp b/src/tasks/nmm.cpp index 9f00752..b9c48e0 100644 --- a/src/tasks/nmm.cpp +++ b/src/tasks/nmm.cpp @@ -9,7 +9,7 @@ nmm::nmm() { } -const std::string& nmm::version() +std::string nmm::version() { return version_by_name("nmm"); } diff --git a/src/tasks/openssl.cpp b/src/tasks/openssl.cpp index c4c87e3..35a8c48 100644 --- a/src/tasks/openssl.cpp +++ b/src/tasks/openssl.cpp @@ -9,7 +9,7 @@ openssl::openssl() { } -const std::string& openssl::version() +std::string openssl::version() { return version_by_name("openssl"); } @@ -206,8 +206,10 @@ std::smatch openssl::parse_version() std::regex re(R"((\d+)(?:\.(\d+)(?:\.(\d+)([a-zA-Z]+)?)?)?)"); std::smatch m; - if (!std::regex_match(version(), m, re)) - bail_out("bad openssl version '{}'", version()); + const auto s = version(); + + if (!std::regex_match(s, m, re)) + bail_out("bad openssl version '{}'", s); return m; } diff --git a/src/tasks/pyqt.cpp b/src/tasks/pyqt.cpp index 6982291..77f9529 100644 --- a/src/tasks/pyqt.cpp +++ b/src/tasks/pyqt.cpp @@ -9,12 +9,12 @@ pyqt::pyqt() { } -const std::string& pyqt::version() +std::string pyqt::version() { return version_by_name("pyqt"); } -const std::string& pyqt::builder_version() +std::string pyqt::builder_version() { return version_by_name("pyqt_builder"); } diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index 2c3b130..b84ca67 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -9,7 +9,7 @@ python::python() { } -const std::string& python::version() +std::string python::version() { return version_by_name("python"); } @@ -26,8 +26,10 @@ python::version_info python::parsed_version() std::regex re(R"(v?(\d+)\.(\d+)(?:\.(\d+))?)"); std::smatch m; - if (!std::regex_match(version(), m, re)) - bail_out("bad python version '{}'", version()); + const auto s = version(); + + if (!std::regex_match(s, m, re)) + bail_out("bad python version '{}'", s); version_info v; diff --git a/src/tasks/sevenz.cpp b/src/tasks/sevenz.cpp index 2f87cec..85af0d1 100644 --- a/src/tasks/sevenz.cpp +++ b/src/tasks/sevenz.cpp @@ -9,7 +9,7 @@ sevenz::sevenz() { } -const std::string& sevenz::version() +std::string sevenz::version() { return version_by_name("sevenz"); } diff --git a/src/tasks/sip.cpp b/src/tasks/sip.cpp index 154e879..034cb51 100644 --- a/src/tasks/sip.cpp +++ b/src/tasks/sip.cpp @@ -9,12 +9,12 @@ sip::sip() { } -const std::string& sip::version() +std::string sip::version() { return version_by_name("sip"); } -const std::string& sip::version_for_pyqt() +std::string sip::version_for_pyqt() { return version_by_name("pyqt_sip"); } @@ -46,8 +46,10 @@ fs::path sip::module_source_path() std::regex re(R"((\d+)\.(\d+)(?:\.(\d+))?)"); std::smatch m; - if (!std::regex_match(version_for_pyqt(), m, re)) - bail_out("bad pyqt sip version {}", version_for_pyqt()); + const auto s = version_for_pyqt(); + + if (!std::regex_match(s, m, re)) + bail_out("bad pyqt sip version {}", s); // 12.7 const auto dir = m[1].str() + "." + m[2].str(); diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp index bf9c6a3..d42714f 100644 --- a/src/tasks/spdlog.cpp +++ b/src/tasks/spdlog.cpp @@ -9,7 +9,7 @@ spdlog::spdlog() { } -const std::string& spdlog::version() +std::string spdlog::version() { return version_by_name("spdlog"); } diff --git a/src/tasks/stylesheets.cpp b/src/tasks/stylesheets.cpp index b1bf1f6..358a9c2 100644 --- a/src/tasks/stylesheets.cpp +++ b/src/tasks/stylesheets.cpp @@ -9,10 +9,9 @@ stylesheets::stylesheets() { } -const std::string& stylesheets::version() +std::string stylesheets::version() { - static std::string s; - return s; + return {}; } std::string stylesheets::paper_lad_6788_version() diff --git a/src/tasks/task.h b/src/tasks/task.h index d38a73c..c2d0e93 100644 --- a/src/tasks/task.h +++ b/src/tasks/task.h @@ -40,7 +40,7 @@ public: const std::vector& names() const; virtual fs::path get_source_path() const = 0; - virtual const std::string& get_version() const = 0; + virtual std::string get_version() const = 0; virtual const bool get_prebuilt() const = 0; virtual bool is_super() const; @@ -111,7 +111,7 @@ public: return Task::source_path(); } - const std::string& get_version() const override + std::string get_version() const override { return Task::version(); } @@ -142,10 +142,9 @@ public: return {}; } - const std::string& get_version() const override + std::string get_version() const override { - static std::string s; - return s; + return {}; } const bool get_prebuilt() const override diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h index 7c3da02..dee788d 100644 --- a/src/tasks/tasks.h +++ b/src/tasks/tasks.h @@ -15,8 +15,8 @@ class boost : public basic_task public: boost(); - static const std::string& version(); - static const std::string& version_vs(); + static std::string version(); + static std::string version_vs(); static bool prebuilt(); static fs::path source_path(); @@ -66,7 +66,7 @@ class boost_di : public basic_task public: boost_di(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -81,7 +81,7 @@ class bzip2 : public basic_task public: bzip2(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -99,7 +99,7 @@ class explorerpp : public basic_task public: explorerpp(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -117,7 +117,7 @@ class fmt : public basic_task public: fmt(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -137,7 +137,7 @@ class gtest : public basic_task public: gtest(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -154,7 +154,7 @@ class licenses : public basic_task public: licenses(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -169,7 +169,7 @@ class libbsarch : public basic_task public: libbsarch(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -189,7 +189,7 @@ class libffi : public basic_task public: libffi(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -206,8 +206,8 @@ class libloot : public basic_task public: libloot(); - static const std::string& version(); - static const std::string& hash(); + static std::string version(); + static std::string hash(); static bool prebuilt(); static fs::path source_path(); @@ -227,7 +227,7 @@ class lz4 : public basic_task public: lz4(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -257,7 +257,7 @@ class modorganizer : public basic_task public: modorganizer(std::string name); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -283,7 +283,7 @@ class ncc : public basic_task public: ncc(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -300,7 +300,7 @@ class nmm : public basic_task public: nmm(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -317,7 +317,7 @@ class openssl : public basic_task public: openssl(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -356,8 +356,8 @@ class pyqt : public basic_task public: pyqt(); - static const std::string& version(); - static const std::string& builder_version(); + static std::string version(); + static std::string builder_version(); static bool prebuilt(); static fs::path source_path(); @@ -397,7 +397,7 @@ public: python(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static version_info parsed_version(); @@ -435,8 +435,8 @@ class sip : public basic_task public: sip(); - static const std::string& version(); - static const std::string& version_for_pyqt(); + static std::string version(); + static std::string version_for_pyqt(); static bool prebuilt(); static fs::path source_path(); @@ -462,7 +462,7 @@ class sevenz : public basic_task public: sevenz(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -486,7 +486,7 @@ class spdlog : public basic_task public: spdlog(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -510,7 +510,7 @@ public: static std::string dark_mode_1809_6788_version(); // dummy, doesn't applly - static const std::string& version(); + static std::string version(); protected: void do_fetch() override; @@ -534,7 +534,7 @@ class usvfs : public basic_task public: usvfs(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); @@ -562,7 +562,7 @@ class zlib : public basic_task public: zlib(); - static const std::string& version(); + static std::string version(); static bool prebuilt(); static fs::path source_path(); diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp index c8c6539..d9c4de3 100644 --- a/src/tasks/usvfs.cpp +++ b/src/tasks/usvfs.cpp @@ -9,7 +9,7 @@ usvfs::usvfs() { } -const std::string& usvfs::version() +std::string usvfs::version() { return version_by_name("usvfs"); } diff --git a/src/tasks/zlib.cpp b/src/tasks/zlib.cpp index 13ae615..519761b 100644 --- a/src/tasks/zlib.cpp +++ b/src/tasks/zlib.cpp @@ -9,7 +9,7 @@ zlib::zlib() { } -const std::string& zlib::version() +std::string zlib::version() { return version_by_name("zlib"); } diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index 6301ced..e9065da 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -72,12 +72,12 @@ fs::path nasm::binary() fs::path qt::installation_path() { - return paths::by_name("qt_install"); + return path_by_name("qt_install"); } fs::path qt::bin_path() { - return paths::by_name("qt_bin"); + return path_by_name("qt_bin"); } std::string qt::version() @@ -103,7 +103,7 @@ fs::path vs::devenv_binary() fs::path vs::installation_path() { - return paths::by_name("vs"); + return path_by_name("vs"); } fs::path vs::vswhere() From 1b75f8833476ceac14bbd775912a2bf49fbbde6e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 May 2020 14:56:47 -0400 Subject: [PATCH 3/5] multiple inis --- src/commands.cpp | 50 ++++++++++++++++++---- src/commands.h | 4 +- src/conf.cpp | 107 ++++++++++++++++++++++++++++++++++++----------- src/conf.h | 7 +++- src/utility.h | 2 +- 5 files changed, 133 insertions(+), 37 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 72b5b38..aecc5bb 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -49,8 +49,8 @@ clipp::group command::common_options_group() auto& o = common; return - (clipp::option("-i", "--ini") - & clipp::value("FILE") >> o.ini) + (clipp::repeatable(clipp::option("-i", "--ini") + & clipp::value("FILE") >> o.inis)) % ("path to the ini file"), (clipp::option("--dry") >> o.dry) @@ -72,10 +72,12 @@ clipp::group command::common_options_group() & clipp::value("DIR") >> o.prefix) % ("base output directory, will contain build/, install/, etc."), - (clipp::repeatable(clipp::option("-s", "--set") >> o.set - & clipp::opt_value("OPTION", o.options))) - % "sets an option, such as 'versions/openssl=1.2'; -s with no " - "arguments lists the available options"; + (clipp::repeatable(clipp::option("-s", "--set") + & clipp::value("OPTION", o.options))) + % "sets an option, such as 'versions/openssl=1.2'", + + (clipp::option("--no-default-inis") >> o.no_default_inis) + % "disables auto detection of ini files, only uses --ini"; } void command::force_exit_code(int code) @@ -145,7 +147,20 @@ int command::run() if (flags_ & requires_options) { - init_options(command::common.ini, command::common.options); + if (o.no_default_inis && o.inis.empty()) + { + u8cerr + << "--no-default-inis requires at least one --ini for the " + << "master ini file\n"; + + return 1; + } + + std::vector inis; + for (auto&& s : o.inis) + inis.push_back(s); + + init_options(inis, !o.no_default_inis, o.options); log_options(); if (!verify_options()) @@ -185,6 +200,8 @@ int help_command::do_run() #pragma warning(suppress: 4548) auto doc = (command::common_options_group(), (clipp::value("command"))); + const auto mobini = master_ini_filename(); + help(doc, "Commands:\n" " help shows this message\n" @@ -196,7 +213,24 @@ int help_command::do_run() "\n\n" "Invoking `mob -d some/prefix build` builds everything. Do \n" "`mob build ...` to build specific tasks. See\n" - "`mob command --help` for more information about a command."); + "`mob command --help` for more information about a command.\n" + "\n" + "INI files\n" + "\n" + "By default, mob will look for a master INI `" + mobini + "` in the \n" + "current directory and up to three of its parents (so it can also be\n" + "found from the build directory). Once mob found the master INI, it\n" + "will look for any other .ini file in the same directory.\n" + "\n" + "These additional INI files will be loaded after the master, in\n" + "lexicographical order, overriding anything the previous INI file\n" + "may have set.\n" + "\n" + "Additional INI files may be specified with --ini. They will be\n" + "loaded in order after the ones that were auto detected. If the same\n" + "INI file is found in the directory and on the command line, its\n" + "position in the load order will be moved to that of the command\n" + "line."); return 0; } diff --git a/src/commands.h b/src/commands.h index c2cfb85..94da6d0 100644 --- a/src/commands.h +++ b/src/commands.h @@ -15,8 +15,8 @@ public: int file_log_level = -1; std::string log_file; std::vector options; - std::vector set; - std::string ini; + std::vector inis; + bool no_default_inis = false; std::string prefix; }; diff --git a/src/conf.cpp b/src/conf.cpp index 1dd2f65..913a325 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -8,7 +8,10 @@ namespace mob { -static const std::string default_ini_filename = "mob.ini"; +std::string master_ini_filename() +{ + return "mob.ini"; +} // special cases to avoid string manipulations static int g_output_log_level = 3; @@ -460,24 +463,15 @@ void ini_error(const fs::path& ini, std::size_t line, const std::string& what) ini.filename(), (line + 1), what); } -fs::path find_ini(const fs::path& ini) +fs::path find_master_ini() { - fs::path p = ini; + auto p = fs::current_path(); - if (!p.empty()) - { - if (fs::exists(p)) - return fs::canonical(p); - else - gcx().bail_out(context::conf, "can't find ini at {}", ini); - } + if (try_parts(p, {"..", "..", "..", master_ini_filename()})) + return fs::canonical(p); - p = fs::current_path(); - - if (try_parts(p, {"..", "..", "..", default_ini_filename})) - return p; - - gcx().bail_out(context::conf, "can't find {}", default_ini_filename); + gcx().bail_out(context::conf, + "can't find master ini {}", master_ini_filename()); } std::vector read_ini(const fs::path& ini) @@ -695,11 +689,75 @@ void set_special_options() } } -void init_options( - const fs::path& ini_from_cl, const std::vector& opts) +std::vector find_inis(const std::vector& inis_from_cl) { - const fs::path actual_ini = find_ini(ini_from_cl); - parse_ini(actual_ini, true); + const auto master = find_master_ini(); + + std::vector v; + + for (auto&& e : fs::directory_iterator(master.parent_path())) + { + const auto p = e.path(); + + if (path_to_utf8(p.extension()) != ".ini") + continue; + + if (p.filename() == master.filename()) + continue; + + v.push_back(p); + } + + std::sort(v.begin(), v.end()); + v.insert(v.begin(), master); + + for (auto&& p : inis_from_cl) + { + if (!fs::exists(p)) + { + u8cerr << "ini " << p << " not found\n"; + throw bailed(); + } + + bool found = false; + + for (auto itor=v.begin(); itor!=v.end(); ++itor) + { + if (fs::equivalent(p, *itor)) + { + found = true; + v.erase(itor); + v.push_back(p); + break; + } + } + + if (!found) + v.push_back(p); + } + + return v; +} + +void init_options( + const std::vector& inis_from_cl, bool auto_detection, + const std::vector& opts) +{ + std::vector inis; + + if (auto_detection) + inis = find_inis(inis_from_cl); + else + inis = inis_from_cl; + + MOB_ASSERT(!inis.empty()); + + bool add = true; + for (auto&& ini : inis) + { + parse_ini(ini, add); + add = false; + } if (!opts.empty()) { @@ -715,6 +773,10 @@ void init_options( set_special_options(); context::set_log_file(conf::log_file()); + gcx().debug(context::conf, "using inis in order:"); + for (auto&& ini : inis) + gcx().debug(context::conf, " . {}", ini); + set_path_if_empty("third_party", find_third_party_directory); this_env::prepend_to_path(paths::third_party() / "bin"); @@ -758,11 +820,6 @@ bool verify_options() return check_missing_options(); } -template -void table(const std::string& caption, const Map& values) -{ -} - std::vector format_options() { std::size_t longest_section = 0; diff --git a/src/conf.h b/src/conf.h index 19559ce..bd4da34 100644 --- a/src/conf.h +++ b/src/conf.h @@ -57,7 +57,12 @@ struct paths }; -void init_options(const fs::path& ini, const std::vector& opts); +std::string master_ini_filename(); + +void init_options( + const std::vector& inis_from_cl, bool auto_detection, + const std::vector& opts); + bool verify_options(); void log_options(); void dump_available_options(); diff --git a/src/utility.h b/src/utility.h index 96cd24b..38b10fb 100644 --- a/src/utility.h +++ b/src/utility.h @@ -64,7 +64,7 @@ class url; class bailed { public: - bailed(std::string s) + bailed(std::string s={}) : s_(std::move(s)) { } From 02135a76d566ef31b1a6c9b067c6fb6b811f87c9 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 May 2020 15:50:15 -0400 Subject: [PATCH 4/5] options per task --- mob.ini | 8 +- src/commands.cpp | 8 +- src/conf.cpp | 309 ++++++++++++++++++++++--------------- src/conf.h | 87 ++++++++--- src/tasks/boost.cpp | 6 +- src/tasks/bzip2.cpp | 2 +- src/tasks/explorerpp.cpp | 2 +- src/tasks/fmt.cpp | 2 +- src/tasks/gtest.cpp | 2 +- src/tasks/libbsarch.cpp | 2 +- src/tasks/libloot.cpp | 4 +- src/tasks/lz4.cpp | 4 +- src/tasks/modorganizer.cpp | 8 +- src/tasks/ncc.cpp | 4 +- src/tasks/nmm.cpp | 2 +- src/tasks/openssl.cpp | 4 +- src/tasks/pyqt.cpp | 6 +- src/tasks/python.cpp | 4 +- src/tasks/sevenz.cpp | 2 +- src/tasks/sip.cpp | 4 +- src/tasks/spdlog.cpp | 2 +- src/tasks/stylesheets.cpp | 8 +- src/tasks/usvfs.cpp | 6 +- src/tasks/zlib.cpp | 2 +- src/tools/cmake.cpp | 2 +- src/tools/extractor.cpp | 2 +- src/tools/git.cpp | 7 +- src/tools/jom.cpp | 2 +- src/tools/msbuild.cpp | 2 +- src/tools/patcher.cpp | 2 +- src/tools/tools.cpp | 35 +++-- src/tools/tools.h | 2 +- 32 files changed, 333 insertions(+), 209 deletions(-) diff --git a/mob.ini b/mob.ini index 00413d4..65d736a 100644 --- a/mob.ini +++ b/mob.ini @@ -1,6 +1,4 @@ -[options] -mo_org = ModOrganizer2 -mo_branch = master +[global] dry = false redownload = false reextract = false @@ -9,6 +7,10 @@ output_log_level = 3 file_log_level = 5 log_file = mob.log +[options] +mo_org = ModOrganizer2 +mo_branch = master + [tools] sevenz = 7z.exe jom = jom.exe diff --git a/src/commands.cpp b/src/commands.cpp index aecc5bb..7beaff8 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -123,22 +123,22 @@ int command::run() if (o.output_log_level >= 0) { o.options.push_back( - "options/output_log_level=" + + "global/output_log_level=" + std::to_string(o.output_log_level)); } if (o.file_log_level > 0) { o.options.push_back( - "options/file_log_level=" + + "global/file_log_level=" + std::to_string(o.file_log_level)); } if (!o.log_file.empty()) - o.options.push_back("options/log_file=" + o.log_file); + o.options.push_back("global/log_file=" + o.log_file); if (o.dry) - o.options.push_back("options/dry=true"); + o.options.push_back("global/dry=true"); if (!o.prefix.empty()) o.options.push_back("paths/prefix=" + o.prefix); diff --git a/src/conf.cpp b/src/conf.cpp index 913a325..8f5cb4c 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -13,24 +13,24 @@ std::string master_ini_filename() return "mob.ini"; } -// special cases to avoid string manipulations -static int g_output_log_level = 3; -static int g_file_log_level = 5; +conf::task_map conf::map_; +int conf::output_log_level_ = 3; +int conf::file_log_level_ = 5; -static std::map> g_conf; -const std::string& get_conf(const std::string& section, const std::string& key) +std::string conf::get_global(const std::string& section, const std::string& key) { - auto sitor = g_conf.find(section); + auto global = map_.find(""); + MOB_ASSERT(global != map_.end()); - if (sitor == g_conf.end()) + auto sitor = global->second.find(section); + if (sitor == global->second.end()) { gcx().bail_out(context::conf, "conf section '{}' doesn't exist", section); } auto kitor = sitor->second.find(key); - if (kitor == sitor->second.end()) { gcx().bail_out(context::conf, @@ -40,20 +40,21 @@ const std::string& get_conf(const std::string& section, const std::string& key) return kitor->second; } -void set_conf( +void conf::set_global( const std::string& section, const std::string& key, const std::string& value) { - auto sitor = g_conf.find(section); + auto global = map_.find(""); + MOB_ASSERT(global != map_.end()); - if (sitor == g_conf.end()) + auto sitor = global->second.find(section); + if (sitor == global->second.end()) { gcx().bail_out(context::conf, "conf section '{}' doesn't exist", section); } auto kitor = sitor->second.find(key); - if (kitor == sitor->second.end()) { gcx().bail_out(context::conf, @@ -63,58 +64,167 @@ void set_conf( kitor->second = value; } -void add_conf( +void conf::add_global( const std::string& section, const std::string& key, const std::string& value) { - g_conf[section][key] = value; + map_[""][section][key] = value; } -bool prebuilt_by_name(const std::string& task) +std::string conf::get_for_task( + const std::vector& task_names, + const std::string& section, const std::string& key) { - std::istringstream iss(get_conf("prebuilt", task)); + task_map::iterator task = map_.end(); + + for (auto&& tn : task_names) + { + task = map_.find(tn); + if (task != map_.end()) + break; + } + + if (task == map_.end()) + return get_global(section, key); + + auto sitor = task->second.find(section); + if (sitor == task->second.end()) + return get_global(section, key); + + auto kitor = sitor->second.find(key); + if (kitor == sitor->second.end()) + return get_global(section, key); + + return kitor->second; +} + +void conf::set_for_task( + const std::string& task_name, const std::string& section, + const std::string& key, const std::string& value) +{ + // make sure it exists, will throw if it doesn't + get_global(section, key); + + map_[task_name][section][key] = value; +} + +bool conf::prebuilt_by_name(const std::string& task) +{ + std::istringstream iss(get_global("prebuilt", task)); bool b; iss >> std::boolalpha >> b; return b; } -std::string version_by_name(const std::string& s) +fs::path conf::path_by_name(const std::string& name) { - return get_conf("versions", s); + return get_global("paths", name); } -fs::path tool_by_name(const std::string& name) +std::string conf::version_by_name(const std::string& name) { - return get_conf("tools", name); + return get_global("versions", name); } -fs::path path_by_name(const std::string& s) +fs::path conf::tool_by_name(const std::string& name) { - return get_conf("paths", s); + return get_global("tools", name); } -std::string conf_by_name(const std::string& name) +std::string conf::global_by_name(const std::string& name) { - return get_conf("options", name); + return get_global("global", name); } -bool bool_conf_by_name(const std::string& name) +bool conf::bool_global_by_name(const std::string& name) { - std::istringstream iss(get_conf("options", name)); + std::istringstream iss(get_global("global", name)); bool b; iss >> std::boolalpha >> b; return b; } - -int conf::output_log_level() +std::string conf::option_by_name( + const std::vector& task_names, const std::string& name) { - return g_output_log_level; + return get_for_task(task_names, "options", name); } -int conf::file_log_level() +void conf::set_output_log_level(const std::string& s) { - return g_file_log_level; + if (s.empty()) + return; + + try + { + const auto i = std::stoi(s); + + if (i < 0 || i > 6) + gcx().bail_out(context::generic, "bad output log level {}", i); + + output_log_level_ = i; + } + catch(std::exception&) + { + gcx().bail_out(context::generic, "bad output log level {}", s); + } +} + +void conf::set_file_log_level(const std::string& s) +{ + if (s.empty()) + return; + + try + { + const auto i = std::stoi(s); + if (i < 0 || i > 6) + gcx().bail_out(context::generic, "bad file log level {}", i); + + file_log_level_ = i; + } + catch(std::exception&) + { + gcx().bail_out(context::generic, "bad file log level {}", s); + } +} + +std::vector conf::format_options() +{ + std::size_t longest_task = 0; + std::size_t longest_section = 0; + std::size_t longest_key = 0; + + for (auto&& [t, ss] : map_) + { + longest_task = std::max(longest_task, t.size()); + + for (auto&& [s, kv] : ss) + { + longest_section = std::max(longest_section, s.size()); + + for (auto&& [k, v] : kv) + longest_key = std::max(longest_key, k.size()); + } + } + + std::vector lines; + + for (auto&& [t, ss] : map_) + { + for (auto&& [s, kv] : ss) + { + for (auto&& [k, v] : kv) + { + lines.push_back( + pad_right(t, longest_task) + " " + + pad_right(s, longest_section) + " " + + pad_right(k, longest_key) + " = " + v); + } + } + } + + return lines; } @@ -259,7 +369,7 @@ bool try_qt_location(fs::path& check) fs::path find_qt() { - fs::path p = path_by_name("qt_install"); + fs::path p = conf::path_by_name("qt_install"); if (!p.empty()) { @@ -306,7 +416,7 @@ void validate_qt() if (!try_qt_location(p)) gcx().bail_out(context::conf, "qt path {} doesn't exist", p); - set_conf("paths", "qt_install", path_to_utf8(p)); + conf::set_global("paths", "qt_install", path_to_utf8(p)); } fs::path get_known_folder(const GUID& id) @@ -425,7 +535,7 @@ bool try_vcvars(fs::path& bat) void find_vcvars() { - fs::path bat = tool_by_name("vcvars"); + fs::path bat = conf::tool_by_name("vcvars"); if (conf::dry()) { @@ -451,7 +561,7 @@ void find_vcvars() } } - set_conf("tools", "vcvars", path_to_utf8(bat)); + conf::set_global("tools", "vcvars", path_to_utf8(bat)); gcx().trace(context::conf, "using vcvars at {}", bat); } @@ -503,8 +613,8 @@ std::vector read_ini(const fs::path& ini) void parse_section( const fs::path& ini, std::size_t& i, - const std::vector& lines, const std::string& section, - bool add) + const std::vector& lines, + const std::string& task, const std::string& section, bool add) { ++i; @@ -525,10 +635,17 @@ void parse_section( if (k.empty()) ini_error(ini, i, "bad line '" + line + "'"); - if (add) - add_conf(section, k, v); + if (task.empty()) + { + if (add) + conf::add_global(section, k, v); + else + conf::set_global(section, k, v); + } else - set_conf(section, k, v); + { + conf::set_for_task(task, section, k, v); + } ++i; } @@ -550,8 +667,23 @@ void parse_ini(const fs::path& ini, bool add) if (line.starts_with("[") && line.ends_with("]")) { - const std::string section = line.substr(1, line.size() - 2); - parse_section(ini, i, lines, section, add); + const std::string s = line.substr(1, line.size() - 2); + + std::string task, section; + + const auto slash = s.find("/"); + + if (slash == std::string::npos) + { + section = s; + } + else + { + task = s.substr(0, slash); + section = s.substr(slash +1 ); + } + + parse_section(ini, i, lines, task, section, add); } else { @@ -562,7 +694,7 @@ void parse_ini(const fs::path& ini, bool add) bool check_missing_options() { - if (conf::mo_org().empty()) + if (conf::mo_org({""}).empty()) { u8cerr << "missing mo_org; either specify it the [options] section of " @@ -571,7 +703,7 @@ bool check_missing_options() return false; } - if (conf::mo_branch().empty()) + if (conf::mo_branch({""}).empty()) { u8cerr << "missing mo_branch; either specify it the [options] section of " @@ -589,22 +721,13 @@ bool check_missing_options() return false; } - for (auto&& [k, v] : g_conf["versions"]) - { - if (v.empty()) - { - u8cerr << "missing version for " << k << "\n"; - return false; - } - } - return true; } template void set_path_if_empty(const std::string& k, F&& f) { - fs::path p = get_conf("paths", k); + fs::path p = conf::get_global("paths", k); if (p.empty()) { @@ -624,14 +747,14 @@ void set_path_if_empty(const std::string& k, F&& f) p = fs::canonical(p); } - set_conf("paths", k, path_to_utf8(p)); + conf::set_global("paths", k, path_to_utf8(p)); } void make_canonical_path( const std::string& key, const fs::path& default_parent, const std::string& default_dir) { - fs::path p = path_by_name(key); + fs::path p = conf::path_by_name(key); if (p.empty()) { @@ -646,47 +769,13 @@ void make_canonical_path( if (!conf::dry()) p = fs::weakly_canonical(fs::absolute(p)); - set_conf("paths", key, path_to_utf8(p)); + conf::set_global("paths", key, path_to_utf8(p)); } void set_special_options() { - auto v = get_conf("options", "output_log_level"); - - if (!v.empty()) - { - try - { - const auto i = std::stoi(v); - if (i < 0 || i > 6) - gcx().bail_out(context::generic, "bad output log level {}", i); - - g_output_log_level = i; - } - catch(std::exception&) - { - gcx().bail_out(context::generic, "bad output log level {}", v); - } - } - - - v = get_conf("options", "file_log_level"); - - if (!v.empty()) - { - try - { - const auto i = std::stoi(v); - if (i < 0 || i > 6) - gcx().bail_out(context::generic, "bad file log level {}", i); - - g_file_log_level = i; - } - catch(std::exception&) - { - gcx().bail_out(context::generic, "bad file log level {}", v); - } - } + conf::set_output_log_level(conf::get_global("global", "output_log_level")); + conf::set_file_log_level(conf::get_global("global", "file_log_level")); } std::vector find_inis(const std::vector& inis_from_cl) @@ -766,7 +855,7 @@ void init_options( for (auto&& o : opts) { const auto po = parse_option(o); - set_conf(po.section, po.key, po.value); + conf::set_global(po.section, po.key, po.value); } } @@ -820,43 +909,15 @@ bool verify_options() return check_missing_options(); } -std::vector format_options() -{ - std::size_t longest_section = 0; - std::size_t longest_key = 0; - - for (auto&& [s, kv] : g_conf) - { - longest_section = std::max(longest_section, s.size()); - - for (auto&& [k, v] : kv) - longest_key = std::max(longest_key, k.size()); - } - - std::vector lines; - - for (auto&& [s, kv] : g_conf) - { - for (auto&& [k, v] : kv) - { - lines.push_back( - pad_right(s, longest_section) + " " + - pad_right(k, longest_key) + " = " + v); - } - } - - return lines; -} - void log_options() { - for (auto&& line : format_options()) + for (auto&& line : conf::format_options()) gcx().trace(context::conf, "{}", line); } void dump_available_options() { - for (auto&& line : format_options()) + for (auto&& line : conf::format_options()) u8cout << line << "\n"; } diff --git a/src/conf.h b/src/conf.h index bd4da34..38628cb 100644 --- a/src/conf.h +++ b/src/conf.h @@ -3,32 +3,83 @@ namespace mob { -bool prebuilt_by_name(const std::string& task); -std::string version_by_name(const std::string& s); -fs::path tool_by_name(const std::string& s); -fs::path path_by_name(const std::string& s); -std::string conf_by_name(const std::string& s); -bool bool_conf_by_name(const std::string& s); - -struct conf +class conf { - static int output_log_level(); - static int file_log_level(); +public: + static std::string get_global( + const std::string& section, const std::string& key); - static std::string mo_org() { return conf_by_name("mo_org"); } - static std::string mo_branch() { return conf_by_name("mo_branch"); } - static fs::path log_file() { return conf_by_name("log_file"); } + static void set_global( + const std::string& section, + const std::string& key, const std::string& value); - static bool dry() { return bool_conf_by_name("dry"); } - static bool redownload() { return bool_conf_by_name("redownload"); } - static bool reextract() { return bool_conf_by_name("reextract"); } - static bool rebuild() { return bool_conf_by_name("rebuild"); } + static void add_global( + const std::string& section, + const std::string& key, const std::string& value); + + + static std::string get_for_task( + const std::vector& task_names, + const std::string& section, const std::string& key); + + static void set_for_task( + const std::string& task_name, const std::string& section, + const std::string& key, const std::string& value); + + + static bool prebuilt_by_name(const std::string& task); + static fs::path path_by_name(const std::string& name); + static std::string version_by_name(const std::string& name); + static fs::path tool_by_name(const std::string& name); + + static std::string global_by_name(const std::string& name); + static bool bool_global_by_name(const std::string& name); + + static std::string option_by_name( + const std::vector& task_names, const std::string& name); + + + static int output_log_level() { return output_log_level_; } + static void set_output_log_level(const std::string& s); + + static int file_log_level() { return file_log_level_; } + static void set_file_log_level(const std::string& s); + + static fs::path log_file() { return global_by_name("log_file"); } + static bool dry() { return bool_global_by_name("dry"); } + static bool redownload() { return bool_global_by_name("redownload"); } + static bool reextract() { return bool_global_by_name("reextract"); } + static bool rebuild() { return bool_global_by_name("rebuild"); } + + + static std::string mo_org(const std::vector& task_names) + { + return option_by_name(task_names, "mo_org"); + } + + static std::string mo_branch(const std::vector& task_names) + { + return option_by_name(task_names, "mo_branch"); + } + + static std::vector format_options(); + +private: + using key_value_map = std::map; + using section_map = std::map; + using task_map = std::map; + + static task_map map_; + + // special cases to avoid string manipulations + static int output_log_level_; + static int file_log_level_; }; struct paths { #define VALUE(NAME) \ - static fs::path NAME() { return path_by_name(#NAME); } + static fs::path NAME() { return conf::path_by_name(#NAME); } VALUE(third_party); VALUE(prefix); diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp index 51fabef..0c8f96a 100644 --- a/src/tasks/boost.cpp +++ b/src/tasks/boost.cpp @@ -11,17 +11,17 @@ boost::boost() std::string boost::version() { - return version_by_name("boost"); + return conf::version_by_name("boost"); } std::string boost::version_vs() { - return version_by_name("boost_vs"); + return conf::version_by_name("boost_vs"); } bool boost::prebuilt() { - return prebuilt_by_name("boost"); + return conf::prebuilt_by_name("boost"); } fs::path boost::source_path() diff --git a/src/tasks/bzip2.cpp b/src/tasks/bzip2.cpp index 958cdba..37cd4c4 100644 --- a/src/tasks/bzip2.cpp +++ b/src/tasks/bzip2.cpp @@ -11,7 +11,7 @@ bzip2::bzip2() std::string bzip2::version() { - return version_by_name("bzip2"); + return conf::version_by_name("bzip2"); } bool bzip2::prebuilt() diff --git a/src/tasks/explorerpp.cpp b/src/tasks/explorerpp.cpp index a397975..fab4952 100644 --- a/src/tasks/explorerpp.cpp +++ b/src/tasks/explorerpp.cpp @@ -11,7 +11,7 @@ explorerpp::explorerpp() std::string explorerpp::version() { - return version_by_name("explorerpp"); + return conf::version_by_name("explorerpp"); } bool explorerpp::prebuilt() diff --git a/src/tasks/fmt.cpp b/src/tasks/fmt.cpp index bfb3927..c11c9ec 100644 --- a/src/tasks/fmt.cpp +++ b/src/tasks/fmt.cpp @@ -11,7 +11,7 @@ fmt::fmt() std::string fmt::version() { - return version_by_name("fmt"); + return conf::version_by_name("fmt"); } bool fmt::prebuilt() diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 382497d..571609d 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -11,7 +11,7 @@ gtest::gtest() std::string gtest::version() { - return version_by_name("gtest"); + return conf::version_by_name("gtest"); } bool gtest::prebuilt() diff --git a/src/tasks/libbsarch.cpp b/src/tasks/libbsarch.cpp index 61d0578..d30c829 100644 --- a/src/tasks/libbsarch.cpp +++ b/src/tasks/libbsarch.cpp @@ -11,7 +11,7 @@ libbsarch::libbsarch() std::string libbsarch::version() { - return version_by_name("libbsarch"); + return conf::version_by_name("libbsarch"); } bool libbsarch::prebuilt() diff --git a/src/tasks/libloot.cpp b/src/tasks/libloot.cpp index 39f92fc..f204637 100644 --- a/src/tasks/libloot.cpp +++ b/src/tasks/libloot.cpp @@ -11,12 +11,12 @@ libloot::libloot() std::string libloot::version() { - return version_by_name("libloot"); + return conf::version_by_name("libloot"); } std::string libloot::hash() { - return version_by_name("libloot_hash"); + return conf::version_by_name("libloot_hash"); } bool libloot::prebuilt() diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index f64bb6b..b8d5433 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -11,12 +11,12 @@ lz4::lz4() std::string lz4::version() { - return version_by_name("lz4"); + return conf::version_by_name("lz4"); } bool lz4::prebuilt() { - return prebuilt_by_name("lz4"); + return conf::prebuilt_by_name("lz4"); } fs::path lz4::source_path() diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp index 6931956..ec2ccd5 100644 --- a/src/tasks/modorganizer.cpp +++ b/src/tasks/modorganizer.cpp @@ -59,8 +59,8 @@ void modorganizer::do_fetch() initialize_super(super_path()); run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(), repo_)) - .branch(conf::mo_branch()) + .url(make_github_url(conf::mo_org(names()), repo_)) + .branch(conf::mo_branch(names())) .output(this_source_path())); } @@ -75,10 +75,10 @@ void modorganizer::do_build_and_install() .arg("submodule") .arg("--quiet") .arg("add") - .arg("-b", conf::mo_branch()) + .arg("-b", conf::mo_branch(names())) .arg("--force") .arg("--name", name()) - .arg(make_github_url(conf::mo_org(), repo_)) + .arg(make_github_url(conf::mo_org(names()), repo_)) .arg(name()) .cwd(super_path()))); } diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index 4b628dc..21ae9fc 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -33,8 +33,8 @@ void ncc::do_clean_for_rebuild() void ncc::do_fetch() { run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(), "modorganizer-NCC")) - .branch(conf::mo_branch()) + .url(make_github_url(conf::mo_org(names()), "modorganizer-NCC")) + .branch(conf::mo_branch(names())) .output(source_path())); } diff --git a/src/tasks/nmm.cpp b/src/tasks/nmm.cpp index b9c48e0..5423f7c 100644 --- a/src/tasks/nmm.cpp +++ b/src/tasks/nmm.cpp @@ -11,7 +11,7 @@ nmm::nmm() std::string nmm::version() { - return version_by_name("nmm"); + return conf::version_by_name("nmm"); } bool nmm::prebuilt() diff --git a/src/tasks/openssl.cpp b/src/tasks/openssl.cpp index 35a8c48..1546c41 100644 --- a/src/tasks/openssl.cpp +++ b/src/tasks/openssl.cpp @@ -11,12 +11,12 @@ openssl::openssl() std::string openssl::version() { - return version_by_name("openssl"); + return conf::version_by_name("openssl"); } bool openssl::prebuilt() { - return prebuilt_by_name("openssl"); + return conf::prebuilt_by_name("openssl"); } fs::path openssl::source_path() diff --git a/src/tasks/pyqt.cpp b/src/tasks/pyqt.cpp index 77f9529..97d4c12 100644 --- a/src/tasks/pyqt.cpp +++ b/src/tasks/pyqt.cpp @@ -11,17 +11,17 @@ pyqt::pyqt() std::string pyqt::version() { - return version_by_name("pyqt"); + return conf::version_by_name("pyqt"); } std::string pyqt::builder_version() { - return version_by_name("pyqt_builder"); + return conf::version_by_name("pyqt_builder"); } bool pyqt::prebuilt() { - return prebuilt_by_name("pyqt"); + return conf::prebuilt_by_name("pyqt"); } fs::path pyqt::source_path() diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index b84ca67..f5190f9 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -11,12 +11,12 @@ python::python() std::string python::version() { - return version_by_name("python"); + return conf::version_by_name("python"); } bool python::prebuilt() { - return prebuilt_by_name("python"); + return conf::prebuilt_by_name("python"); } python::version_info python::parsed_version() diff --git a/src/tasks/sevenz.cpp b/src/tasks/sevenz.cpp index 85af0d1..aed4a41 100644 --- a/src/tasks/sevenz.cpp +++ b/src/tasks/sevenz.cpp @@ -11,7 +11,7 @@ sevenz::sevenz() std::string sevenz::version() { - return version_by_name("sevenz"); + return conf::version_by_name("sevenz"); } bool sevenz::prebuilt() diff --git a/src/tasks/sip.cpp b/src/tasks/sip.cpp index 034cb51..7425225 100644 --- a/src/tasks/sip.cpp +++ b/src/tasks/sip.cpp @@ -11,12 +11,12 @@ sip::sip() std::string sip::version() { - return version_by_name("sip"); + return conf::version_by_name("sip"); } std::string sip::version_for_pyqt() { - return version_by_name("pyqt_sip"); + return conf::version_by_name("pyqt_sip"); } bool sip::prebuilt() diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp index d42714f..d0abd49 100644 --- a/src/tasks/spdlog.cpp +++ b/src/tasks/spdlog.cpp @@ -11,7 +11,7 @@ spdlog::spdlog() std::string spdlog::version() { - return version_by_name("spdlog"); + return conf::version_by_name("spdlog"); } bool spdlog::prebuilt() diff --git a/src/tasks/stylesheets.cpp b/src/tasks/stylesheets.cpp index 358a9c2..e45e8f3 100644 --- a/src/tasks/stylesheets.cpp +++ b/src/tasks/stylesheets.cpp @@ -16,22 +16,22 @@ std::string stylesheets::version() std::string stylesheets::paper_lad_6788_version() { - return version_by_name("ss_paper_lad_6788"); + return conf::version_by_name("ss_paper_lad_6788"); } std::string stylesheets::paper_automata_6788_version() { - return version_by_name("ss_paper_automata_6788"); + return conf::version_by_name("ss_paper_automata_6788"); } std::string stylesheets::paper_mono_6788_version() { - return version_by_name("ss_paper_mono_6788"); + return conf::version_by_name("ss_paper_mono_6788"); } std::string stylesheets::dark_mode_1809_6788_version() { - return version_by_name("ss_dark_mode_1809_6788"); + return conf::version_by_name("ss_dark_mode_1809_6788"); } diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp index d9c4de3..da33fa3 100644 --- a/src/tasks/usvfs.cpp +++ b/src/tasks/usvfs.cpp @@ -11,12 +11,12 @@ usvfs::usvfs() std::string usvfs::version() { - return version_by_name("usvfs"); + return conf::version_by_name("usvfs"); } bool usvfs::prebuilt() { - return prebuilt_by_name("usvfs"); + return conf::prebuilt_by_name("usvfs"); } fs::path usvfs::source_path() @@ -66,7 +66,7 @@ void usvfs::build_and_install_prebuilt() void usvfs::fetch_from_source() { run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(), "usvfs")) + .url(make_github_url(conf::mo_org(names()), "usvfs")) .branch(version()) .output(source_path())); } diff --git a/src/tasks/zlib.cpp b/src/tasks/zlib.cpp index 519761b..7e1d7b4 100644 --- a/src/tasks/zlib.cpp +++ b/src/tasks/zlib.cpp @@ -11,7 +11,7 @@ zlib::zlib() std::string zlib::version() { - return version_by_name("zlib"); + return conf::version_by_name("zlib"); } bool zlib::prebuilt() diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp index 7b0c918..fbf355b 100644 --- a/src/tools/cmake.cpp +++ b/src/tools/cmake.cpp @@ -13,7 +13,7 @@ cmake::cmake() fs::path cmake::binary() { - return tool_by_name("cmake"); + return conf::tool_by_name("cmake"); } void cmake::clean(const context& cx, const fs::path& root) diff --git a/src/tools/extractor.cpp b/src/tools/extractor.cpp index 356f794..f50214a 100644 --- a/src/tools/extractor.cpp +++ b/src/tools/extractor.cpp @@ -11,7 +11,7 @@ extractor::extractor() fs::path extractor::binary() { - return tool_by_name("sevenz"); + return conf::tool_by_name("sevenz"); } extractor& extractor::file(const fs::path& file) diff --git a/src/tools/git.cpp b/src/tools/git.cpp index 58f55eb..78c3f5b 100644 --- a/src/tools/git.cpp +++ b/src/tools/git.cpp @@ -12,7 +12,7 @@ git::git(ops o) fs::path git::binary() { - return tool_by_name("git"); + return conf::tool_by_name("git"); } git& git::url(const mob::url& u) @@ -38,10 +38,15 @@ void git::do_run() switch (op_) { case clone_or_pull: + { do_clone_or_pull(); + break; + } default: + { cx_->bail_out(context::generic, "git unknown op {}", op_); + } } } diff --git a/src/tools/jom.cpp b/src/tools/jom.cpp index 5c9fffe..4c4b8bf 100644 --- a/src/tools/jom.cpp +++ b/src/tools/jom.cpp @@ -12,7 +12,7 @@ jom::jom() fs::path jom::binary() { - return tool_by_name("jom"); + return conf::tool_by_name("jom"); } jom& jom::path(const fs::path& p) diff --git a/src/tools/msbuild.cpp b/src/tools/msbuild.cpp index 209b5c6..0facf1b 100644 --- a/src/tools/msbuild.cpp +++ b/src/tools/msbuild.cpp @@ -13,7 +13,7 @@ msbuild::msbuild() : fs::path msbuild::binary() { - return tool_by_name("msbuild"); + return conf::tool_by_name("msbuild"); } msbuild& msbuild::solution(const fs::path& sln) diff --git a/src/tools/patcher.cpp b/src/tools/patcher.cpp index e0721c7..55833d9 100644 --- a/src/tools/patcher.cpp +++ b/src/tools/patcher.cpp @@ -12,7 +12,7 @@ patcher::patcher() fs::path patcher::binary() { - return tool_by_name("patch"); + return conf::tool_by_name("patch"); } patcher& patcher::task(const std::string& name, bool prebuilt) diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index e9065da..42ded9d 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -62,32 +62,32 @@ bool tool::interrupted() const fs::path perl::binary() { - return tool_by_name("perl"); + return conf::tool_by_name("perl"); } fs::path nasm::binary() { - return tool_by_name("nasm"); + return conf::tool_by_name("nasm"); } fs::path qt::installation_path() { - return path_by_name("qt_install"); + return conf::path_by_name("qt_install"); } fs::path qt::bin_path() { - return path_by_name("qt_bin"); + return conf::path_by_name("qt_bin"); } std::string qt::version() { - return version_by_name("qt"); + return conf::version_by_name("qt"); } std::string qt::vs_version() { - return version_by_name("qt_vs"); + return conf::version_by_name("qt_vs"); } @@ -98,42 +98,42 @@ vs::vs(ops o) fs::path vs::devenv_binary() { - return tool_by_name("devenv"); + return conf::tool_by_name("devenv"); } fs::path vs::installation_path() { - return path_by_name("vs"); + return conf::path_by_name("vs"); } fs::path vs::vswhere() { - return tool_by_name("vswhere"); + return conf::tool_by_name("vswhere"); } fs::path vs::vcvars() { - return tool_by_name("vcvars"); + return conf::tool_by_name("vcvars"); } std::string vs::version() { - return version_by_name("vs"); + return conf::version_by_name("vs"); } std::string vs::year() { - return version_by_name("vs_year"); + return conf::version_by_name("vs_year"); } std::string vs::toolset() { - return version_by_name("vs_toolset"); + return conf::version_by_name("vs_toolset"); } std::string vs::sdk() { - return version_by_name("sdk"); + return conf::version_by_name("sdk"); } vs& vs::solution(const fs::path& sln) @@ -147,10 +147,15 @@ void vs::do_run() switch (op_) { case upgrade: + { do_upgrade(); + break; + } default: + { cx_->bail_out(context::generic, "vs unknown op {}", op_); + } } } @@ -184,7 +189,7 @@ nuget::nuget(fs::path sln) fs::path nuget::binary() { - return tool_by_name("nuget"); + return conf::tool_by_name("nuget"); } void nuget::do_run() diff --git a/src/tools/tools.h b/src/tools/tools.h index a7e0fa6..659472d 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -134,7 +134,7 @@ class git : public basic_process_runner public: enum ops { - clone_or_pull + clone_or_pull = 1 }; From f2806d10dd26341331a8903c1212adf10831ea3a Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 May 2020 16:22:04 -0400 Subject: [PATCH 5/5] added --no-pull new task_conf() to avoid fiddling with names everywhere changed syntax from tool/section to tool:section, easier to parse --- mob.ini | 1 + src/commands.cpp | 8 ++++- src/commands.h | 1 + src/conf.cpp | 71 +++++++++++++++++--------------------- src/conf.h | 15 +++----- src/tasks/boost_di.cpp | 2 +- src/tasks/gtest.cpp | 2 +- src/tasks/libffi.cpp | 2 +- src/tasks/lz4.cpp | 2 +- src/tasks/modorganizer.cpp | 10 +++--- src/tasks/ncc.cpp | 6 ++-- src/tasks/nmm.cpp | 2 +- src/tasks/python.cpp | 2 +- src/tasks/spdlog.cpp | 2 +- src/tasks/task.cpp | 5 +++ src/tasks/task.h | 40 ++++++++++++++++++++- src/tasks/tasks.h | 1 - src/tasks/usvfs.cpp | 4 +-- src/tools/git.cpp | 54 +++++++++++++++++++---------- src/tools/tools.h | 8 +++-- 20 files changed, 147 insertions(+), 91 deletions(-) diff --git a/mob.ini b/mob.ini index 65d736a..0afa9f2 100644 --- a/mob.ini +++ b/mob.ini @@ -10,6 +10,7 @@ log_file = mob.log [options] mo_org = ModOrganizer2 mo_branch = master +no_pull = false [tools] sevenz = 7z.exe diff --git a/src/commands.cpp b/src/commands.cpp index 7beaff8..81a2b5b 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -279,6 +279,9 @@ clipp::group build_command::do_group() (clipp::option("-n", "--new") >> clean_) % "deletes everything and starts from scratch", + (clipp::option("-p", "--no-pull") >> nopull_) + % "clones repos if necessary, but never pulls once cloned", + (clipp::option("--keep-msbuild") >> keep_msbuild_) % "don't terminate msbuild.exe instances after building", @@ -298,6 +301,9 @@ void build_command::do_pre_run() if (rebuild_ || clean_) common.options.push_back("options/rebuild=true"); + + if (nopull_) + common.options.push_back("options/no_pull=true"); } int build_command::do_run() @@ -329,7 +335,7 @@ void build_command::terminate_msbuild() if (conf::dry()) return; - system("taskkill /im msbuild.exe /f > NUL"); + system("taskkill /im msbuild.exe /f > NUL 2>&1"); } diff --git a/src/commands.h b/src/commands.h index 94da6d0..ee86501 100644 --- a/src/commands.h +++ b/src/commands.h @@ -103,6 +103,7 @@ private: bool reextract_ = false; bool rebuild_ = false; bool clean_ = false; + bool nopull_ = false; bool keep_msbuild_ = false; void terminate_msbuild(); diff --git a/src/conf.cpp b/src/conf.cpp index 8f5cb4c..56813d5 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -138,7 +138,7 @@ std::string conf::global_by_name(const std::string& name) bool conf::bool_global_by_name(const std::string& name) { - std::istringstream iss(get_global("global", name)); + std::istringstream iss(global_by_name(name)); bool b; iss >> std::boolalpha >> b; return b; @@ -150,6 +150,15 @@ std::string conf::option_by_name( return get_for_task(task_names, "options", name); } +bool conf::bool_option_by_name( + const std::vector& task_names, const std::string& name) +{ + std::istringstream iss(option_by_name(task_names, name)); + bool b; + iss >> std::boolalpha >> b; + return b; +} + void conf::set_output_log_level(const std::string& s) { if (s.empty()) @@ -230,30 +239,28 @@ std::vector conf::format_options() struct parsed_option { - std::string section, key, value; + std::string task, section, key, value; }; parsed_option parse_option(const std::string& s) { - const auto slash = s.find("/"); - if (slash == std::string::npos) + // task:section/key=value + // task: is optional + std::regex re(R"((?:(.+)\:)?(.+)/(.*)=(.*))"); + std::smatch m; + + if (!std::regex_match(s, m, re)) { gcx().bail_out(context::conf, - "bad option {}, must be section/key=value", s); + "bad option {}, must be [task:]section/key=value", s); } - const auto equal = s.find("=", slash); - if (slash == std::string::npos) - { - gcx().bail_out(context::conf, - "bad option {}, must be section/key=value", s); - } + std::string task = trim_copy(m[1]); + std::string section = trim_copy(m[2]); + std::string key = trim_copy(m[3]); + std::string value = trim_copy(m[4]); - std::string section = s.substr(0, slash); - std::string key = s.substr(slash + 1, equal - slash - 1); - std::string value = s.substr(equal + 1); - - return {section, key, value}; + return {task, section, key, value}; } bool try_parts(fs::path& check, const std::vector& parts) @@ -671,16 +678,16 @@ void parse_ini(const fs::path& ini, bool add) std::string task, section; - const auto slash = s.find("/"); + const auto col = s.find(":"); - if (slash == std::string::npos) + if (col == std::string::npos) { section = s; } else { - task = s.substr(0, slash); - section = s.substr(slash +1 ); + task = s.substr(0, col); + section = s.substr(col + 1); } parse_section(ini, i, lines, task, section, add); @@ -694,24 +701,6 @@ void parse_ini(const fs::path& ini, bool add) bool check_missing_options() { - if (conf::mo_org({""}).empty()) - { - u8cerr - << "missing mo_org; either specify it the [options] section of " - << "the ini or pass '-s options/mo_org=something'\n"; - - return false; - } - - if (conf::mo_branch({""}).empty()) - { - u8cerr - << "missing mo_branch; either specify it the [options] section of " - << "the ini or pass '-s options/mo_org=something'\n"; - - return false; - } - if (paths::prefix().empty()) { u8cerr @@ -855,7 +844,11 @@ void init_options( for (auto&& o : opts) { const auto po = parse_option(o); - conf::set_global(po.section, po.key, po.value); + + if (po.task.empty()) + conf::set_global(po.section, po.key, po.value); + else + conf::set_for_task(po.task, po.section, po.key, po.value); } } diff --git a/src/conf.h b/src/conf.h index 38628cb..81c7296 100644 --- a/src/conf.h +++ b/src/conf.h @@ -38,6 +38,9 @@ public: static std::string option_by_name( const std::vector& task_names, const std::string& name); + static bool bool_option_by_name( + const std::vector& task_names, const std::string& name); + static int output_log_level() { return output_log_level_; } static void set_output_log_level(const std::string& s); @@ -51,17 +54,6 @@ public: static bool reextract() { return bool_global_by_name("reextract"); } static bool rebuild() { return bool_global_by_name("rebuild"); } - - static std::string mo_org(const std::vector& task_names) - { - return option_by_name(task_names, "mo_org"); - } - - static std::string mo_branch(const std::vector& task_names) - { - return option_by_name(task_names, "mo_branch"); - } - static std::vector format_options(); private: @@ -76,6 +68,7 @@ private: static int file_log_level_; }; + struct paths { #define VALUE(NAME) \ diff --git a/src/tasks/boost_di.cpp b/src/tasks/boost_di.cpp index 21be2a7..c31e93d 100644 --- a/src/tasks/boost_di.cpp +++ b/src/tasks/boost_di.cpp @@ -26,7 +26,7 @@ fs::path boost_di::source_path() void boost_di::do_fetch() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("boost-experimental", "di")) .branch("cpp14") .output(source_path())); diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 571609d..d2a1c1a 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -31,7 +31,7 @@ void gtest::do_clean_for_rebuild() void gtest::do_fetch() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("google", "googletest")) .branch(version()) .output(source_path())); diff --git a/src/tasks/libffi.cpp b/src/tasks/libffi.cpp index e55d7ba..a9b4e65 100644 --- a/src/tasks/libffi.cpp +++ b/src/tasks/libffi.cpp @@ -26,7 +26,7 @@ fs::path libffi::source_path() void libffi::do_fetch() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("python","cpython-bin-deps")) .branch("libffi") .output(source_path())); diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index b8d5433..8f9c4f6 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -72,7 +72,7 @@ void lz4::build_and_install_prebuilt() void lz4::fetch_from_source() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("lz4","lz4")) .branch(version()) .output(source_path())); diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp index ec2ccd5..4a603c9 100644 --- a/src/tasks/modorganizer.cpp +++ b/src/tasks/modorganizer.cpp @@ -58,9 +58,9 @@ void modorganizer::do_fetch() { initialize_super(super_path()); - run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(names()), repo_)) - .branch(conf::mo_branch(names())) + run_tool(git(task_conf().git_op()) + .url(make_github_url(task_conf().mo_org(), repo_)) + .branch(task_conf().mo_branch()) .output(this_source_path())); } @@ -75,10 +75,10 @@ void modorganizer::do_build_and_install() .arg("submodule") .arg("--quiet") .arg("add") - .arg("-b", conf::mo_branch(names())) + .arg("-b", task_conf().mo_branch()) .arg("--force") .arg("--name", name()) - .arg(make_github_url(conf::mo_org(names()), repo_)) + .arg(make_github_url(task_conf().mo_org(), repo_)) .arg(name()) .cwd(super_path()))); } diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index 21ae9fc..f67fb70 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -32,9 +32,9 @@ void ncc::do_clean_for_rebuild() void ncc::do_fetch() { - run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(names()), "modorganizer-NCC")) - .branch(conf::mo_branch(names())) + run_tool(git(task_conf().git_op()) + .url(make_github_url(task_conf().mo_org(), "modorganizer-NCC")) + .branch(task_conf().mo_branch()) .output(source_path())); } diff --git a/src/tasks/nmm.cpp b/src/tasks/nmm.cpp index 5423f7c..45e8b24 100644 --- a/src/tasks/nmm.cpp +++ b/src/tasks/nmm.cpp @@ -31,7 +31,7 @@ void nmm::do_clean_for_rebuild() void nmm::do_fetch() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("Nexus-Mods", "Nexus-Mod-Manager")) .branch(version()) .output(source_path())); diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index f5190f9..e85e230 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -111,7 +111,7 @@ void python::build_and_install_prebuilt() void python::fetch_from_source() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("python", "cpython")) .branch(version()) .output(source_path())); diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp index d0abd49..a2ac18e 100644 --- a/src/tasks/spdlog.cpp +++ b/src/tasks/spdlog.cpp @@ -26,7 +26,7 @@ fs::path spdlog::source_path() void spdlog::do_fetch() { - run_tool(git(git::clone_or_pull) + run_tool(git(task_conf().git_op()) .url(make_github_url("gabime", "spdlog")) .branch(version()) .output(source_path())); diff --git a/src/tasks/task.cpp b/src/tasks/task.cpp index 7b19999..6ddc6b2 100644 --- a/src/tasks/task.cpp +++ b/src/tasks/task.cpp @@ -288,6 +288,11 @@ void task::parallel(std::vector>> t.join(); } +task_conf_holder task::task_conf() const +{ + return task_conf_holder(names_); +} + void task::run() { threaded_run(name(), [&] diff --git a/src/tasks/task.h b/src/tasks/task.h index c2d0e93..f9b6ee4 100644 --- a/src/tasks/task.h +++ b/src/tasks/task.h @@ -2,11 +2,13 @@ #include "../utility.h" #include "../context.h" +#include "../tools/tools.h" namespace mob { class task; +class tool; void add_task(std::unique_ptr t); @@ -25,7 +27,41 @@ void run_all_tasks(); void list_tasks(bool err=false); -class tool; +class task_conf_holder +{ +public: + task_conf_holder(std::vector names) + : names_(std::move(names)) + { + } + + std::string mo_org() + { + return conf::option_by_name(names_, "mo_org"); + } + + std::string mo_branch() + { + return conf::option_by_name(names_, "mo_branch"); + } + + bool no_pull() + { + return conf::bool_option_by_name(names_, "no_pull"); + } + + git::ops git_op() + { + if (no_pull()) + return git::clone; + else + return git::clone_or_pull2; + } + +private: + std::vector names_; +}; + class task { @@ -80,6 +116,8 @@ protected: void threaded_run(std::string name, std::function f); void parallel(std::vector>> v); + task_conf_holder task_conf() const; + private: struct thread_context; diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h index dee788d..5e568dd 100644 --- a/src/tasks/tasks.h +++ b/src/tasks/tasks.h @@ -5,7 +5,6 @@ #include "../conf.h" #include "../utility.h" #include "../op.h" -#include "../tools/tools.h" namespace mob { diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp index da33fa3..c588e5d 100644 --- a/src/tasks/usvfs.cpp +++ b/src/tasks/usvfs.cpp @@ -65,8 +65,8 @@ void usvfs::build_and_install_prebuilt() void usvfs::fetch_from_source() { - run_tool(git(git::clone_or_pull) - .url(make_github_url(conf::mo_org(names()), "usvfs")) + run_tool(git(task_conf().git_op()) + .url(make_github_url(task_conf().mo_org(), "usvfs")) .branch(version()) .output(source_path())); } diff --git a/src/tools/git.cpp b/src/tools/git.cpp index 78c3f5b..5720f2c 100644 --- a/src/tools/git.cpp +++ b/src/tools/git.cpp @@ -35,9 +35,31 @@ git& git::output(const fs::path& dir) void git::do_run() { + if (url_.empty() || where_.empty()) + bail_out("git missing parameters"); + + if (conf::redownload() || conf::reextract()) + { + cx_->trace(context::rebuild, "deleting directory controlled by git"); + op::delete_directory(*cx_, where_, op::optional); + } + + switch (op_) { - case clone_or_pull: + case clone: + { + do_clone(); + break; + } + + case pull: + { + do_pull(); + break; + } + + case clone_or_pull2: { do_clone_or_pull(); break; @@ -52,25 +74,19 @@ void git::do_run() void git::do_clone_or_pull() { - if (url_.empty() || where_.empty()) - bail_out("git missing parameters"); - - if (conf::redownload() || conf::reextract()) - { - cx_->trace(context::rebuild, "deleting directory controlled by git"); - op::delete_directory(*cx_, where_, op::optional); - } - - const fs::path dot_git = where_ / ".git"; - - if (!fs::exists(dot_git)) - clone(); - else - pull(); + if (!do_clone()) + do_pull(); } -void git::clone() +bool git::do_clone() { + const fs::path dot_git = where_ / ".git"; + if (fs::exists(dot_git)) + { + cx_->trace(context::generic, "not cloning, {} exists", dot_git); + return false; + } + process_ = process() .binary(binary()) .stderr_level(context::level::trace) @@ -84,9 +100,11 @@ void git::clone() .arg(where_); execute_and_join(); + + return true; } -void git::pull() +void git::do_pull() { process_ = process() .binary(binary()) diff --git a/src/tools/tools.h b/src/tools/tools.h index 659472d..5167fbc 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -134,7 +134,9 @@ class git : public basic_process_runner public: enum ops { - clone_or_pull = 1 + clone = 1, + pull, + clone_or_pull2 }; @@ -156,8 +158,8 @@ private: fs::path where_; void do_clone_or_pull(); - void clone(); - void pull(); + bool do_clone(); + void do_pull(); };