convert sip-module-script.py to acp

dump log lines before continuing even if a process returned 0
This commit is contained in:
isanae
2020-05-14 19:42:17 -04:00
parent 39a22d2650
commit f851f4577b
9 changed files with 204 additions and 35 deletions
+12 -13
View File
@@ -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
View File
@@ -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);
}
+6 -1
View File
@@ -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
View File
@@ -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)
{
+6
View File
@@ -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
View File
@@ -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());
}
+16
View File
@@ -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
View File
@@ -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
View File
@@ -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;