2020-04-27 09:43:05 -04:00
|
|
|
#include "pch.h"
|
|
|
|
|
#include "utility.h"
|
|
|
|
|
#include "conf.h"
|
|
|
|
|
#include "op.h"
|
2020-04-29 16:42:50 -04:00
|
|
|
#include "net.h"
|
2020-04-27 09:43:05 -04:00
|
|
|
|
|
|
|
|
namespace builder
|
|
|
|
|
{
|
|
|
|
|
|
2020-04-27 14:40:28 -04:00
|
|
|
struct color
|
|
|
|
|
{
|
|
|
|
|
color(int r, int g, int b)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "\033[38;2;" << r << ";" << g << ";" << b << "m";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~color()
|
|
|
|
|
{
|
|
|
|
|
std::cout << "\033[39m\033[49m";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
color(const color&) = delete;
|
|
|
|
|
color& operator=(const color&) = delete;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<color> color_for_level(level lv)
|
|
|
|
|
{
|
|
|
|
|
switch (lv)
|
|
|
|
|
{
|
|
|
|
|
case level::error:
|
|
|
|
|
case level::bail:
|
|
|
|
|
return std::make_unique<color>(240, 50, 50);
|
|
|
|
|
|
|
|
|
|
case level::warning:
|
|
|
|
|
return std::make_unique<color>(240, 240, 50);
|
|
|
|
|
|
|
|
|
|
case level::debug:
|
|
|
|
|
return std::make_unique<color>(150, 150, 150);
|
|
|
|
|
|
|
|
|
|
case level::info:
|
|
|
|
|
default:
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-04-27 09:43:05 -04:00
|
|
|
std::string error_message(DWORD e)
|
|
|
|
|
{
|
|
|
|
|
return std::error_code(
|
|
|
|
|
static_cast<int>(e), std::system_category()).message();
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-27 14:40:28 -04:00
|
|
|
|
|
|
|
|
std::vector<std::string> g_errors, g_warnings;
|
|
|
|
|
std::mutex g_log_mutex;
|
|
|
|
|
|
2020-04-27 09:43:05 -04:00
|
|
|
void out(level lv, const std::string& s)
|
|
|
|
|
{
|
|
|
|
|
if (lv == level::debug && !conf::verbose())
|
|
|
|
|
return;
|
|
|
|
|
|
2020-04-27 14:40:28 -04:00
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(g_log_mutex);
|
|
|
|
|
auto c = color_for_level(lv);
|
|
|
|
|
|
|
|
|
|
std::cout << s << "\n";
|
|
|
|
|
|
|
|
|
|
if (lv == level::error || lv == level::bail)
|
|
|
|
|
g_errors.push_back(s);
|
|
|
|
|
else if (lv == level::warning)
|
|
|
|
|
g_warnings.push_back(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lv == level::bail)
|
|
|
|
|
throw bailed(s);
|
2020-04-27 09:43:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void out(level lv, const std::string& s, DWORD e)
|
|
|
|
|
{
|
|
|
|
|
out(lv, s + ", " + error_message(e));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void out(level lv, const std::string& s, const std::error_code& e)
|
|
|
|
|
{
|
|
|
|
|
out(lv, s + ", " + e.message());
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-27 14:40:28 -04:00
|
|
|
void dump_logs()
|
|
|
|
|
{
|
|
|
|
|
if (!g_warnings.empty())
|
|
|
|
|
{
|
|
|
|
|
auto c = color_for_level(level::warning);
|
|
|
|
|
std::cout << "\n\nthere were warnings:\n";
|
|
|
|
|
|
|
|
|
|
for (auto&& s : g_warnings)
|
|
|
|
|
std::cout << " - " << s << "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!g_errors.empty())
|
|
|
|
|
{
|
|
|
|
|
auto c = color_for_level(level::error);
|
|
|
|
|
std::cout << "\n\nthere were errors:\n";
|
|
|
|
|
|
|
|
|
|
for (auto&& s : g_errors)
|
|
|
|
|
std::cout << " - " << s << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string env(const std::string& name)
|
|
|
|
|
{
|
|
|
|
|
const std::size_t buffer_size = GetEnvironmentVariableA(
|
|
|
|
|
name.c_str(), nullptr, 0);
|
|
|
|
|
|
|
|
|
|
if (buffer_size == 0)
|
|
|
|
|
bail_out("environment variable " + name + " doesn't exist");
|
|
|
|
|
|
|
|
|
|
auto buffer = std::make_unique<char[]>(buffer_size + 1);
|
|
|
|
|
std::fill(buffer.get(), buffer.get() + buffer_size + 1, 0);
|
|
|
|
|
|
|
|
|
|
GetEnvironmentVariableA(
|
|
|
|
|
name.c_str(), buffer.get(), static_cast<DWORD>(buffer_size));
|
|
|
|
|
|
|
|
|
|
return buffer.get();
|
2020-04-28 19:29:05 -04:00
|
|
|
}
|
2020-04-27 14:40:28 -04:00
|
|
|
|
2020-04-28 19:29:05 -04:00
|
|
|
void env(const std::string& name, const std::string& value)
|
|
|
|
|
{
|
|
|
|
|
::SetEnvironmentVariableA(name.c_str(), value.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void prepend_to_path(const fs::path& dir)
|
|
|
|
|
{
|
|
|
|
|
if (!fs::exists(dir))
|
|
|
|
|
bail_out("can't add " + dir.string() + " to path, doesn't exist");
|
|
|
|
|
|
|
|
|
|
if (!fs::is_directory(dir))
|
|
|
|
|
bail_out("can't add " + dir.string() + " to path, not a directory");
|
|
|
|
|
|
|
|
|
|
env("PATH", dir.string() + ";" + env("PATH"));
|
2020-04-27 14:40:28 -04:00
|
|
|
}
|
2020-04-27 09:43:05 -04:00
|
|
|
|
|
|
|
|
std::string read_text_file(const fs::path& p)
|
|
|
|
|
{
|
|
|
|
|
debug("reading " + p.string());
|
|
|
|
|
|
|
|
|
|
std::string s;
|
|
|
|
|
|
|
|
|
|
std::ifstream in(p);
|
|
|
|
|
if (!in)
|
|
|
|
|
bail_out("can't read from " + p.string() + "'");
|
|
|
|
|
|
|
|
|
|
in.seekg(0, std::ios::end);
|
|
|
|
|
s.resize(static_cast<std::size_t>(in.tellg()));
|
|
|
|
|
in.seekg(0, std::ios::beg);
|
|
|
|
|
in.read(&s[0], static_cast<std::streamsize>(s.size()));
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string replace_all(
|
|
|
|
|
std::string s, const std::string& from, const std::string& to)
|
|
|
|
|
{
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
const auto pos = s.find(from);
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
s.replace(pos, from.size(), to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 22:14:47 -04:00
|
|
|
std::string join(const std::vector<std::string>& v, const std::string& sep)
|
|
|
|
|
{
|
|
|
|
|
std::string s;
|
|
|
|
|
|
|
|
|
|
for (auto&& e : v)
|
|
|
|
|
{
|
|
|
|
|
if (!s.empty())
|
|
|
|
|
s += sep;
|
|
|
|
|
|
|
|
|
|
s += e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-29 16:42:50 -04:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 19:29:05 -04:00
|
|
|
|
|
|
|
|
file_deleter::file_deleter(fs::path p)
|
|
|
|
|
: p_(std::move(p)), delete_(true)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file_deleter::~file_deleter()
|
|
|
|
|
{
|
|
|
|
|
if (delete_)
|
|
|
|
|
delete_now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void file_deleter::delete_now()
|
|
|
|
|
{
|
|
|
|
|
if (fs::exists(p_))
|
|
|
|
|
op::delete_file(p_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void file_deleter::cancel()
|
|
|
|
|
{
|
|
|
|
|
delete_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
directory_deleter::directory_deleter(fs::path p)
|
|
|
|
|
: p_(std::move(p)), delete_(true)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
directory_deleter::~directory_deleter()
|
|
|
|
|
{
|
|
|
|
|
if (delete_)
|
|
|
|
|
delete_now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void directory_deleter::delete_now()
|
|
|
|
|
{
|
|
|
|
|
if (fs::exists(p_))
|
|
|
|
|
op::delete_directory(p_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void directory_deleter::cancel()
|
|
|
|
|
{
|
|
|
|
|
delete_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-27 09:43:05 -04:00
|
|
|
} // namespace
|