From ab8f2ee8a2411d6e840a34dbbbd679c3549b5900 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 29 Apr 2020 16:42:50 -0400 Subject: [PATCH] cmd class --- src/main.cpp | 51 +++++------ src/tools.cpp | 239 ++++++++++++++++++++++-------------------------- src/tools.h | 3 + src/utility.cpp | 62 +++++++++++++ src/utility.h | 58 ++++++++++++ 5 files changed, 258 insertions(+), 155 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9944f50..e56ccdd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -630,15 +630,14 @@ protected: private: void configure() { - run_tool( - "perl", - "\"" + third_party::perl().string() + "\" " + - "Configure " - "--openssldir=\"" + build_path().string() + "\" " - "--prefix=\"" + build_path().string() + "\" " - "-FS -MP1 " - "VC-WIN64A", - source_path()); + run_tool(cmd(third_party::perl()) + .arg("Configure") + .arg("--openssldir", build_path()) + .arg("--prefix", build_path()) + .arg("-FS") + .arg("-MP1") + .arg("VC-WIN64A") + .cwd(source_path())); } void install_engines() @@ -813,16 +812,15 @@ protected: } else { - run_tool( - "package python", - "\"" + (source_path() / "python.bat").string() + "\"" - " \"PC/layout\"" - " --source=\"" + source_path().string() + "\"" - " --build=\"" + build_path().string() + "\"" - " --temp=\"" + (build_path() / "pythoncore_temp").string() + "\"" - " --copy=\"" + (build_path() / "pythoncore").string() + "\"" - " --preset-embed", - source_path()); + run_tool(cmd(source_path() / "python.bat") + .name("package python") + .arg(fs::path("PC/layout")) + .arg("--source", source_path()) + .arg("--build", build_path()) + .arg("--temp", (build_path() / "pythoncore_temp")) + .arg("--copy", (build_path() / "pythoncore")) + .arg("--preset-embed") + .cwd(source_path())); op::touch(build_path() / "_mob_packaged"); } @@ -851,11 +849,10 @@ protected: private: void upgrade_project() { - run_tool( - "upgrade project", - "\"" + third_party::devenv().string() + "\" " - "\"" + solution_file().string() + "\" " - "/upgrade" + redir_nul()); + run_tool(cmd(third_party::devenv()) + .name("upgrade project") + .arg(solution_file()) + .arg("/upgrade")); } fs::path solution_file() const @@ -937,15 +934,15 @@ int run(int argc, char** argv) vcvars(); prepend_to_path(find_third_party_directory() / "bin"); - //g_tasks.push_back(std::make_unique()); + g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); - //g_tasks.push_back(std::make_unique()); + g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); - g_tasks.push_back(std::make_unique()); + //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); //g_tasks.push_back(std::make_unique()); diff --git a/src/tools.cpp b/src/tools.cpp index f603602..61bf8c9 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -39,7 +39,7 @@ void vcvars() const fs::path tmp = paths::temp_file(); const std::string cmd = - "\"" + find_vcvars().string() + "\" amd64" + redir_nul() + " && " + "\"" + find_vcvars().string() + "\" amd64 && " "set > \"" + tmp.string() + "\""; op::run(cmd); @@ -69,29 +69,6 @@ void vcvars() } -process do_cmake( - const fs::path& build, const fs::path& prefix, - const std::string& args, const std::string& generator) -{ - std::string cmd = "\"" + third_party::cmake().string() + "\""; - - cmd += " -G \"" + generator + "\" -DCMAKE_INSTALL_MESSAGE=NEVER"; - - if (!prefix.empty()) - cmd += " -DCMAKE_INSTALL_PREFIX=\"" + prefix.string() + "\""; - - if (!conf::verbose()) - cmd += " --log-level=WARNING"; - - if (!args.empty()) - cmd += " " + args; - - cmd += " .."; - - return op::run(cmd, build); -} - - tool::tool(std::string name) : name_(std::move(name)), interrupted_(false) { @@ -145,6 +122,11 @@ int process_runner::execute_and_join(process p, bool check_exit_code) return process_.exit_code(); } +int process_runner::execute_and_join(const cmd& c, bool check_exit_code) +{ + return execute_and_join(op::run(c.string(), c.cwd()), check_exit_code); +} + void process_runner::join(bool check_exit_code) { process_.join(); @@ -266,46 +248,26 @@ void git_clone::do_run() void git_clone::clone() { - std::ostringstream oss; - - oss - << "\"" + third_party::git().string() + "\"" - << " clone" - << " --recurse-submodules" - << " --depth 1" - << " --branch \"" + branch_ + "\" "; - - if (!conf::verbose()) - { - oss - << " --quiet" - << " -c advice.detachedHead=false"; - } - - oss - << " \"" + repo_url().string() + "\" " - << " \"" + where_.string() + "\""; - - execute_and_join(op::run(oss.str())); + execute_and_join(cmd(third_party::git()) + .arg("clone") + .arg("--recurse-submodules") + .arg("--depth", "1") + .arg("--branch", branch_) + .arg("--quiet", cmd::quiet) + .arg("-c", "advice.detachedHead=false", cmd::quiet) + .arg(repo_url()) + .arg(where_)); } void git_clone::pull() { - std::ostringstream oss; - - oss - << "\"" + third_party::git().string() + "\"" - << " pull" - << " --recurse-submodules"; - - if (!conf::verbose()) - oss << " --quiet"; - - oss - << " \"" + repo_url().string() + "\" " - << " \"" << branch_ << "\""; - - execute_and_join(op::run(oss.str(), where_)); + execute_and_join(cmd(third_party::git()) + .arg("pull") + .arg("--recurse-submodules") + .arg("--quiet", cmd::quiet) + .arg(repo_url()) + .arg(branch_) + .cwd(where_)); } url git_clone::repo_url() const @@ -336,14 +298,9 @@ void decompresser::do_run() info("decompress " + file_.string() + " into " + where_.string()); op::touch(interrupt_file()); - - const auto sevenz = "\"" + third_party::sevenz().string() + "\""; - op::create_directories(where_); directory_deleter delete_output(where_); - process p; - // the -spe from 7z is supposed to figure out if there's a folder in the // archive with the same name as the target and extract its content to // avoid duplicating the folder @@ -360,20 +317,38 @@ void decompresser::do_run() // so the handling of a duplicate directory is done manually in // check_duplicate_directory() below + std::string c; + if (file_.string().ends_with(".tar.gz")) { - p = op::run( - sevenz + " x -so \"" + file_.string() + "\" | " + - sevenz + " x -aoa -si -ttar -o\"" + where_.string() + "\" " + redir_nul()); + c = cmd(third_party::sevenz()) + .arg("x") + .arg("-so", file_) + .string(); + + c += " | "; + + c += cmd(third_party::sevenz()) + .arg("x") + .arg("-aoa") + .arg("-si") + .arg("-ttar") + .arg("-o", where_, cmd::nospace) + .string(); } else { - p = op::run( - sevenz + " x -aoa -bd -bb0 -o\"" + where_.string() + "\" " - "\"" + file_.string() + "\" " + redir_nul()); + c = cmd(third_party::sevenz()) + .arg("x") + .arg("-aoa") + .arg("-bd") + .arg("-bb0") + .arg("-o", where_, cmd::nospace) + .arg(file_) + .string(); } - execute_and_join(std::move(p)); + execute_and_join(op::run(c)); check_duplicate_directory(); delete_output.cancel(); @@ -450,18 +425,11 @@ void patcher::do_run() if (!fs::exists(patches_)) return; - std::ostringstream oss; - - oss - << "\"" << third_party::patch().string() << "\" " - << "--read-only=ignore " - << "--strip=0 " - << "--directory=\"" << output_.string() << "\" "; - - if (!conf::verbose()) - oss << "--quiet "; - - const std::string base = oss.str(); + const auto base = cmd(third_party::patch()) + .arg("--read-only", "ignore") + .arg("--strip", "0") + .arg("--directory", output_) + .arg("--quiet", cmd::quiet); for (auto e : fs::directory_iterator(patches_)) { @@ -478,13 +446,20 @@ void patcher::do_run() continue; } - const std::string input = "--input=\"" + p.string() + "\""; - const std::string check = base + " --dry-run --force --reverse " + input + redir_nul(); - const std::string apply = base + " --forward --batch " + input + redir_nul(); + const auto check = cmd(base) + .arg("--dry-run") + .arg("--force") + .arg("--reverse") + .arg("--input", p); + + const auto apply = cmd(base) + .arg("--forward") + .arg("--batch") + .arg("--input", p); { // check - if (execute_and_join(op::run(check), false) == 0) + if (execute_and_join(check, false) == 0) { debug("patch " + p.string() + " already applied"); continue; @@ -494,12 +469,32 @@ void patcher::do_run() { // apply debug("applying patch " + p.string()); - execute_and_join(op::run(apply)); + execute_and_join(apply); } } } +process do_cmake( + const fs::path& build, const fs::path& prefix, + const std::string& args, const std::string& generator) +{ + auto c = cmd(third_party::cmake()) + .arg("-G", generator) + .arg("-DCMAKE_INSTALL_MESSAGE=NEVER") + .arg("--log-level", "WARNING", cmd::quiet); + + if (!prefix.empty()) + c.arg("-DCMAKE_INSTALL_PREFIX=", prefix, cmd::nospace); + + c + .arg(args) + .arg(".."); + + return op::run(c.string(), build); +} + + cmake_for_nmake::cmake_for_nmake(fs::path r, std::string a, fs::path p) : process_runner("cmake_for_nmake"), root_(std::move(r)), args_(std::move(a)), prefix_(std::move(p)) @@ -547,27 +542,21 @@ jom::jom(fs::path dir, std::string target, std::string args, flags f) : void jom::do_run() { - std::ostringstream oss; - oss << "\"" << third_party::jom().string() << "\""; - - if (!conf::verbose()) - oss << " /C /S"; - - oss << " /K "; + auto c = cmd(third_party::jom()) + .arg("/C", cmd::quiet) + .arg("/S", cmd::quiet) + .arg("/K"); if (flags_ & single_job) - oss << " /J 1"; + c.arg("/J", "1"); - if (!args_.empty()) - oss << " " << args_; - - if (!target_.empty()) - oss << " " << target_; - - oss << redir_nul(); + c + .arg(args_) + .arg(target_) + .cwd(dir_); const bool check_exit_code = !(flags_ & accept_failure); - execute_and_join(op::run(oss.str(), dir_), check_exit_code); + execute_and_join(c, check_exit_code); } @@ -584,35 +573,29 @@ msbuild::msbuild( void msbuild::do_run() { - std::ostringstream oss; - - oss - << "\"" << third_party::msbuild().string() << "\"" - << " -nologo " - << " -maxCpuCount" - << " -property:UseMultiToolTask=true " - << " -property:EnforceProcessCountAcrossBuilds=true " - << " -property:Configuration=Release" - << " -property:Platform=x64" - << " -property:PlatformToolset=" + versions::vs_toolset() - << " -property:WindowsTargetPlatformVersion=" << versions::sdk(); + auto c = cmd(third_party::msbuild()) + .arg("-nologo") + .arg("-maxCpuCount") + .arg("-property:UseMultiToolTask=true") + .arg("-property:EnforceProcessCountAcrossBuilds=true") + .arg("-property:Configuration=Release") + .arg("-property:Platform=x64") + .arg("-property:PlatformToolset=" + versions::vs_toolset()) + .arg("-property:WindowsTargetPlatformVersion=" + versions::sdk()) + .arg("-verbosity:minimal", cmd::quiet) + .arg("-consoleLoggerParameters:ErrorsOnly", cmd::quiet); if (!projects_.empty()) - oss << " -target:" + builder::join(projects_, ","); + c.arg("-target:" + builder::join(projects_, ",")); for (auto&& p : params_) - oss << " -property:" + p; + c.arg("-property:" + p); - if (!conf::verbose()) - { - oss - << " -verbosity:minimal " - << " -consoleLoggerParameters:ErrorsOnly "; - } + c + .arg(sln_) + .cwd(sln_.parent_path()); - oss << " \"" + sln_.string() + "\""; - - execute_and_join(op::run(oss.str(), sln_.parent_path())); + execute_and_join(c); } } // namespace diff --git a/src/tools.h b/src/tools.h index 3162a28..b4d0c26 100644 --- a/src/tools.h +++ b/src/tools.h @@ -56,6 +56,7 @@ class process_runner : public tool { public: process_runner(std::string name, std::string cmd, fs::path cwd={}); + process_runner(const cmd& c); void join(bool check_exit_code=true); int exit_code() const; @@ -65,7 +66,9 @@ protected: void do_run() override; void do_interrupt() override; + int execute_and_join(process p, bool check_exit_code=true); + int execute_and_join(const cmd& c, bool check_exit_code=true); private: std::string cmd_; diff --git a/src/utility.cpp b/src/utility.cpp index c81ec80..90d641f 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -2,6 +2,7 @@ #include "utility.h" #include "conf.h" #include "op.h" +#include "net.h" namespace builder { @@ -188,6 +189,67 @@ std::string join(const std::vector& v, const std::string& sep) return s; } +cmd& cmd::name(const std::string& s) +{ + name_ = s; + return *this; +} + +const std::string& cmd::name() const +{ + if (name_.empty()) + return exe_; + else + return name_; +} + +cmd& cmd::cwd(const fs::path& p) +{ + cwd_ = p; + return *this; +} + +const fs::path& cmd::cwd() const +{ + return cwd_; +} + +void cmd::add_arg(const std::string& name, const std::string& value, flags f) +{ + if ((f & quiet) && conf::verbose()) + return; + + if (name.empty() && value.empty()) + return; + + if (name.empty()) + s_ += " " + value; + else if (f & nospace) + s_ += " " + name + value; + else + s_ += " " + name + " " + value; +} + +std::string cmd::arg_to_string(const char* s) +{ + return std::string(" ") + s; +} + +std::string cmd::arg_to_string(const std::string& s) +{ + return " " + s; +} + +std::string cmd::arg_to_string(const fs::path& p) +{ + return " \"" + p.string() + "\""; +} + +std::string cmd::arg_to_string(const url& u) +{ + return " " + u.string(); +} + file_deleter::file_deleter(fs::path p) : p_(std::move(p)), delete_(true) diff --git a/src/utility.h b/src/utility.h index 73b730e..f611e85 100644 --- a/src/utility.h +++ b/src/utility.h @@ -3,6 +3,8 @@ namespace builder { +class url; + class bailed { public: @@ -138,4 +140,60 @@ std::string replace_all( std::string join(const std::vector& v, const std::string& sep); + +class cmd +{ +public: + enum flags + { + noflags = 0x00, + quiet = 0x01, + nospace = 0x02 + }; + + cmd(const fs::path& exe) + : exe_(exe.filename().string()) + { + s_ += arg_to_string(exe); + } + + cmd& name(const std::string& s); + const std::string& name() const; + + cmd& cwd(const fs::path& p); + const fs::path& cwd() const; + + template + cmd& arg(const T& value, flags f=noflags) + { + add_arg("", arg_to_string(value), f); + return *this; + } + + template + cmd& arg(const std::string& name, const T& value, flags f=noflags) + { + add_arg(name, arg_to_string(value), f); + return *this; + } + + const std::string& string() const + { + return s_; + } + +private: + std::string name_; + std::string exe_; + fs::path cwd_; + std::string s_; + + void add_arg(const std::string& name, const std::string& value, flags f); + + std::string arg_to_string(const char* s); + std::string arg_to_string(const std::string& s); + std::string arg_to_string(const fs::path& p); + std::string arg_to_string(const url& u); +}; + } // namespace