diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp index bd97c27..e77f5cd 100644 --- a/src/tasks/boost.cpp +++ b/src/tasks/boost.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index 417ac4f..4af1302 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/openssl.cpp b/src/tasks/openssl.cpp index 91b43e3..5c85b3e 100644 --- a/src/tasks/openssl.cpp +++ b/src/tasks/openssl.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/pyqt.cpp b/src/tasks/pyqt.cpp index d156aed..102faa2 100644 --- a/src/tasks/pyqt.cpp +++ b/src/tasks/pyqt.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index 59e3bd7..6b84f1c 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/sip.cpp b/src/tasks/sip.cpp index 98875a6..00c6e56 100644 --- a/src/tasks/sip.cpp +++ b/src/tasks/sip.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/process.h" namespace mob { diff --git a/src/tasks/translations.cpp b/src/tasks/translations.cpp index 0bee069..e61191e 100644 --- a/src/tasks/translations.cpp +++ b/src/tasks/translations.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tasks.h" +#include "../core/env.h" #include "../utility/threading.h" namespace mob diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp index 5d6e027..34a1e4b 100644 --- a/src/tools/cmake.cpp +++ b/src/tools/cmake.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tools.h" +#include "../core/process.h" namespace mob { @@ -46,7 +47,7 @@ cmake& cmake::prefix(const fs::path& s) cmake& cmake::def(const std::string& name, const std::string& value) { - process_.arg("-D" + name + "=" + value + ""); + def_.emplace_back(name, value); return *this; } @@ -119,7 +120,7 @@ void cmake::do_generate() const auto& g = get_generator(gen_); - process_ + auto p = process() .stdout_encoding(encodings::utf8) .stderr_encoding(encodings::utf8) .binary(binary()) @@ -130,29 +131,33 @@ void cmake::do_generate() if (genstring_.empty()) { - process_ + p .arg("-G", "\"" + g.name + "\"") .arg(g.get_arch(arch_)); } else { - process_ + p .arg("-G", "\"" + genstring_ + "\""); } if (!prefix_.empty()) - process_.arg("-DCMAKE_INSTALL_PREFIX=", prefix_, process::nospace); + p.arg("-DCMAKE_INSTALL_PREFIX=", prefix_, process::nospace); + + for (auto&& [name, value] : def_) + p.arg("-D" + name + "=" + value + ""); if (cmd_.empty()) - process_.arg(".."); + p.arg(".."); else - process_.arg(cmd_); + p.arg(cmd_); - process_ + p .env(env::vs(arch_) .set("CXXFLAGS", "/wd4566")) .cwd(build_path()); + set_process(p); execute_and_join(); } diff --git a/src/tools/extractor.cpp b/src/tools/extractor.cpp index 6510e48..ebb7a63 100644 --- a/src/tools/extractor.cpp +++ b/src/tools/extractor.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "tools.h" +#include "../core/process.h" namespace mob { @@ -89,18 +90,18 @@ void extractor::do_run() .arg("-ttar") .arg("-o", where_, process::nospace); - process_ = process::pipe(extract_tar, extract_gz); + set_process(process::pipe(extract_tar, extract_gz)); } else { - process_ = process() + set_process(process() .binary(binary()) .arg("x") .arg("-aoa") .arg("-bd") .arg("-bb0") .arg("-o", where_, process::nospace) - .arg(file_); + .arg(file_)); } execute_and_join(); diff --git a/src/tools/git.cpp b/src/tools/git.cpp index 5ee623f..aff3620 100644 --- a/src/tools/git.cpp +++ b/src/tools/git.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "tools.h" #include "../core/conf.h" +#include "../core/process.h" #include "../utility/threading.h" namespace mob @@ -130,12 +131,12 @@ void git::apply(const fs::path& p, const std::string& diff) void git::apply(const std::string& diff) { - process_ = make_process() + set_process(make_process() .stdin_string(diff) .arg("apply") .arg("--whitespace", "nowarn") .arg("-") - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -150,12 +151,12 @@ void git::fetch( void git::fetch(const std::string& remote, const std::string& branch) { - process_ = make_process() + set_process(make_process() .arg("fetch") .arg("-q") .arg(remote) .arg(branch) - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -169,12 +170,12 @@ void git::checkout(const fs::path& p, const std::string& what) void git::checkout(const std::string& what) { - process_ = make_process() + set_process(make_process() .arg("-c", "advice.detachedHead=false") .arg("checkout") .arg("-q") .arg(what) - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -188,15 +189,15 @@ std::string git::current_branch(const fs::path& p) std::string git::current_branch() { - process_ = make_process() + set_process(make_process() .stdout_flags(process::keep_in_string) .arg("branch") .arg("--show-current") - .cwd(root_); + .cwd(root_)); execute_and_join(); - return trim_copy(process_.stdout_string()); + return trim_copy(get_process().stdout_string()); } fs::path git::binary() @@ -327,7 +328,7 @@ process git::make_process() void git::do_add_submodule() { - process_ = make_process() + set_process(make_process() .stderr_level(context::level::trace) .arg("-c", "core.autocrlf=false") .arg("submodule") @@ -338,7 +339,7 @@ void git::do_add_submodule() .arg("--name", submodule_) .arg(url_) .arg(submodule_) - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -358,21 +359,22 @@ bool git::do_clone() return false; } - process_ = make_process() + auto p = make_process() .stderr_level(context::level::trace) .arg("clone") .arg("--recurse-submodules"); if (shallow_) - process_.arg("--depth", "1"); + p.arg("--depth", "1"); - process_ + p .arg("--branch", branch_) .arg("--quiet", process::log_quiet) .arg("-c", "advice.detachedHead=false", process::log_quiet) .arg(url_) .arg(root_); + set_process(p); execute_and_join(); @@ -393,14 +395,14 @@ void git::do_pull() if (revert_ts_) do_revert_ts(); - process_ = make_process() + set_process(make_process() .stderr_level(context::level::trace) .arg("pull") .arg("--recurse-submodules") .arg("--quiet", process::log_quiet) .arg(url_) .arg(branch_) - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -489,11 +491,11 @@ void git::do_revert_ts() return; } - process_ = make_process() + set_process(make_process() .stderr_level(context::level::trace) .arg("checkout") .arg(p) - .cwd(root_); + .cwd(root_)); execute_and_join(); }); @@ -501,93 +503,93 @@ void git::do_revert_ts() void git::set_config(const std::string& key, const std::string& value) { - process_ = make_process() + set_process(make_process() .stderr_level(context::level::trace) .arg("config") .arg(key) .arg(value) - .cwd(root_); + .cwd(root_)); execute_and_join(); } bool git::has_remote(const std::string& name) { - process_ = make_process() + set_process(make_process() .flags(process::allow_failure) .stderr_level(context::level::debug) .arg("config") .arg("remote." + name + ".url") - .cwd(root_); + .cwd(root_)); return (execute_and_join() == 0); } void git::rename_remote(const std::string& from, const std::string& to) { - process_ = make_process() + set_process(make_process() .arg("remote") .arg("rename") .arg(from) .arg(to) - .cwd(root_); + .cwd(root_)); execute_and_join(); } void git::add_remote(const std::string& name, const std::string& url) { - process_ = make_process() + set_process(make_process() .arg("remote") .arg("add") .arg(name) .arg(url) - .cwd(root_); + .cwd(root_)); execute_and_join(); } void git::set_remote_push(const std::string& remote, const std::string& url) { - process_ = make_process() + set_process(make_process() .arg("remote") .arg("set-url") .arg("--push") .arg(remote) .arg(url) - .cwd(root_); + .cwd(root_)); execute_and_join(); } void git::set_assume_unchanged(const fs::path& relative_file, bool on) { - process_ = make_process() + set_process(make_process() .arg("update-index") .arg(on ? "--assume-unchanged" : "--no-assume-unchanged") .arg(relative_file, process::forward_slashes) - .cwd(root_); + .cwd(root_)); execute_and_join(); } bool git::is_tracked(const fs::path& relative_file) { - process_ = make_process() + set_process(make_process() .stdout_level(context::level::debug) .stderr_level(context::level::debug) .flags(process::allow_failure) .arg("ls-files") .arg("--error-unmatch") .arg(relative_file, process::forward_slashes) - .cwd(root_); + .cwd(root_)); return (execute_and_join() == 0); } bool git::is_repo() { - process_ = make_process() + set_process(make_process() .arg("rev-parse") .arg("--is-inside-work-tree") .stderr_filter([](process::filter& f) @@ -596,71 +598,71 @@ bool git::is_repo() f.lv = context::level::trace; }) .flags(process::allow_failure) - .cwd(root_); + .cwd(root_)); return (execute_and_join() == 0); } bool git::branch_exists() { - process_ = make_process() + set_process(make_process() .flags(process::allow_failure) .arg("ls-remote") .arg("--exit-code") .arg("--heads") .arg(url_) - .arg(branch_); + .arg(branch_)); return (execute_and_join() == 0); } bool git::has_uncommitted_changes() { - process_ = make_process() + set_process(make_process() .flags(process::allow_failure) .stdout_flags(process::keep_in_string) .arg("status") .arg("-s") .arg("--porcelain") - .cwd(root_); + .cwd(root_)); execute_and_join(); - return (process_.stdout_string() != ""); + return (get_process().stdout_string() != ""); } bool git::has_stashed_changes() { - process_ = make_process() + set_process(make_process() .flags(process::allow_failure) .stderr_level(context::level::trace) .arg("stash show") - .cwd(root_); + .cwd(root_)); return (execute_and_join() == 0); } void git::init() { - process_ = make_process() + set_process(make_process() .arg("init") - .cwd(root_); + .cwd(root_)); execute_and_join(); } std::string git::git_file() { - process_ = make_process() + set_process(make_process() .stdout_flags(process::keep_in_string) .arg("remote") .arg("get-url") .arg("origin") - .cwd(root_); + .cwd(root_)); execute_and_join(); - const std::string out = process_.stdout_string(); + const std::string out = get_process().stdout_string(); const auto last_slash = out.find_last_of("/"); if (last_slash == std::string::npos) diff --git a/src/tools/jom.cpp b/src/tools/jom.cpp index 45426c0..b4163e5 100644 --- a/src/tools/jom.cpp +++ b/src/tools/jom.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "tools.h" #include "../core/conf.h" +#include "../core/process.h" namespace mob { @@ -17,7 +18,7 @@ fs::path jom::binary() jom& jom::path(const fs::path& p) { - process_.cwd(p); + cwd_ = p; return *this; } @@ -29,7 +30,7 @@ jom& jom::target(const std::string& s) jom& jom::def(const std::string& s) { - process_.arg(s); + def_.push_back(s); return *this; } @@ -52,15 +53,18 @@ int jom::result() const void jom::do_run() { + process p; + process::flags_t pflags = process::terminate_on_interrupt; if (flags_ & allow_failure) { - process_.stderr_level(context::level::trace); + p.stderr_level(context::level::trace); pflags |= process::allow_failure; } - process_ + p .binary(binary()) + .cwd(cwd_) .stderr_filter([](process::filter& f) { if (f.line.find("empower your cores") != std::string::npos) @@ -75,13 +79,17 @@ void jom::do_run() .arg("/K"); if (flags_ & single_job) - process_.arg("/J", "1"); + p.arg("/J", "1"); - process_ + for (auto&& def : def_) + p.arg(def); + + p .arg(target_) .flags(pflags) .env(env::vs(arch_)); + set_process(p); execute_and_join(); } diff --git a/src/tools/msbuild.cpp b/src/tools/msbuild.cpp index 3c23ad5..22d6d91 100644 --- a/src/tools/msbuild.cpp +++ b/src/tools/msbuild.cpp @@ -1,10 +1,21 @@ #include "pch.h" #include "tools.h" #include "../core/conf.h" +#include "../core/process.h" namespace mob { +void error_filter(process::filter& f) +{ + // ": error C2065" + // ": error MSB1009" + static std::regex re(": error [A-Z]"); + if (std::regex_search(f.line.begin(), f.line.end(), re)) + f.lv = context::level::error; +} + + msbuild::msbuild(ops o) : basic_process_runner("msbuild"), op_(o), config_("Release"), arch_(arch::def), flags_(noflags) @@ -127,18 +138,19 @@ void msbuild::do_run(const std::vector& targets) } process::flags_t pflags = process::noflags; + process p; if (is_set(flags_, allow_failure)) { - process_.stderr_level(context::level::trace); + p.stderr_level(context::level::trace); pflags |= process::allow_failure; } else { - process_.stdout_filter([&](auto& f){ error_filter(f); }); + p.stdout_filter([&](auto& f){ error_filter(f); }); } - process_ + p .binary(binary()) .chcp(65001) .stdout_encoding(encodings::utf8) @@ -147,13 +159,13 @@ void msbuild::do_run(const std::vector& targets) if (!is_set(flags_, single_job)) { - process_ + p .arg("-maxCpuCount") .arg("-property:UseMultiToolTask=true") .arg("-property:EnforceProcessCountAcrossBuilds=true"); } - process_ + p .arg("-property:Configuration=", config_, process::quote) .arg("-property:PlatformToolset=" + toolset) .arg("-property:WindowsTargetPlatformVersion=" + vs::sdk()) @@ -163,22 +175,23 @@ void msbuild::do_run(const std::vector& targets) .arg("-consoleLoggerParameters:ErrorsOnly", process::log_quiet); if (!targets.empty()) - process_.arg("-target:" + mob::join(targets, ";")); + p.arg("-target:" + mob::join(targets, ";")); - for (auto&& p : params_) - process_.arg("-property:" + p); + for (auto&& param : params_) + p.arg("-property:" + param); env e = env::vs(arch_); - for (auto&& p : prepend_path_) - e.prepend_path(p); + for (auto&& path : prepend_path_) + e.prepend_path(path); - process_ + p .arg(sln_) .flags(pflags) .cwd(sln_.parent_path()) .env(e); + set_process(p); execute_and_join(); } @@ -188,13 +201,4 @@ void msbuild::do_clean() do_run(map(targets_, [&](auto&& t){ return t + ":Clean"; })); } -void msbuild::error_filter(process::filter& f) const -{ - // ": error C2065" - // ": error MSB1009" - static std::regex re(": error [A-Z]"); - if (std::regex_search(f.line.begin(), f.line.end(), re)) - f.lv = context::level::error; -} - } // namespace diff --git a/src/tools/patcher.cpp b/src/tools/patcher.cpp index 27d6916..bffb138 100644 --- a/src/tools/patcher.cpp +++ b/src/tools/patcher.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "tools.h" #include "../core/conf.h" +#include "../core/process.h" namespace mob { @@ -129,7 +130,7 @@ void patcher::do_patch(const fs::path& patch_file) cx().trace(context::generic, "checking if already patched"); - process_ = check; + set_process(check); const auto ret = execute_and_join(); if (ret == 0) @@ -154,7 +155,7 @@ void patcher::do_patch(const fs::path& patch_file) // apply cx().trace(context::generic, "applying patch {}", patch_file); - process_ = apply; + set_process(apply); execute_and_join(); } } diff --git a/src/tools/process_runner.cpp b/src/tools/process_runner.cpp index 53cdbcc..4de5c11 100644 --- a/src/tools/process_runner.cpp +++ b/src/tools/process_runner.cpp @@ -1,43 +1,58 @@ #include "pch.h" #include "tools.h" #include "../core/conf.h" +#include "../core/process.h" namespace mob { basic_process_runner::basic_process_runner(std::string name) - : tool(std::move(name)) + : tool(std::move(name)), process_(new process) { } +basic_process_runner::basic_process_runner(basic_process_runner&& r) = default; + +basic_process_runner::~basic_process_runner() = default; + +void basic_process_runner::set_process(const process& p) +{ + process_.reset(new process(p)); +} + +process& basic_process_runner::get_process() +{ + return *process_; +} + void basic_process_runner::do_interrupt() { - process_.interrupt(); + process_->interrupt(); } int basic_process_runner::execute_and_join() { - set_name(process_.name()); - process_.set_context(&cx()); - process_.run(); + set_name(process_->name()); + process_->set_context(&cx()); + process_->run(); join(); - return process_.exit_code(); + return process_->exit_code(); } void basic_process_runner::join() { - process_.join(); + process_->join(); } int basic_process_runner::exit_code() const { - return process_.exit_code(); + return process_->exit_code(); } process_runner::process_runner(process&& p) - : tool(p.name()), own_(std::move(p)), p_(nullptr) + : tool(p.name()), own_(new process(std::move(p))), p_(nullptr) { } @@ -46,6 +61,8 @@ process_runner::process_runner(process& p) { } +process_runner::~process_runner() = default; + void process_runner::do_run() { execute_and_join(); @@ -87,7 +104,7 @@ process& process_runner::real_process() if (p_) return *p_; else - return own_; + return *own_; } const process& process_runner::real_process() const @@ -95,7 +112,7 @@ const process& process_runner::real_process() const if (p_) return *p_; else - return own_; + return *own_; } } // namespace diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index e74599f..d6cd95b 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -3,6 +3,7 @@ #include "../utility.h" #include "../core/op.h" #include "../core/conf.h" +#include "../core/process.h" #include "../tasks/tasks.h" namespace mob @@ -177,11 +178,11 @@ void vs::do_upgrade() return; } - process_ + set_process(process() .binary(devenv_binary()) .env(env::vs(arch::x64)) .arg("/upgrade") - .arg(sln_); + .arg(sln_)); execute_and_join(); } @@ -190,11 +191,11 @@ void vs::do_upgrade() nuget::nuget(fs::path sln) : basic_process_runner("nuget"), sln_(std::move(sln)) { - process_ + set_process(process() .binary(binary()) .arg("restore") .arg(sln_) - .cwd(sln_.parent_path()); + .cwd(sln_.parent_path())); } fs::path nuget::binary() @@ -233,7 +234,7 @@ pip_install& pip_install::file(const fs::path& p) void pip_install::do_run() { - process_ + auto p = process() .binary(python::python_exe()) .chcp(65001) .stdout_encoding(encodings::utf8) @@ -245,14 +246,15 @@ void pip_install::do_run() .arg("--disable-pip-version-check"); if (!package_.empty()) - process_.arg(package_ + "==" + version_); + p.arg(package_ + "==" + version_); else if (!file_.empty()) - process_.arg(file_); + p.arg(file_); - process_ + p .env(this_env::get() .set("PYTHONUTF8", "1")); + set_process(p); execute_and_join(); } @@ -331,13 +333,13 @@ void transifex::do_init() // exit code is 2 when the directory already contains a .tx - process_ = process() + set_process(process() .binary(binary()) .success_exit_codes({0, 2}) .flags(process::ignore_output_on_success) .arg("init") .arg("--no-interactive") - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -349,7 +351,7 @@ void transifex::do_config() op::create_directories(cx(), root_, op::unsafe); - process_ = process() + set_process(process() .binary(binary()) .stdout_level(stdout_) .arg("config") @@ -357,7 +359,7 @@ void transifex::do_config() .arg(url_) .env(this_env::get() .set("TX_TOKEN", key_)) - .cwd(root_); + .cwd(root_)); execute_and_join(); } @@ -366,7 +368,7 @@ void transifex::do_pull() { op::create_directories(cx(), root_, op::unsafe); - process_ = process() + auto p = process() .binary(binary()) .stdout_level(stdout_) .arg("pull") @@ -379,8 +381,9 @@ void transifex::do_pull() .cwd(root_); if (force_) - process_.arg("--force"); + p.arg("--force"); + set_process(p); execute_and_join(); } @@ -438,7 +441,7 @@ void lrelease::do_run() { const auto qm = qm_file(); - process_ = process() + auto p = process() .binary(binary()) .arg("-silent") .stderr_filter([](auto&& f) @@ -451,11 +454,12 @@ void lrelease::do_run() for (auto&& s : sources_) - process_.arg(s); + p.arg(s); - process_ + p .arg("-qm", (out_ / qm)); + set_process(p); execute_and_join(); } @@ -481,9 +485,9 @@ void iscc::do_run() if (iss_.empty()) cx().bail_out(context::generic, "iscc missing iss file"); - process_ + set_process(process() .binary(binary()) - .arg(iss_); + .arg(iss_)); execute_and_join(); } diff --git a/src/tools/tools.h b/src/tools/tools.h index 9001763..2b1c3bd 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -1,7 +1,6 @@ #pragma once #include "../net.h" -#include "../core/process.h" #include "../core/conf.h" #include "../core/op.h" #include "../core/context.h" @@ -9,6 +8,8 @@ namespace mob { +class process; + class tool { public: @@ -100,16 +101,24 @@ private: class basic_process_runner : public tool { public: + // anchors + basic_process_runner(basic_process_runner&&); + ~basic_process_runner(); + void join(); int exit_code() const; protected: - process process_; - basic_process_runner(std::string name); + void set_process(const process& p); + process& get_process(); + void do_interrupt() override; int execute_and_join(); + +private: + std::unique_ptr process_; }; @@ -119,6 +128,9 @@ public: process_runner(process&& p); process_runner(process& p); + // anchor + ~process_runner(); + void join(); int exit_code() const; @@ -128,7 +140,7 @@ protected: void do_run() override; private: - process own_; + std::unique_ptr own_; process* p_; void do_interrupt() override; @@ -411,6 +423,7 @@ private: generators gen_; std::string genstring_; fs::path prefix_; + std::vector> def_; fs::path output_; arch arch_; std::string cmd_; @@ -449,6 +462,8 @@ protected: void do_run() override; private: + fs::path cwd_; + std::vector def_; std::string target_; flags_t flags_; arch arch_; @@ -503,8 +518,6 @@ private: void do_clean(); void do_build(); void do_run(const std::vector& targets); - - void error_filter(process::filter& f) const; }; MOB_ENUM_OPERATORS(msbuild::flags_t);