mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
convert sip-module-script.py to acp
dump log lines before continuing even if a process returned 0
This commit is contained in:
+12
-13
@@ -307,22 +307,21 @@ std::string context::make_log_string(reason r, level, std::string_view s) const
|
||||
|
||||
void dump_logs()
|
||||
{
|
||||
if (!g_warnings.empty())
|
||||
if (!g_warnings.empty() || !g_errors.empty())
|
||||
{
|
||||
auto c = level_color(context::level::warning);
|
||||
u8cout << "\n\nthere were warnings:\n";
|
||||
u8cout << "\n\nthere were problems:\n";
|
||||
|
||||
for (auto&& s : g_warnings)
|
||||
u8cout << s << "\n";
|
||||
}
|
||||
{
|
||||
auto c = level_color(context::level::warning);
|
||||
for (auto&& s : g_warnings)
|
||||
u8cout << s << "\n";
|
||||
}
|
||||
|
||||
if (!g_errors.empty())
|
||||
{
|
||||
auto c = level_color(context::level::error);
|
||||
u8cout << "\n\nthere were errors:\n";
|
||||
|
||||
for (auto&& s : g_errors)
|
||||
u8cout << s << "\n";
|
||||
{
|
||||
auto c = level_color(context::level::error);
|
||||
for (auto&& s : g_errors)
|
||||
u8cout << s << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-5
@@ -311,6 +311,14 @@ void copy_glob_to_dir_if_better(
|
||||
const auto file_parent = src_glob.parent_path();
|
||||
const auto wildcard = src_glob.filename().native();
|
||||
|
||||
if (!fs::exists(file_parent))
|
||||
{
|
||||
cx.bail_out(context::fs,
|
||||
"can't copy glob {} to {}, parent directory {} doesn't exist",
|
||||
src_glob, dest_dir, file_parent);
|
||||
}
|
||||
|
||||
|
||||
for (auto&& e : fs::directory_iterator(file_parent))
|
||||
{
|
||||
const auto name = e.path().filename().native();
|
||||
@@ -355,6 +363,43 @@ void copy_glob_to_dir_if_better(
|
||||
}
|
||||
}
|
||||
|
||||
void swap_files(
|
||||
const context& cx, const fs::path& src, const fs::path& dest,
|
||||
const fs::path& backup, flags)
|
||||
{
|
||||
cx.trace(context::fs, "swapping {} and {}", src, dest);
|
||||
|
||||
if (conf::dry())
|
||||
return;
|
||||
|
||||
const wchar_t* backup_p = nullptr;
|
||||
std::wstring backup_s;
|
||||
|
||||
if (!backup.empty())
|
||||
{
|
||||
backup_s = backup.native();
|
||||
backup_p = backup_s.c_str();
|
||||
}
|
||||
|
||||
const auto r = ::ReplaceFileW(
|
||||
src.native().c_str(), dest.native().c_str(), backup_p,
|
||||
REPLACEFILE_IGNORE_MERGE_ERRORS | REPLACEFILE_IGNORE_ACL_ERRORS,
|
||||
nullptr, nullptr);
|
||||
|
||||
if (r)
|
||||
return;
|
||||
|
||||
const auto e = GetLastError();
|
||||
|
||||
cx.warning(
|
||||
context::generic,
|
||||
"failed to atomically rename {} to {}, {}; hoping for the best",
|
||||
src, dest, error_message(e));
|
||||
|
||||
op::rename(cx, src, backup);
|
||||
op::rename(cx, dest, src);
|
||||
}
|
||||
|
||||
std::string read_text_file_impl(const context& cx, const fs::path& p, flags f)
|
||||
{
|
||||
cx.trace(context::fs, "reading {}", p);
|
||||
@@ -398,15 +443,17 @@ std::string read_text_file(
|
||||
}
|
||||
|
||||
void write_text_file(
|
||||
const context& cx, const fs::path& p, std::string_view s, flags f)
|
||||
const context& cx, encodings e, const fs::path& p,
|
||||
std::string_view utf8, flags f)
|
||||
{
|
||||
check(cx, p);
|
||||
|
||||
cx.trace(context::fs, "writing {} bytes to {}", s.size(), p);
|
||||
const std::string bytes = utf8_to_bytes(e, utf8);
|
||||
cx.trace(context::fs, "writing {} bytes to {}", bytes.size(), p);
|
||||
|
||||
{
|
||||
std::ofstream out(p);
|
||||
out << s;
|
||||
std::ofstream out(p, std::ios::binary);
|
||||
out.write(bytes.data(), static_cast<std::streamsize>(bytes.size()));
|
||||
out.close();
|
||||
|
||||
if (out.bad())
|
||||
@@ -423,7 +470,7 @@ void write_text_file(
|
||||
}
|
||||
|
||||
cx.trace(context::fs,
|
||||
"finished writing {} bytes to {}", s.size(), p);
|
||||
"finished writing {} bytes to {}", bytes.size(), p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,10 +51,15 @@ void copy_glob_to_dir_if_better(
|
||||
const context& cx,
|
||||
const fs::path& src_glob, const fs::path& dest_dir, flags f);
|
||||
|
||||
void swap_files(
|
||||
const context& cx, const fs::path& src, const fs::path& dest,
|
||||
const fs::path& backup={}, flags f=noflags);
|
||||
|
||||
std::string read_text_file(
|
||||
const context& cx, encodings e, const fs::path& p, flags f=noflags);
|
||||
|
||||
void write_text_file(
|
||||
const context& cx, const fs::path& p, std::string_view s, flags f=noflags);
|
||||
const context& cx, encodings e, const fs::path& p, std::string_view utf8,
|
||||
flags f=noflags);
|
||||
|
||||
} // namespace
|
||||
|
||||
+28
-4
@@ -231,8 +231,9 @@ process::impl& process::impl::operator=(const impl& i)
|
||||
}
|
||||
|
||||
|
||||
process::process()
|
||||
: cx_(&gcx()), unicode_(false), chcp_(-1), flags_(process::noflags), code_(0)
|
||||
process::process() :
|
||||
cx_(&gcx()), unicode_(false), chcp_(-1), flags_(process::noflags),
|
||||
stdout_(context::level::trace), stderr_(context::level::error), code_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -634,6 +635,7 @@ void process::read_pipe(
|
||||
return;
|
||||
}
|
||||
|
||||
logs_[f.lv].push_back(std::string(f.line));
|
||||
cx_->log(f.r, f.lv, "{}", f.line);
|
||||
});
|
||||
|
||||
@@ -682,7 +684,29 @@ void process::on_completed()
|
||||
// success
|
||||
if (code_ == 0)
|
||||
{
|
||||
cx_->trace(context::cmd, "process exit code is 0");
|
||||
const auto& warnings = logs_[context::level::warning];
|
||||
const auto& errors = logs_[context::level::error];
|
||||
|
||||
if (!warnings.empty() || !errors.empty())
|
||||
{
|
||||
cx_->warning(
|
||||
context::cmd,
|
||||
"process exit code is 0, but stderr had something");
|
||||
|
||||
cx_->warning(context::cmd, "process was: {}", make_cmd());
|
||||
cx_->warning(context::cmd, "stderr:");
|
||||
|
||||
for (auto&& line : warnings)
|
||||
cx_->warning(context::std_err, " {}", line);
|
||||
|
||||
for (auto&& line : errors)
|
||||
cx_->warning(context::std_err, " {}", line);
|
||||
}
|
||||
else
|
||||
{
|
||||
cx_->trace(context::cmd, "process exit code is 0");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -804,7 +828,7 @@ void process::dump_stderr() noexcept
|
||||
if (!s.empty())
|
||||
{
|
||||
cx_->error(context::cmd,
|
||||
"{} failed, content of stderr:", make_name());
|
||||
"{} failed, {}, content of stderr:", make_name(), make_cmd());
|
||||
|
||||
for_each_line(s, [&](auto&& line)
|
||||
{
|
||||
|
||||
@@ -216,6 +216,11 @@ private:
|
||||
filter_fun filter;
|
||||
encodings encoding = encodings::dont_know;
|
||||
encoded_buffer buffer;
|
||||
|
||||
stream(context::level lv)
|
||||
: level(lv)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
const context* cx_;
|
||||
@@ -231,6 +236,7 @@ private:
|
||||
std::string raw_;
|
||||
std::string cmd_;
|
||||
fs::path error_log_file_;
|
||||
std::map<context::level, std::vector<std::string>> logs_;
|
||||
|
||||
impl impl_;
|
||||
DWORD code_;
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ void boost::write_config_jam()
|
||||
});
|
||||
|
||||
|
||||
op::write_text_file(cx(), config_jam_file(), oss.str());
|
||||
op::write_text_file(cx(), encodings::utf8, config_jam_file(), oss.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -150,8 +150,24 @@ void sip::generate()
|
||||
.env(this_env::get()
|
||||
.set("PYTHONUTF8", "1"))));
|
||||
|
||||
|
||||
const std::string filename = "sip-module-script.py";
|
||||
const fs::path src = python::scripts_path() / filename;
|
||||
const fs::path backup = python::scripts_path() / (filename + ".bak");
|
||||
const fs::path dest = python::scripts_path() / (filename + ".acp");
|
||||
|
||||
if (!fs::exists(backup))
|
||||
{
|
||||
const std::string utf8 = op::read_text_file(cx(), encodings::utf8, src);
|
||||
op::write_text_file(cx(), encodings::acp, dest, utf8);
|
||||
op::swap_files(cx(), src, dest, backup);
|
||||
}
|
||||
|
||||
run_tool(process_runner(process()
|
||||
.binary(sip_module_exe())
|
||||
.chcp(850)
|
||||
.stdout_encoding(encodings::acp)
|
||||
.stderr_encoding(encodings::acp)
|
||||
.arg("--sip-h")
|
||||
.arg("PyQt5.zip")
|
||||
.cwd(source_path())));
|
||||
|
||||
+81
-10
@@ -71,6 +71,11 @@ void dump_stacktrace(const wchar_t* what)
|
||||
|
||||
std::wcerr << L"\n";
|
||||
}
|
||||
|
||||
if (IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
else
|
||||
TerminateProcess(GetCurrentProcess(), 0xffff);
|
||||
}
|
||||
|
||||
void terminate_handler() noexcept
|
||||
@@ -525,7 +530,7 @@ console_color::~console_color()
|
||||
}
|
||||
|
||||
|
||||
std::optional<std::wstring> to_utf16(UINT from, std::string_view s)
|
||||
std::optional<std::wstring> to_widechar(UINT from, std::string_view s)
|
||||
{
|
||||
if (s.empty())
|
||||
return std::wstring();
|
||||
@@ -551,13 +556,13 @@ std::optional<std::wstring> to_utf16(UINT from, std::string_view s)
|
||||
return std::wstring(buffer.get(), buffer.get() + written);
|
||||
}
|
||||
|
||||
std::optional<std::string> to_utf8(std::wstring_view ws)
|
||||
std::optional<std::string> to_multibyte(UINT to, std::wstring_view ws)
|
||||
{
|
||||
if (ws.empty())
|
||||
return std::string();
|
||||
|
||||
const int size = WideCharToMultiByte(
|
||||
CP_UTF8, 0, ws.data(), static_cast<int>(ws.size()), nullptr, 0,
|
||||
to, 0, ws.data(), static_cast<int>(ws.size()), nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
|
||||
if (size == 0)
|
||||
@@ -567,7 +572,7 @@ std::optional<std::string> to_utf8(std::wstring_view ws)
|
||||
static_cast<std::size_t>(size + 1));
|
||||
|
||||
const int written = WideCharToMultiByte(
|
||||
CP_UTF8, 0, ws.data(), static_cast<int>(ws.size()),
|
||||
to, 0, ws.data(), static_cast<int>(ws.size()),
|
||||
buffer.get(), size, nullptr, nullptr);
|
||||
|
||||
if (written == 0)
|
||||
@@ -581,10 +586,10 @@ std::optional<std::string> to_utf8(std::wstring_view ws)
|
||||
|
||||
std::wstring utf8_to_utf16(std::string_view s)
|
||||
{
|
||||
auto ws = to_utf16(CP_UTF8, s);
|
||||
auto ws = to_widechar(CP_UTF8, s);
|
||||
if (!ws)
|
||||
{
|
||||
std::cerr << "can't convert from utf8 to utf16\n";
|
||||
std::wcerr << L"can't convert from utf8 to utf16\n";
|
||||
return L"???";
|
||||
}
|
||||
|
||||
@@ -593,10 +598,10 @@ std::wstring utf8_to_utf16(std::string_view s)
|
||||
|
||||
std::string utf16_to_utf8(std::wstring_view ws)
|
||||
{
|
||||
auto s = to_utf8(ws);
|
||||
auto s = to_multibyte(CP_UTF8, ws);
|
||||
if (!s)
|
||||
{
|
||||
std::cerr << "can't convert from utf16 to utf8\n";
|
||||
std::wcerr << L"can't convert from utf16 to utf8\n";
|
||||
return "???";
|
||||
}
|
||||
|
||||
@@ -605,16 +610,30 @@ std::string utf16_to_utf8(std::wstring_view ws)
|
||||
|
||||
std::wstring cp_to_utf16(UINT from, std::string_view s)
|
||||
{
|
||||
auto ws = to_utf16(from, s);
|
||||
auto ws = to_widechar(from, s);
|
||||
if (!ws)
|
||||
{
|
||||
std::cerr << "can't convert from acp to utf16\n";
|
||||
std::wcerr << L"can't convert from cp " << from << L" to utf16\n";
|
||||
return L"???";
|
||||
}
|
||||
|
||||
return *ws;
|
||||
}
|
||||
|
||||
std::string utf16_to_cp(UINT to, std::wstring_view ws)
|
||||
{
|
||||
auto s = to_multibyte(to, ws);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
std::wcerr << L"can't convert from cp " << to << L" to utf16\n";
|
||||
return "???";
|
||||
}
|
||||
|
||||
return *s;
|
||||
}
|
||||
|
||||
|
||||
std::string bytes_to_utf8(encodings e, std::string_view s)
|
||||
{
|
||||
switch (e)
|
||||
@@ -647,6 +666,58 @@ std::string bytes_to_utf8(encodings e, std::string_view s)
|
||||
}
|
||||
}
|
||||
|
||||
std::string utf16_to_bytes(encodings e, std::wstring_view ws)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case encodings::utf16:
|
||||
{
|
||||
return std::string(
|
||||
reinterpret_cast<const char*>(ws.data()),
|
||||
ws.size() * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
case encodings::acp:
|
||||
{
|
||||
return utf16_to_cp(CP_ACP, ws);
|
||||
}
|
||||
|
||||
case encodings::oem:
|
||||
{
|
||||
return utf16_to_cp(CP_OEMCP, ws);
|
||||
}
|
||||
|
||||
case encodings::utf8:
|
||||
case encodings::dont_know:
|
||||
default:
|
||||
{
|
||||
return utf16_to_utf8(ws);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string utf8_to_bytes(encodings e, std::string_view utf8)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case encodings::utf16:
|
||||
case encodings::acp:
|
||||
case encodings::oem:
|
||||
{
|
||||
const std::wstring ws = utf8_to_utf16(utf8);
|
||||
return utf16_to_bytes(e, ws);
|
||||
}
|
||||
|
||||
case encodings::utf8:
|
||||
case encodings::dont_know:
|
||||
default:
|
||||
{
|
||||
return std::string(utf8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string path_to_utf8(fs::path p)
|
||||
{
|
||||
|
||||
+2
-1
@@ -240,7 +240,8 @@ std::string trim_copy(const std::string& s, const std::string& what=" \t\r\n");
|
||||
|
||||
std::wstring utf8_to_utf16(std::string_view s);
|
||||
std::string utf16_to_utf8(std::wstring_view ws);
|
||||
std::string bytes_to_utf8(encodings e, std::string_view s);
|
||||
std::string bytes_to_utf8(encodings e, std::string_view bytes);
|
||||
std::string utf8_to_bytes(encodings e, std::string_view utf8);
|
||||
|
||||
template <class T>
|
||||
std::string path_to_utf8(T&&) = delete;
|
||||
|
||||
Reference in New Issue
Block a user