rework of conf, ini, vswhere

things are broken
This commit is contained in:
isanae
2020-05-05 07:41:09 -04:00
parent 07da68acee
commit facf4c32f3
18 changed files with 8057 additions and 442 deletions
+673 -298
View File
File diff suppressed because it is too large Load Diff
+86 -58
View File
@@ -3,10 +3,24 @@
namespace mob
{
class bad_command_line {};
class bad_conf {};
#define VALUE(NAME) \
static decltype(auto) NAME() { return by_name(#NAME); }
struct tool_paths
{
static fs::path perl();
static fs::path msbuild();
static fs::path devenv();
static fs::path cmake();
static fs::path git();
};
struct conf
{
static void set(int argc, char** argv);
static bool log_dump();
static bool log_trace();
static bool log_debug();
@@ -19,83 +33,97 @@ struct conf
static bool reextract();
static bool rebuild();
static std::string mo_org();
static std::string mo_branch();
static const std::string& by_name(const std::string& s);
VALUE(mo_org);
VALUE(mo_branch);
};
struct third_party
{
static fs::path sevenz();
static fs::path jom();
static fs::path patch();
static fs::path git();
static fs::path cmake();
static fs::path perl();
static fs::path devenv();
static fs::path msbuild();
static fs::path nuget();
static const fs::path& by_name(const std::string& s);
VALUE(sevenz);
VALUE(jom);
VALUE(patch);
VALUE(nuget);
VALUE(vswhere);
};
struct prebuilt
{
static bool boost();
static bool by_name(const std::string& s);
VALUE(boost);
};
struct versions
{
static const std::string& vs();
static const std::string& vs_year();
static const std::string& vs_toolset();
static const std::string& sdk();
static const std::string& sevenzip();
static const std::string& zlib();
static const std::string& boost();
static const std::string& boost_vs();
static const std::string& python();
static const std::string& fmt();
static const std::string& gtest();
static const std::string& libbsarch();
static const std::string& libloot();
static const std::string& libloot_hash();
static const std::string& openssl();
static const std::string& bzip2();
static const std::string& lz4();
static const std::string& nmm();
static const std::string& spdlog();
static const std::string& usvfs();
static const std::string& qt();
static const std::string& qt_vs();
static const std::string& pyqt();
static const std::string& pyqt_builder();
static const std::string& sip();
static const std::string& pyqt_sip();
static const std::string& by_name(const std::string& s);
VALUE(vs);
VALUE(vs_year);
VALUE(vs_toolset);
VALUE(sdk);
VALUE(sevenzip);
VALUE(zlib);
VALUE(boost);
VALUE(boost_vs);
VALUE(python);
VALUE(fmt);
VALUE(gtest);
VALUE(libbsarch);
VALUE(libloot);
VALUE(libloot_hash);
VALUE(openssl);
VALUE(bzip2);
VALUE(lz4);
VALUE(nmm);
VALUE(spdlog);
VALUE(usvfs);
VALUE(qt);
VALUE(qt_vs);
VALUE(pyqt);
VALUE(pyqt_builder);
VALUE(sip);
VALUE(pyqt_sip);
};
struct paths
{
static fs::path prefix();
static fs::path cache();
static fs::path patches();
static fs::path build();
static const fs::path& by_name(const std::string& s);
static fs::path install();
static fs::path install_bin();
static fs::path install_libs();
static fs::path install_pdbs();
VALUE(third_party);
VALUE(prefix);
VALUE(cache);
VALUE(patches);
VALUE(build);
static fs::path install_dlls();
static fs::path install_loot();
static fs::path install_plugins();
VALUE(install);
VALUE(install_bin);
VALUE(install_libs);
VALUE(install_pdbs);
static fs::path qt();
static fs::path qt_bin();
static fs::path program_files_x86();
static fs::path program_files_x64();
VALUE(install_dlls);
VALUE(install_loot);
VALUE(install_plugins);
static fs::path temp_dir();
static fs::path temp_file();
VALUE(vs);
VALUE(vcvars);
VALUE(qt_install);
VALUE(qt_bin);
VALUE(pf_x86);
VALUE(pf_x64);
VALUE(temp_dir);
};
fs::path find_third_party_directory();
#undef VALUE
void init_options();
void dump_options();
void conf_command_line_options(clipp::group& g);
fs::path make_temp_file();
} // namespace
+2
View File
@@ -50,6 +50,7 @@ std::string reason_string(context::reason r)
case context::fs: return "fs";
case context::net: return "net";
case context::generic: return "";
case context::conf: return "conf";
default: return "?";
}
}
@@ -252,6 +253,7 @@ std::string context::make_log_string(reason r, level, std::string_view s) const
case context::fs:
case context::net:
case context::generic:
case context::conf:
default:
oss << s;
break;
+8 -5
View File
@@ -14,19 +14,22 @@ public:
// generic
generic,
// an action was bypassed because it was already done
// a configuration action
conf,
// something was bypassed because it was already done
bypass,
// an action was done because the --redownload option was set
// something was done because the --redownload option was set
redownload,
// an action was done because the --rebuild option was set
// something was done because the --rebuild option was set
rebuild,
// an action was done because the --reextract option was set
// something was done because the --reextract option was set
reextract,
// an action was done in case of interruption or because something
// something was done in case of interruption or because something
// was interrupted
interruption,
+2 -37
View File
@@ -8,41 +8,6 @@
namespace mob
{
fs::path find_vcvars()
{
const std::vector<std::string> editions =
{
"Community", "Preview", "Enterprise", "Professional"
};
const fs::path bat = "vcvarsall.bat";
gcx().trace(context::generic, "looking for " + bat.string());
for (auto&& edition : editions)
{
const auto dir =
paths::program_files_x86() /
"Microsoft Visual Studio" /
versions::vs_year() /
edition / "VC" / "Auxiliary" / "Build";
const auto f = dir / bat;
if (fs::exists(f))
{
gcx().trace(context::generic, "found " + f.string());
return f;
}
else
{
gcx().trace(context::generic, "not found in " + dir.string());
}
}
gcx().bail_out(context::generic, "couldn't find visual studio");
}
env get_vcvars_env(arch a)
{
std::string arch_s;
@@ -64,11 +29,11 @@ env get_vcvars_env(arch a)
gcx().trace(context::generic, "looking for vcvars for " + arch_s);
const fs::path tmp = paths::temp_file();
const fs::path tmp = make_temp_file();
// "vcvarsall.bat" amd64 && set > temp_file
std::string cmd =
"\"" + find_vcvars().string() + "\" " + arch_s +
"\"" + paths::vcvars().string() + "\" " + arch_s +
" && set > \"" + tmp.string() + "\"";
process::raw(gcx(), cmd)
+73 -7
View File
@@ -9,6 +9,7 @@
namespace mob
{
BOOL WINAPI signal_handler(DWORD) noexcept
{
gcx().debug(context::generic, "caught sigint");
@@ -31,18 +32,74 @@ struct curl_init
};
std::string version()
{
return "mob 1.0";
}
void show_help(const clipp::group& g)
{
std::cout
<< clipp::make_man_page(
g, "mob", clipp::doc_formatting()
.first_column(4)
.doc_column(30));
}
int run(int argc, char** argv)
{
struct
{
bool version = false;
bool help = false;
} cmd;
clipp::group g;
g.push_back(
(clipp::option("--version")
>> [&]{ cmd.version = true; })
% "shows the version",
(clipp::option("-h", "--help")
>> [&]{ cmd.help = true; })
% "shows this message"
);
conf_command_line_options(g);
try
{
const auto pr = clipp::parse(argc, argv, g);
if (!pr)
throw bad_command_line();
if (cmd.version)
{
std::cout << version() << "\n";
return 0;
}
if (cmd.help)
{
show_help(g);
return 0;
}
init_options();
dump_options();
return 0;
::SetConsoleCtrlHandler(signal_handler, TRUE);
curl_init curl;
this_env::set(
"PATH",
(find_third_party_directory() / "bin").string() + ";",
env::prepend);
//this_env::set("PATH", paths::third_party().string() + ";", env::prepend);
add_task<sevenz>();
add_task<zlib>();
@@ -63,7 +120,7 @@ int run(int argc, char** argv)
add_task<sip>();
add_task<pyqt>();
if (argc > 1)
/*if (argc > 1)
{
std::vector<std::string> tasks;
@@ -84,13 +141,22 @@ int run(int argc, char** argv)
}
return 0;
}
}*/
run_all_tasks();
return 0;
}
catch(bailed)
catch(bad_command_line&)
{
show_help(g);
return 1;
}
catch(bad_conf&)
{
return 1;
}
catch(bailed&)
{
error("bailing out");
return 1;
+2
View File
@@ -64,7 +64,9 @@
#include <Shlobj.h>
#include <shlwapi.h>
#include <curl/curl.h>
#include <clipp.h>
#pragma warning(pop)
+139 -30
View File
@@ -8,7 +8,7 @@
namespace mob
{
HANDLE bit_bucket()
HANDLE get_bit_bucket()
{
SECURITY_ATTRIBUTES sa { .nLength = sizeof(sa), .bInheritHandle = TRUE };
return ::CreateFileA("NUL", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
@@ -212,7 +212,9 @@ process::impl& process::impl::operator=(const impl& i)
process::process() :
cx_(&gcx()), flags_(process::noflags),
stdout_flags_(process::forward_to_log),
stdout_level_(context::level::trace),
stderr_flags_(process::forward_to_log),
stderr_level_(context::level::error),
code_(0)
{
@@ -279,6 +281,12 @@ const fs::path& process::cwd() const
return cwd_;
}
process& process::stdout_flags(stream_flags s)
{
stdout_flags_ = s;
return *this;
}
process& process::stdout_level(context::level lv)
{
stdout_level_ = lv;
@@ -291,6 +299,12 @@ process& process::stdout_filter(filter_fun f)
return *this;
}
process& process::stderr_flags(stream_flags s)
{
stderr_flags_ = s;
return *this;
}
process& process::stderr_level(context::level lv)
{
stderr_level_ = lv;
@@ -363,6 +377,9 @@ void process::run()
void process::do_run(const std::string& what)
{
if (raw_.empty() && bin_.empty())
cx_->bail_out(context::cmd, "process: nothing to run");
if (fs::exists(error_log_file_))
{
cx_->trace(context::cmd,
@@ -375,12 +392,55 @@ void process::do_run(const std::string& what)
STARTUPINFOA si = { .cb=sizeof(si) };
PROCESS_INFORMATION pi = {};
auto process_stderr = impl_.stderr_pipe.create();
auto process_stdout = impl_.stdout_pipe.create();
handle_ptr stdout_pipe, stderr_pipe;
si.hStdOutput = process_stdout.get();
si.hStdError = process_stderr.get();
si.hStdInput = bit_bucket();
switch (stdout_flags_)
{
case forward_to_log:
case keep_in_string:
{
stdout_pipe = impl_.stdout_pipe.create();
si.hStdOutput = stdout_pipe.get();
break;
}
case bit_bucket:
{
si.hStdOutput = get_bit_bucket();
break;
}
case inherit:
{
si.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
break;
}
}
switch (stderr_flags_)
{
case forward_to_log:
case keep_in_string:
{
stderr_pipe = impl_.stderr_pipe.create();
si.hStdError = stderr_pipe.get();
break;
}
case bit_bucket:
{
si.hStdError = get_bit_bucket();
break;
}
case inherit:
{
si.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
break;
}
}
si.hStdInput = get_bit_bucket();
si.dwFlags = STARTF_USESTDHANDLES;
const std::string cmd = this_env::get("COMSPEC");
@@ -458,37 +518,76 @@ void process::join()
void process::read_pipes()
{
// stdout
std::string_view s = impl_.stdout_pipe.read();
for_each_line(s, [&](auto&& line)
switch (stdout_flags_)
{
filter f = {line, context::std_out, stdout_level_, false};
if (stdout_filter_)
case forward_to_log:
{
stdout_filter_(f);
if (f.ignore)
return;
std::string_view s = impl_.stdout_pipe.read();
for_each_line(s, [&](auto&& line)
{
filter f = {line, context::std_out, stdout_level_, false};
if (stdout_filter_)
{
stdout_filter_(f);
if (f.ignore)
return;
}
cx_->log(f.r, f.lv, f.line);
});
break;
}
cx_->log(f.r, f.lv, f.line);
});
// stderr
s = impl_.stderr_pipe.read();
for_each_line(s, [&](auto&& line)
{
filter f = {line, context::std_err, stderr_level_, false};
if (stderr_filter_)
case keep_in_string:
{
stderr_filter_(f);
if (f.ignore)
return;
std::string_view s = impl_.stdout_pipe.read();
stdout_string_ += s;
break;
}
cx_->log(f.r, f.lv, f.line);
});
case bit_bucket:
case inherit:
break;
}
switch (stderr_flags_)
{
case forward_to_log:
{
std::string_view s = impl_.stderr_pipe.read();
for_each_line(s, [&](auto&& line)
{
filter f = {line, context::std_err, stderr_level_, false};
if (stderr_filter_)
{
stderr_filter_(f);
if (f.ignore)
return;
}
cx_->log(f.r, f.lv, f.line);
});
break;
}
case keep_in_string:
{
std::string_view s = impl_.stderr_pipe.read();
stderr_string_ += s;
break;
}
case bit_bucket:
case inherit:
break;
}
}
void process::on_completed()
@@ -603,6 +702,16 @@ int process::exit_code() const
return static_cast<int>(code_);
}
std::string process::steal_stdout()
{
return std::move(stdout_string_);
}
std::string process::steal_stderr()
{
return std::move(stderr_string_);
}
void process::add_arg(const std::string& k, const std::string& v, arg_flags f)
{
if ((f & log_debug) && !conf::log_debug())
+19
View File
@@ -55,6 +55,14 @@ public:
quote = 0x20
};
enum stream_flags
{
forward_to_log = 1,
bit_bucket,
keep_in_string,
inherit
};
struct filter
{
const std::string_view line;
@@ -96,9 +104,11 @@ public:
process& cwd(const fs::path& p);
const fs::path& cwd() const;
process& stdout_flags(stream_flags s);
process& stdout_level(context::level lv);
process& stdout_filter(filter_fun f);
process& stderr_flags(stream_flags s);
process& stderr_level(context::level lv);
process& stderr_filter(filter_fun f);
@@ -146,6 +156,8 @@ public:
void join();
int exit_code() const;
std::string steal_stdout();
std::string steal_stderr();
private:
struct impl
@@ -164,10 +176,17 @@ private:
fs::path bin_;
fs::path cwd_;
flags_t flags_;
stream_flags stdout_flags_;
context::level stdout_level_;
filter_fun stdout_filter_;
std::string stdout_string_;
stream_flags stderr_flags_;
context::level stderr_level_;
filter_fun stderr_filter_;
std::string stderr_string_;
mob::env env_;
std::string raw_;
std::string cmd_;
+1 -1
View File
@@ -51,7 +51,7 @@ void openssl::do_build_and_install()
void openssl::configure()
{
run_tool(process_runner(process()
.binary(third_party::perl())
.binary(tool_paths::perl())
.arg("Configure")
.arg("--openssldir=", build_path())
.arg("--prefix=", build_path())
+1 -1
View File
@@ -8,7 +8,7 @@ cmake::cmake()
: basic_process_runner("cmake"), gen_(jom), arch_(arch::def)
{
process_
.binary(third_party::cmake());
.binary(tool_paths::cmake());
}
cmake& cmake::generator(generators g)
+2 -2
View File
@@ -56,7 +56,7 @@ void git_clone::do_run()
void git_clone::clone()
{
process_ = process()
.binary(third_party::git())
.binary(tool_paths::git())
.stderr_level(context::level::trace)
.arg("clone")
.arg("--recurse-submodules")
@@ -73,7 +73,7 @@ void git_clone::clone()
void git_clone::pull()
{
process_ = process()
.binary(third_party::git())
.binary(tool_paths::git())
.stderr_level(context::level::trace)
.arg("pull")
.arg("--recurse-submodules")
+1 -1
View File
@@ -9,7 +9,7 @@ msbuild::msbuild()
: basic_process_runner("msbuild"), config_("Release"), arch_(arch::def)
{
process_
.binary(third_party::msbuild());
.binary(tool_paths::msbuild());
}
msbuild& msbuild::solution(const fs::path& sln)
+1 -1
View File
@@ -64,7 +64,7 @@ devenv_upgrade::devenv_upgrade(fs::path sln)
: basic_process_runner("upgrade project"), sln_(std::move(sln))
{
process_
.binary(third_party::devenv())
.binary(tool_paths::devenv())
.env(env::vs(arch::x64));
}
+20
View File
@@ -39,6 +39,26 @@ std::string join(const std::vector<std::string>& v, const std::string& sep)
return s;
}
void trim(std::string& s, const std::string& what)
{
while (!s.empty())
{
if (what.find(s[0]) != std::string::npos)
s.erase(0, 1);
else if (what.find(s[s.size() - 1]) != std::string::npos)
s.erase(s.size() - 1, 1);
else
break;
}
}
std::string trim_copy(const std::string& s, const std::string& what)
{
std::string c = s;
trim(c, what);
return c;
}
std::string pad_right(std::string s, std::size_t n, char c)
{
if (s.size() < n)
+3 -1
View File
@@ -166,10 +166,12 @@ std::string replace_all(
std::string s, const std::string& from, const std::string& to);
std::string join(const std::vector<std::string>& v, const std::string& sep);
std::string pad_right(std::string s, std::size_t n, char c=' ');
std::string pad_left(std::string s, std::size_t n, char c=' ');
void trim(std::string& s, const std::string& what=" \t\r\n");
std::string trim_copy(const std::string& s, const std::string& what=" \t\r\n");
template <class F>
void for_each_line(std::string_view s, F&& f)
BIN
View File
Binary file not shown.
+7024
View File
File diff suppressed because it is too large Load Diff